Permalink
Browse files

Use touch event's scale and rotation fields.

Thanks to @natevw, I see there are `scale` and `rotation` fields on the touch
event that we can use to compute the zoom and angle offsets more easily. Also,
this commit updates the example to auto-detect retina displays using the
devicePixelRatio field of the current window.
  • Loading branch information...
1 parent acca777 commit f4c3ff1d1a946939dfaf634b041ca130ab0f7b06 @mbostock mbostock committed Apr 8, 2011
Showing with 88 additions and 90 deletions.
  1. +7 −3 examples/iphone4/iphone4.js
  2. +10 −13 polymaps.js
  3. +61 −61 polymaps.min.js
  4. +1 −1 src/Map.js
  5. +8 −11 src/Touch.js
  6. +1 −1 src/Transform.js
@@ -1,15 +1,19 @@
var po = org.polymaps;
+// Note: po.interact has built-in touch support!
var map = po.map()
.container(document.getElementById("map").appendChild(po.svg("svg")))
- .add(po.interact()); // built-in touch support
+ .add(po.interact());
+// Compute zoom offset for retina display.
+var dz = Math.log(window.devicePixelRatio || 1) / Math.LN2;
+
+// CloudMade image tiles, hooray!
map.add(po.image()
.url(po.url("http://{S}tile.cloudmade.com"
+ "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register
+ "/998/256/{Z}/{X}/{Y}.png")
- .repeat(false)
.hosts(["a.", "b.", "c.", ""]))
- .zoom(function(z) { return z + 1; })); // use 2x resolution tiles
+ .zoom(function(z) { return z + dz; }));
// no compass! pinch-to-zoom ftw
View
@@ -40,7 +40,7 @@ po.transform = function(a, b, c, d, e, f) {
transform.zoomFraction = function(x) {
if (!arguments.length) return zoomFraction;
zoomFraction = x;
- zoomDelta = Math.floor(zoomFraction + Math.log(Math.sqrt(a * a + b * b + c * c + d * d)) / Math.log(2));
+ zoomDelta = Math.floor(zoomFraction + Math.log(Math.sqrt(a * a + b * b + c * c + d * d)) / Math.LN2);
k = Math.pow(2, -zoomDelta);
return transform;
};
@@ -625,7 +625,7 @@ po.map = function() {
l = map.pointLocation({x: (bl.x + tr.x) / 2, y: (bl.y + tr.y) / 2});
// update the zoom level
- zoom = zoom + zoomFraction - Math.log(k) / Math.log(2);
+ zoom = zoom + zoomFraction - Math.log(k) / Math.LN2;
rezoom();
// set the new center
@@ -1846,6 +1846,8 @@ po.touch = function() {
container,
rotate = false,
last = 0,
+ zoom,
+ angle,
locations = {}; // touch identifier -> location
window.addEventListener("touchmove", touchmove, false);
@@ -1863,7 +1865,9 @@ po.touch = function() {
}
last = t;
- // store original touch locations
+ // store original zoom & touch locations
+ zoom = map.zoom();
+ angle = map.angle();
while (++i < n) {
t = e.touches[i];
locations[t.identifier] = map.pointLocation(map.mouse(t));
@@ -1887,16 +1891,9 @@ po.touch = function() {
c0 = po.map.locationCoordinate(locations[t0.identifier]),
c1 = po.map.locationCoordinate(locations[t1.identifier]),
c2 = {row: (c0.row + c1.row) / 2, column: (c0.column + c1.column) / 2, zoom: 0},
- l2 = po.map.coordinateLocation(c2), // center location
- px = p0.x - p1.x,
- py = p0.y - p1.y,
- dp = Math.sqrt(px * px + py * py) / 256,
- cx = c0.column - c1.column,
- cy = c0.row - c1.row,
- dc = Math.sqrt(cx * cx + cy * cy),
- z2 = Math.log(dp / dc) / Math.log(2); // zoom level
- map.zoomBy(z2 - map.zoom(), p2, l2);
- if (rotate) map.angle(Math.atan2(cx, cy) - Math.atan2(px, py));
+ l2 = po.map.coordinateLocation(c2); // center location
+ map.zoomBy(Math.log(e.scale) / Math.LN2 + zoom - map.zoom(), p2, l2);
+ if (rotate) map.angle(e.rotation / 180 * Math.PI + angle);
e.preventDefault();
break;
}
Oops, something went wrong.

0 comments on commit f4c3ff1

Please sign in to comment.