Skip to content
This repository has been archived by the owner on Mar 13, 2018. It is now read-only.

Commit

Permalink
start of a working pinch/rotate impl
Browse files Browse the repository at this point in the history
  • Loading branch information
dfreedm committed Dec 5, 2013
1 parent 000916c commit f1c64f4
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 0 deletions.
1 change: 1 addition & 0 deletions build.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
"src/hold.js",
"src/track.js",
"src/flick.js",
"src/pinch.js",
"src/tap.js"
]
1 change: 1 addition & 0 deletions pointergestures.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
'src/hold.js',
'src/track.js',
'src/flick.js',
'src/pinch.js',
'src/tap.js'
];

Expand Down
109 changes: 109 additions & 0 deletions src/pinch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright 2013 The Polymer Authors. All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/

/*
* Basic strategy: find the farthest apart points, use as diameter of circle
* react to size change and rotation of the chord
*/

(function(scope) {
var dispatcher = scope.dispatcher;
var pointermap = new scope.PointerMap();
var RAD_TO_DEG = 180 / Math.PI;
var pinch = {
events: [
'pointerdown',
'pointermove',
'pointerup',
'pointercancel'
],
reference: {},
pointerdown: function(ev) {
pointermap.set(ev.pointerId, ev);
if (pointermap.pointers() == 2) {
var points = this.calcChord();
var angle = this.calcAngle(points);
this.reference = {
angle: angle,
diameter: points.diameter,
target: scope.findLCA(points.a.target, points.b.target)
};
}
},
pointerup: function(ev) {
pointermap.delete(ev.pointerId);
},
pointermove: function(ev) {
if (pointermap.has(ev.pointerId)) {
pointermap.set(ev.pointerId, ev);
if (pointermap.pointers() > 1) {
this.calcPinchRotate();
}
}
},
pointercancel: function(ev) {
this.pointerup(ev);
},
dispatchPinch: function(diameter, target) {
var zoom = diameter / this.reference.diameter;
var ev = dispatcher.makeEvent('pinch', {
scale: zoom
});
dispatcher.dispatchEvent(ev, this.reference.target);
},
dispatchRotate: function(angle) {
var diff = Math.round((angle - this.reference.angle) % 360);
var ev = dispatcher.makeEvent('rotate', {
angle: diff
});
dispatcher.dispatchEvent(ev, this.reference.target);
},
calcPinchRotate: function() {
var points = this.calcChord();
var diameter = points.diameter;
var angle = this.calcAngle(points);
if (diameter != this.reference.diameter) {
this.dispatchPinch(diameter);
}
if (angle != this.reference.angle) {
this.dispatchRotate(angle);
}
},
calcChord: function() {
var pointers = [];
pointermap.forEach(function(p) {
pointers.push(p);
});
var dist = 0;
var points = {};
var x, y, d;
for (var i = 0; i < pointers.length; i++) {
var a = pointers[i];
for (var j = i + 1; j < pointers.length; j++) {
var b = pointers[j];
x = Math.abs(a.clientX - b.clientX);
y = Math.abs(a.clientY - b.clientY);
d = x + y;
if (d > dist) {
dist = d;
points = {a: a, b: b};
}
}
}
x = Math.abs(points.a.clientX - points.b.clientX / 2);
y = Math.abs(points.a.clientY - points.b.clientY / 2);
points.center = { x: x, y: y };
points.diameter = dist;
return points;
},
calcAngle: function(points) {
var x = points.a.clientX - points.b.clientX;
var y = points.a.clientY - points.b.clientY;
return (360 + Math.atan2(y, x) * RAD_TO_DEG) % 360;
},
};
dispatcher.registerRecognizer('pinch', pinch);
})(window.PointerGestures);

0 comments on commit f1c64f4

Please sign in to comment.