画像の拡大縮小を 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)をオンでやってみました。

関連記事

Strict モード JavaScript

Javascript Strictモード “use strict”;

Strict モード(厳格モード) Strict モードとは、ECMAScript5(2009年1

記事を読む

WordPress エラー:Failed to load plugin: table from url https://cdn.tinymce.com/4/plugins/table/plugin.min.js

WordPress エラー:Failed to load plugin: table from url https://cdn.tinymce.com/4/plugins/table/plugin.min.js

WordPress エラーの状態 WordPress 管理画面のテキスト入力欄で(ビジュアルタブの

記事を読む

Wordpress VR Test

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

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

記事を読む

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

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

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

記事を読む

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

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

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

記事を読む

Javascript let const アロー関数 クラス

Javascript ES5,6 の新機能(letとconst,アロー関数,クラスなど)

ESとはECMASCriptの略で、ECMA という国際的な標準化機関が定めた JavaScript

記事を読む

canvas タグでお絵描き(レスポンシブ)

canvas タグでお絵描き(レスポンシブ)

簡単なメモ張みたいなものが欲しいので作ってみました。 canvas のレスポンシブが少しひっかかっ

記事を読む

javascriptで複数同じ名前のformの値を取得する

javascriptで複数同じ名前のformの値を取得するとエラー Cannot read property ‘value’ of undefined

Javascript で value の値を取得する このようなHTMLフォームがあった場合、

記事を読む

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 エラー:Failed to load plugin: table from url https://cdn.tinymce.com/4/plugins/table/plugin.min.js
WordPress エラー:Failed to load plugin: table from url https://cdn.tinymce.com/4/plugins/table/plugin.min.js

WordPress エラーの状態 WordPress 管理画面のテキ

wordpress タイトルの変更
WordPress タイトルの変更

テンプレートタグ the_title(); get_the_title

All-in-One WP Migration で サーバ移動
「All-in-One WP Migration」プラグインで 簡単に WordPress のサーバー移行する手順メモ

1.移行元サイトでのデータエクスポート 「All-in-One WP

DNSサーバーとは
ドメインとは?DNSサーバーとは?

ドメインとは? ドメインとは? ドメインとは、インターネット上のネ

javascriptで複数同じ名前のformの値を取得する
javascriptで複数同じ名前のformの値を取得するとエラー Cannot read property ‘value’ of undefined

Javascript で value の値を取得する このようなHT

→もっと見る

    • 202403
      Mon Tue Wed Thu Fri Sat Sun
      123
      45678910
      11121314151617
      18192021222324
      25262728293031
    にほんブログ村 IT技術ブログへ にほんブログ村 IT技術ブログ PHPへ にほんブログ村 IT技術ブログ WordPressへ
    にほんブログ村 FC2 Blog Ranking
    PAGE TOP ↑