画像の拡大縮小を javascript の touch イベントでやってみる

公開日: : android, javascript

画像の拡大・縮小 タッチイベント

画像の幅と高さを取得

まずは、neko.jpg という画像を用意して、幅と高さを取得します。

<!DOCTYPE html>
<html>
<head lang="ja">
<meta charset="UTF-8">
<title>画像の幅と高さを取得</title>

<script>
function BodyOnLoad() {
	var w = document.getElementById('test').width;
	var h = document.getElementById('test').height;
}
</script>
</head>
<body onLoad="BodyOnLoad()">
<img id="test" src="neko.jpg" />
</body>
</html>

タッチイベントの種類

スマホでピンチイン・アウトを行うのに、タッチ関連のイベントを見てみます。

タッチイベント

  • touchstart → タッチを開始すると実行される
  • touchmove → タッチしたまま平行移動すると実行される
  • touchend → タッチ終了すると実行される

ジェスチャーイベント

  • gesturestart → 指が2本以上触れると実行される
  • gesturechange → 2本指以上触れた状態で移動した時実行される
  • gestureend → 指を離して1本以下になると実行される

ジェスチャーイベントは、iPhoneやiPadなどのiOS端末には搭載されているが、Android端末やWindows Phoneには実装されていない。

らしいので、2本指かどうかはタッチイベントでやってみようと思います。

タッチイベントの書き方

タッチイベントは、何本の指でタッチされたか分かる length プロパティがあるので、指が複数かどうかを切り分けられます。

touchstart

el = window;
el.addEventListener('touchstart',function(e){
	if(e.touches.length > 1){
		window.alert('2本指でタッチした');
	}
	else{
		window.alert('1本指でタッチした');
	}		
},false);

touchmove

el = window;
el.addEventListener('touchmove',function(e){
	if(e.touches.length > 1){
		window.alert('2本指で動かした');
	}
	else{
		window.alert('1本指で動かした');
	}
},false);

touchend

el.addEventListener('touchend',function(e){
	window.alert('タッチが終了した');
},false);

touchcancel

タッチ操作を中断させる処理が発生すると実行される(画面の自動回転など)

el.addEventListener('touchcancel',function(e){
	window.alert('タッチが中断した');
},false);

touchcancel イベントが発行された場合、touchend イベントは発行されないらしく、タッチ操作の終了は、両方で監視する必要があるらしいです。

画像の拡大縮小(ピンチイン・アウト)

touches には、pageX と pageY プロパティーに座標が入っています。

タッチイベントで発生するオブジェクト

  • touches → スクリーン上のタッチの情報
  • targetTouches → 同じノード内でタッチが開始された指の情報
  • changedTouches → イベントの発生元となった指の情報

タッチイベントで発生するオブジェクトのプロパティー

  • clientX・clientY → HTMLの要素に対する指の座標
  • screenX・screenY → 画面の表示領域に対する指の座標
  • pageX・pageY → ページ全体に対する指の座標
  • target → イベントの発生元要素
  • identifier → タッチ要素のID

拡大・縮小は、ratioという変数を用意して、ムーブイベント内で、単純に拡大の場合は1.1倍、縮小の場合は0.9倍としていこうと思います。

(変数を用意しないで、直接幅高さにかけていくと、小数点以下の計算で画像の比率が大幅に変わってしまうっぽいので。)

function BodyOnLoad() {
    var ratio=1;
    var w = document.getElementById('test').width;
    var h = document.getElementById('test').height;

	var touchstart_bar = 0;
	var touchmove_bar = 0;
	el = window;
	//タッチの場合
	el.addEventListener('touchstart',function(e){
	    touchstart_bar = 0;
	    touchmove_bar = 0;
	    if(e.touches.length > 1){
	        //絶対値を取得
	        w_abs_start = Math.abs(e.touches[1].pageX - e.touches[0].pageX);
	        h_abs_start = Math.abs(e.touches[1].pageY - e.touches[0].pageY);
	        //はじめに2本指タッチした時の面積
	        touchstart_bar = w_abs_start*h_abs_start;
	    }
	},false);
	 
	//ムーブの場合
	el.addEventListener('touchmove', function(e) {
	    if(e.touches.length > 1){
	        //絶対値を取得
	        w_abs_move = Math.abs(e.touches[1].pageX - e.touches[0].pageX);
	        h_abs_move = Math.abs(e.touches[1].pageY - e.touches[0].pageY);
	        //ムーブした時の面積
	        touchmove_bar = w_abs_move*h_abs_move;
	        //はじめに2タッチ面積からムーブした時の面積を引く
	        area_bar = touchstart_bar-touchmove_bar;
	        if(area_bar<0){//拡大する
	            ratio *= 1.1;
	        }
	        else if(area_bar>0){//縮小する
	            ratio *= 0.9;
	        }
	        document.getElementById('test').width = w*ratio;
	        document.getElementById('test').height = h*ratio;
	    }
	         
	});
}

※ デモはパソコンでは動作しません。
DEMO を見る
拡大・縮小の切り分けは、まずタッチした時の2本の指の面積を(touchstart_bar 変数に)とっておいて、ムーブした時の2本の指の面積と比べて大きくなったら拡大、小さくなっていたら縮小でやってみました。

画像の拡大・縮小・移動

画像を1本指でタッチした時は移動も追加してみました。全文は以下です。

<!DOCTYPE html>
<html>
<head lang="ja">
<meta charset="UTF-8">
<title>スマホのタッチイベントで画像の拡大・縮小・移動</title>

