-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathTwoFingerSync.js
123 lines (110 loc) · 4.31 KB
/
TwoFingerSync.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Owner: [email protected]
* @license MPL 2.0
* @copyright Famous Industries, Inc. 2014
*/
define(function(require, exports, module) {
var EventHandler = require('famous/core/EventHandler');
/**
* Helper to PinchSync, RotateSync, and ScaleSync. Generalized handling of
* two-finger touch events.
* This class is meant to be overridden and not used directly.
*
* @class TwoFingerSync
* @constructor
*/
function TwoFingerSync() {
this._eventInput = new EventHandler();
this._eventOutput = new EventHandler();
EventHandler.setInputHandler(this, this._eventInput);
EventHandler.setOutputHandler(this, this._eventOutput);
this.touchAEnabled = false;
this.touchAId = 0;
this.posA = null;
this.timestampA = 0;
this.touchBEnabled = false;
this.touchBId = 0;
this.posB = null;
this.timestampB = 0;
this._eventInput.on('touchstart', this.handleStart.bind(this));
this._eventInput.on('touchmove', this.handleMove.bind(this));
this._eventInput.on('touchend', this.handleEnd.bind(this));
this._eventInput.on('touchcancel', this.handleEnd.bind(this));
}
TwoFingerSync.calculateAngle = function(posA, posB) {
var diffX = posB[0] - posA[0];
var diffY = posB[1] - posA[1];
return Math.atan2(diffY, diffX);
};
TwoFingerSync.calculateDistance = function(posA, posB) {
var diffX = posB[0] - posA[0];
var diffY = posB[1] - posA[1];
return Math.sqrt(diffX * diffX + diffY * diffY);
};
TwoFingerSync.calculateCenter = function(posA, posB) {
return [(posA[0] + posB[0]) / 2.0, (posA[1] + posB[1]) / 2.0];
};
var _now = Date.now;
// private
TwoFingerSync.prototype.handleStart = function handleStart(event) {
for (var i = 0; i < event.changedTouches.length; i++) {
var touch = event.changedTouches[i];
if (!this.touchAEnabled) {
this.touchAId = touch.identifier;
this.touchAEnabled = true;
this.posA = [touch.pageX, touch.pageY];
this.timestampA = _now();
}
else if (!this.touchBEnabled) {
this.touchBId = touch.identifier;
this.touchBEnabled = true;
this.posB = [touch.pageX, touch.pageY];
this.timestampB = _now();
this._startUpdate(event);
}
}
};
// private
TwoFingerSync.prototype.handleMove = function handleMove(event) {
if (!(this.touchAEnabled && this.touchBEnabled)) return;
var prevTimeA = this.timestampA;
var prevTimeB = this.timestampB;
var diffTime;
for (var i = 0; i < event.changedTouches.length; i++) {
var touch = event.changedTouches[i];
if (touch.identifier === this.touchAId) {
this.posA = [touch.pageX, touch.pageY];
this.timestampA = _now();
diffTime = this.timestampA - prevTimeA;
}
else if (touch.identifier === this.touchBId) {
this.posB = [touch.pageX, touch.pageY];
this.timestampB = _now();
diffTime = this.timestampB - prevTimeB;
}
}
if (diffTime) this._moveUpdate(diffTime);
};
// private
TwoFingerSync.prototype.handleEnd = function handleEnd(event) {
for (var i = 0; i < event.changedTouches.length; i++) {
var touch = event.changedTouches[i];
if (touch.identifier === this.touchAId || touch.identifier === this.touchBId) {
if (this.touchAEnabled && this.touchBEnabled) {
this._eventOutput.emit('end', {
touches : [this.touchAId, this.touchBId],
angle : this._angle
});
}
this.touchAEnabled = false;
this.touchAId = 0;
this.touchBEnabled = false;
this.touchBId = 0;
}
}
};
module.exports = TwoFingerSync;
});