画像の拡大縮小を 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)をオンでやってみました。
関連記事
-
-
Javascript ES5,6 の新機能(letとconst,アロー関数,クラスなど)
ESとはECMASCriptの略で、ECMA という国際的な標準化機関が定めた JavaScript
-
-
canvas タグでお絵描き(レスポンシブ)
簡単なメモ張みたいなものが欲しいので作ってみました。 canvas のレスポンシブが少しひっかかっ
-
-
WordPress エラー:Failed to load plugin: table from url https://cdn.tinymce.com/4/plugins/table/plugin.min.js
WordPress エラーの状態 WordPress 管理画面のテキスト入力欄で(ビジュアルタブの
-
-
WordPress で VR させて、360°のパノラマ画像を表示する
WordPress.com内ショートコードで VR させる WordPress.com内で、VR(
-
-
写真をアップロードして切り抜きが出来るcropboxにタッチイベントを付けてみる
Git Hub の cropbox 写真をアップロードしてカット出来るjQueryのプラグイン c
-
-
javascriptで複数同じ名前のformの値を取得するとエラー Cannot read property ‘value’ of undefined
Javascript で value の値を取得する このようなHTMLフォームがあった場合、
-
-
Javascript ノードの取得や挿入
ノードの取得 ノードの取得(ダイレクトアクセス) document.getElementById
-
-
WEBページをアプリっぽくする(サービスワーカーでホーム画面に追加)
前回作ったお絵かきページを、簡単にアプリっぽくしようと思います。 具体的には、スマホで最近よく見か
-
-
Javascript タイピング ゲーム スマホ用 をつくる
JavaScript スマホ用 切り替え 前回の記事のゲームですが、スマホだとサイズが合わなくてや
-
-
HTML5 audio タグ を使って音声を出す
HTML5からaudioタグを使えば、Flashなどのプラグインを使わなくてもブラウザ上で音声を再生