VulpesOS/gaia/apps/camera/js/lib/pinch.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

140 lines
2.8 KiB
JavaScript
Executable file

define(function(require, exports, module) {
'use strict';
/**
* Dependencies
*/
var unbind = require('lib/bind').unbind;
var bindAll = require('lib/bind-all');
var bind = require('lib/bind');
var events = require('evt');
/**
* Mixin event emitter
*/
events(Pinch.prototype);
/**
* Exports
*/
module.exports = Pinch;
/**
* Initialize a new `Pinch` interface.
*
* @constructor
*/
function Pinch(el) {
bindAll(this);
this.attach(el);
}
Pinch.prototype.attach = function(el) {
this.el = el;
bind(this.el, 'touchstart', this.onTouchStart);
bind(window, 'touchmove', this.onTouchMove);
bind(window, 'touchend', this.onTouchEnd);
};
Pinch.prototype.detach = function() {
unbind(this.el, 'touchstart', this.onTouchStart);
unbind(window, 'touchmove', this.onTouchMove);
unbind(window, 'touchend', this.onTouchEnd);
this.el = null;
};
Pinch.prototype.enable = function() {
this.disabled = false;
};
Pinch.prototype.disable = function() {
this.disabled = true;
};
Pinch.prototype.onTouchStart = function(evt) {
if (evt.touches.length !== 2 || this.disabled) {
return;
}
this.lastTouchA = evt.touches[0];
this.lastTouchB = evt.touches[1];
this.isPinching = true;
this.emit('started');
};
Pinch.prototype.onTouchMove = function(evt) {
if (!this.isPinching || this.disabled) {
return;
}
var touchA = getNewTouchA(this, evt.touches);
var touchB = getNewTouchB(this, evt.touches);
var deltaPinch = getDeltaPinch(this, touchA, touchB);
this.emit('changed', deltaPinch);
this.lastTouchA = touchA;
this.lastTouchB = touchB;
};
Pinch.prototype.onTouchEnd = function(evt) {
if (!this.isPinching || this.disabled) {
return;
}
if (evt.touches.length < 2) {
this.isPinching = false;
this.emit('ended');
}
};
function getNewTouchA(pinch, touches) {
if (!pinch.lastTouchA) {
return null;
}
for (var i = 0, length = touches.length, touch; i < length; i++) {
touch = touches[i];
if (touch.identifier === pinch.lastTouchA.identifier) {
return touch;
}
}
return null;
}
function getNewTouchB(pinch, touches) {
if (!pinch.lastTouchB) {
return null;
}
for (var i = 0, length = touches.length, touch; i < length; i++) {
touch = touches[i];
if (touch.identifier === pinch.lastTouchB.identifier) {
return touch;
}
}
return null;
}
function getDeltaPinch(pinch, touchA, touchB) {
var lastTouchA = pinch.lastTouchA;
var lastTouchB = pinch.lastTouchB;
if (!touchA || !lastTouchA || !touchB || !lastTouchB) {
return 0;
}
var oldDistance = Math.sqrt(
Math.pow(lastTouchB.pageX - lastTouchA.pageX, 2) +
Math.pow(lastTouchB.pageY - lastTouchA.pageY, 2));
var newDistance = Math.sqrt(
Math.pow(touchB.pageX - touchA.pageX, 2) +
Math.pow(touchB.pageY - touchA.pageY, 2));
return newDistance - oldDistance;
}
});