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
Original file line number Diff line number Diff line change
@@ -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
23 changes: 10 additions & 13 deletions polymaps.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
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});

// 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
Expand Down Expand Up @@ -1846,6 +1846,8 @@ po.touch = function() {
container,
rotate = false,
last = 0,
zoom,
angle,
locations = {}; // touch identifier -> location

window.addEventListener("touchmove", touchmove, false);
Expand All @@ -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));
Expand All @@ -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;
}
Expand Down
Loading

0 comments on commit f4c3ff1

Please sign in to comment.