<script>
function BodyOnLoad() {

	var ratio=1;
	var w = document.getElementById('test').width;
	var h = document.getElementById('test').height;
	document.getElementById('test').style.position = 'fixed';
	document.getElementById('test').style.left = '10px';
	document.getElementById('test').style.top = '10px';

	var touchstart_bar = 0;
	var touchmove_bar = 0;
	var touchstart_flg = false;
	el = window;
	
	//タッチの場合
	el.addEventListener('touchstart',function(e){
	    touchstart_bar = 0;
	    touchmove_bar = 0;
		//2本指だったらAndroidではgesturestartは使えない
		if(e.touches.length > 1){
			//絶対値を取得
			w_abs_start = Math.abs(e.touches[1].pageX - e.touches[0].pageX);
			h_abs_start = Math.abs(e.touches[1].pageY - e.touches[0].pageY);
			//はじめに2本指タッチした時の面積
			touchstart_bar = w_abs_start*h_abs_start;
		}
	},false);
	
	//画像を一本指でタッチした場合だけ画像を動かす
	document.getElementById('test').addEventListener('touchstart',function(e){
		if(e.touches.length == 1)touchstart_flg = true;
	},false);

	//ムーブの場合
	el.addEventListener('touchmove', function(e) {
		//2本指だったらAndroidではgesturestartは使えない
		if(e.touches.length > 1){
			//絶対値を取得
			w_abs_move = Math.abs(e.touches[1].pageX - e.touches[0].pageX);
			h_abs_move = Math.abs(e.touches[1].pageY - e.touches[0].pageY);
			//ムーブした時の面積
			touchmove_bar = w_abs_move*h_abs_move;
			//はじめに2タッチ面積からムーブした時の面積を引く
			area_bar = touchstart_bar-touchmove_bar;
			if(area_bar<0){//拡大する
				ratio *= 1.1;
			}
			else if(area_bar>0){//縮小する
				//if(ratio>0.1)ratio *= 0.9;
				ratio *= 0.9;
			}
			document.getElementById('test').width = w*ratio;
			document.getElementById('test').height = h*ratio;
		}
		else if(touchstart_flg){
			var move_x = e.touches[0].pageX-(w*ratio)/2;
			var move_y = e.touches[0].pageY-(h*ratio)/2;
			document.getElementById('test').style.position = 'fixed';
			document.getElementById('test').style.left = String(move_x)+'px';
			document.getElementById('test').style.top = String(move_y)+'px';
		}
	});
	
	//タッチの終了
	el.addEventListener('touchend',function(e){
		touchstart_flg = false;
	},false);
	//タッチの中断
	el.addEventListener('touchcancel',function(e){
		touchstart_flg = false;
	},false);
}
</script>
</head>
<body onLoad="BodyOnLoad()">
<img id="test" src="neko.jpg" />
</body>
</html>

※ デモはパソコンでは動作しません。
DEMO を見る
1本指の場合はページ全体でタッチを監視せず、画像上を指で触れた場合だけフラグ(touchstart_flg)をオンでやってみました。

関連記事

画像加工 cropbox.js

写真をアップロードして切り抜きが出来るcropboxにタッチイベントを付けてみる

Git Hub の cropbox 写真をアップロードしてカット出来るjQueryのプラグイン c

記事を読む

Wordpress VR Test

WordPress で VR させて、360°のパノラマ画像を表示する

WordPress.com内ショートコードで VR させる WordPress.com内で、VR(

記事を読む

Javascript 写真ギャラリー サムネイルスライド横 レスポンシブ対応

Javascript 写真ギャラリー サムネイルスライド横 レスポンシブ対応

Javascript でマウスドラッグのテストをしていきます。 分かりやすいように、ボールを投げる

記事を読む

JavaScript タイピングゲーム スマホ用

Javascript タイピング ゲーム スマホ用 をつくる

JavaScript スマホ用 切り替え 前回の記事のゲームですが、スマホだとサイズが合わなくてや

記事を読む

JavaScript 規制標識 タイピングゲーム(自分用・激ムズ)

HTML5 audio タグ を使って音声を出す

HTML5からaudioタグを使えば、Flashなどのプラグインを使わなくてもブラウザ上で音声を再生

記事を読む

Three.jsで360°パノラマ画像を VR させる

Three.jsで360°パノラマ画像を VR させる

Three.jsで360°パノラマ画像を VR させる VRを作るのに前回のプラグイン「WP-VR

記事を読む

android javascript

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Wordpress 自作フォーム 2(注意点とエラー:This is somewhat embarrassing, isn’t it? など)
WordPress 自作フォーム その2(注意点とエラー:This is somewhat embarrassing, isn’t it? など)

前回(WordPress 自作フォーム 1)のつづきです。 今回は細

Wordpress 自作フォーム
WordPress 自作フォーム その1(サンプルと設置)

Wordpress でプラグインを使わずにフォームをやってみます。

Javascript 写真ギャラリー サムネイルスライド横 レスポンシブ対応
Javascript 写真ギャラリー サムネイルスライド横 レスポンシブ対応

Javascript でマウスドラッグのテストをしていきます。 分か

Three.jsで360°パノラマ画像を VR させる
Three.jsで360°パノラマ画像を VR させる

Three.jsで360°パノラマ画像を VR させる VRを作るの

Wordpress VR Test
WordPress で VR させて、360°のパノラマ画像を表示する

WordPress.com内ショートコードで VR させる Word

→もっと見る

にほんブログ村 IT技術ブログへ にほんブログ村 IT技術ブログ PHPへ にほんブログ村 IT技術ブログ WordPressへ
にほんブログ村 FC2 Blog Ranking
PAGE TOP ↑