Skip to content

Commit

Permalink
Use touch event's scale and rotation fields.
Browse files Browse the repository at this point in the history
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
mbostock committed Apr 8, 2011
1 parent acca777 commit f4c3ff1
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 90 deletions.
10 changes: 7 additions & 3 deletions examples/iphone4/iphone4.js
@@ -1,15 +1,19 @@
var po = org.polymaps; var po = org.polymaps;


// Note: po.interact has built-in touch support!
var map = po.map() var map = po.map()
.container(document.getElementById("map").appendChild(po.svg("svg"))) .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() map.add(po.image()
.url(po.url("http://{S}tile.cloudmade.com" .url(po.url("http://{S}tile.cloudmade.com"
+ "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register
+ "/998/256/{Z}/{X}/{Y}.png") + "/998/256/{Z}/{X}/{Y}.png")
.repeat(false)
.hosts(["a.", "b.", "c.", ""])) .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 // no compass! pinch-to-zoom ftw
23 changes: 10 additions & 13 deletions polymaps.js
Expand Up @@ -40,7 +40,7 @@ po.transform = function(a, b, c, d, e, f) {
transform.zoomFraction = function(x) { transform.zoomFraction = function(x) {
if (!arguments.length) return zoomFraction; if (!arguments.length) return zoomFraction;
zoomFraction = x; 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); k = Math.pow(2, -zoomDelta);
return transform; return transform;
}; };
Expand Down Expand Up @@ -625,7 +625,7 @@ po.map = function() {
l = map.pointLocation({x: (bl.x + tr.x) / 2, y: (bl.y + tr.y) / 2}); l = map.pointLocation({x: (bl.x + tr.x) / 2, y: (bl.y + tr.y) / 2});


// update the zoom level // update the zoom level
zoom = zoom + zoomFraction - Math.log(k) / Math.log(2); zoom = zoom + zoomFraction - Math.log(k) / Math.LN2;
rezoom(); rezoom();


// set the new center // set the new center
Expand Down Expand Up @@ -1846,6 +1846,8 @@ po.touch = function() {
container, container,
rotate = false, rotate = false,
last = 0, last = 0,
zoom,
angle,
locations = {}; // touch identifier -> location locations = {}; // touch identifier -> location


window.addEventListener("touchmove", touchmove, false); window.addEventListener("touchmove", touchmove, false);
Expand All @@ -1863,7 +1865,9 @@ po.touch = function() {
} }
last = t; last = t;


// store original touch locations // store original zoom & touch locations
zoom = map.zoom();
angle = map.angle();
while (++i < n) { while (++i < n) {
t = e.touches[i]; t = e.touches[i];
locations[t.identifier] = map.pointLocation(map.mouse(t)); locations[t.identifier] = map.pointLocation(map.mouse(t));
Expand All @@ -1887,16 +1891,9 @@ po.touch = function() {
c0 = po.map.locationCoordinate(locations[t0.identifier]), c0 = po.map.locationCoordinate(locations[t0.identifier]),
c1 = po.map.locationCoordinate(locations[t1.identifier]), c1 = po.map.locationCoordinate(locations[t1.identifier]),
c2 = {row: (c0.row + c1.row) / 2, column: (c0.column + c1.column) / 2, zoom: 0}, c2 = {row: (c0.row + c1.row) / 2, column: (c0.column + c1.column) / 2, zoom: 0},
l2 = po.map.coordinateLocation(c2), // center location l2 = po.map.coordinateLocation(c2); // center location
px = p0.x - p1.x, map.zoomBy(Math.log(e.scale) / Math.LN2 + zoom - map.zoom(), p2, l2);
py = p0.y - p1.y, if (rotate) map.angle(e.rotation / 180 * Math.PI + angle);
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));
e.preventDefault(); e.preventDefault();
break; break;
} }
Expand Down

0 comments on commit f4c3ff1

Please sign in to comment.