p5.js でのタッチ操作、具体的には「回転、ピンチイン/ピンチアウト」の操作になるのですが、それらを Hammer.JS を使って実装してみた、という話です。
最初に、今回実装したものを動作させた際の動画を掲載します。
ここから実装をした話を書いていきます。
他の方が作られたサンプル
既に、Hammer.JS と p5.js を組み合わせて使われてる方がいないか、それらをキーワードにして検索すると、以下のページが検索でヒットします。
●p5.js Web Editor | hammer.js swipe
https://editor.p5js.org/shiffman/sketches/HyEDRsPel
このサンプルは、Hammer.JS と p5.js を組み合わせてスワイプ操作を判定しているものでした。JavaScript のプログラムは以下の通りです。
var msg = "swipe";
function setup() {
createCanvas(windowWidth, windowHeight);
textAlign(CENTER);
textSize(30);
noStroke();
// set options to prevent default behaviors for swipe, pinch, etc
var options = {
preventDefault: true
};
// document.body registers gestures anywhere on the page
var hammer = new Hammer(document.body, options);
hammer.get('swipe').set({
direction: Hammer.DIRECTION_ALL
});
hammer.on("swipe", swiped);
}
function draw() {
background(250, 10, 100);
text(msg, width / 2, height / 2);
}
function swiped(event) {
console.log(event);
if (event.direction == 4) {
msg = "you swiped right";
} else if (event.direction == 8) {
msg = "you swiped up";
} else if (event.direction == 16) {
msg = "you swiped down";
} else if (event.direction == 2) {
msg = "you swiped left";
}
}
上記の実装ではスワイプ操作のみを対象としていますが、内容的には簡単に「回転、ピンチイン/ピンチアウト」の操作にも流用できそうです。
回転を実装する
まずはスマホの画面上で、2本指で回転させる操作をした場合に、キャンバスを回転させるものを作ってみます。実装は、p5.js Web Editor を用いて行います。
以下に JavaScript のプログラムを掲載します。Hammer.JS を利用するために、p5.js Web Editor の index.html で、Hammer.JS を読み込む行を加えるのを忘れないようにしてください(※ 自分は CDN上のライブラリを読み込むようにしました)。
let rStart, r, rEventStart;
function setup() {
createCanvas(windowWidth, windowHeight);
r = 0;
const hammer = new Hammer(document.body, {
preventDefault: true,
});
hammer.get("rotate").set({ enable: true });
hammer.on("rotate", onRotate);
}
function onRotate(event) {
if (event.eventType === Hammer.INPUT_START) {
rStart = r;
rEventStart = event.rotation;
} else if (event.eventType === Hammer.INPUT_MOVE || Hammer.INPUT_END) {
r = rStart + radians(event.rotation - rEventStart);
}
}
function draw() {
background(220);
translate(width / 2, height / 2);
rotate(r);
line(-0.3 * width, 0, 0.3 * width, 0);
}
プログラムについて、少し補足します。
setup() の部分では、Hammer.JS の回転を利用するための処理を書いています。
また、draw() の中の処理は線を描画しており、その際、キャンバスの中心を原点として描画を回転させています。その回転する角度は、onRotate() の中で決めています。
そして、onRotate() の中では、回転の操作開始時と、その後の回転操作継続・終了時の処理を書いています。回転の操作開始時には、その時点でのキャンバスを回転させている角度と、タッチ操作で検出された角度を保存しています(event.rotation
で得られる値は、マルチタッチした際のタッチした 2点がなす角度となるようです)。
その後の回転操作継続・終了時の処理では、最初に覚えた値から動いた角度分だけ、キャンバスを回転させるようにしています。なお、event.rotation は度数法(度)の値のようなので、弧度法(ラジアン)に変換して利用しています。
ここで用いた Hammer.JS のイベント(rotation)の内容については、公式ページの API のページ を参照ください。
拡大/縮小を実装する
次は、拡大/縮小です。
以下に JavaScript のプログラムを掲載します。先ほどと同様に、Hammer.JS を利用するために、p5.js Web Editor の index.html で、Hammer.JS を読み込む行を加えるのを忘れないようにしてください。
let s, sEnd;
function setup() {
createCanvas(windowWidth, windowHeight);
sEnd = 1;
const hammer = new Hammer(document.body, {
preventDefault: true,
});
hammer.get("pinch").set({ enable: true });
hammer.on("pinch", onPinch);
}
function onPinch(event) {
if (event.eventType === Hammer.INPUT_END) {
sEnd = s;
} else {
s = sEnd * event.scale;
if (s < 0.5) {
s = 0.5;
} else if (s > 3) {
s = 3;
}
}
}
function draw() {
background(220);
translate(width / 2, height / 2);
scale(s);
rect(-50, -50, 100);
line(-0.3 * width, 0, 0.3 * width, 0);
}
今回のプログラムでは、ピンチイン/ピンチアウトを行った際に、キャンバスで描画する図形の拡大/縮小を行うようにしています。
基本的に、ピンチ操作をしている間は、拡大/縮小率を描画にそのまま反映させています。そして、ピンチ操作が終了した際に、その際の拡大/縮小に用いた割合の値を、変数に保存しています(なおこの値は、最初は「1」で初期化しています)。