@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
128 lines (101 loc) • 3.09 kB
JavaScript
import Vector2 from "../../../../core/geom/Vector2.js";
import { getTouchCenter } from "./getTouchCenter.js";
/**
*
* @param {TouchList} touchList
* @param {function(Touch,number)} callback
*/
function forEachTouch(touchList, callback) {
const length = touchList.length;
for (let i = 0; i < length; i++) {
const touch = touchList.item(i);
callback(touch, i);
}
}
/**
*
* @param {Signal} touchStart
* @param {Signal} touchEnd
* @param {Signal} touchMove
* @param {Signal} pinch
* @param {Signal} pinchStart
* @param {Signal} pinchEnd
* @param {PointerDevice} device
*/
export function observePinch({
touchStart,
touchEnd,
touchMove,
pinch,
pinchStart,
pinchEnd,
device
}) {
const center = new Vector2();
const v2 = new Vector2();
const pinchBox0 = new Vector2();
const pinchBox1 = new Vector2();
let pinchActive = false;
let touchCount = 0;
/**
*
* @param {TouchList} touchList
* @param {Vector2} pinchDimensions
*/
function computeTouchRadius(touchList, pinchDimensions) {
getTouchCenter(touchList, center);
const length = touchList.length;
pinchDimensions.set(0, 0);
for (let i = 0; i < length; i++) {
const touch = touchList.item(i);
device.readPointerPositionFromEvent(v2, touch);
v2.sub(center);
v2.abs();
pinchDimensions.add(v2);
}
return pinchDimensions.multiplyScalar(1 / length);
}
function touchRemoved(touch, event) {
touchCount--;
if (touchCount < 2 && pinchActive) {
handlePinchEnd(event);
}
}
function touchAdded(touch, event) {
touchCount++;
if (touchCount > 1 && !pinchActive) {
handlePinchStart(event);
}
}
function handlePinchStart(event) {
pinchActive = true;
computeTouchRadius(event.touches, pinchBox0);
touchMove.add(handleMove);
pinchStart.send1(pinchBox0);
}
/**
*
* @param {TouchEvent} event
*/
function handlePinchEnd(event) {
pinchActive = false;
touchMove.remove(handleMove);
pinchEnd.send0();
}
function handleDown(position, event) {
forEachTouch(event.changedTouches, function (touch) {
touchAdded(touch, event);
});
}
function handleUp(position, event) {
forEachTouch(event.changedTouches, function (touch) {
touchRemoved(touch, event);
});
}
function handleMove(position, event) {
computeTouchRadius(event.touches, pinchBox1);
pinch.send2(pinchBox1, pinchBox0);
}
touchEnd.add(handleUp);
touchStart.add(handleDown);
}