Permalink
Browse files

Touch support!

This adds basic touch support, including single touch (pan) and double touch
(pan and zoom). In a future change, I'd also like to support rotation for double
touch, and double-tap to snap to the nearest integer zoom level. This commit
also includes a simple example that shows how to specify 2x resolution tiles for
the iPhone 4's retina display.
  • Loading branch information...
1 parent b756f5a commit 2035dacf2cc3387873f004a2d70cf3e1475e14fd @mbostock committed Apr 7, 2011
Showing with 245 additions and 62 deletions.
  1. +1 −0 Makefile
  2. +21 −0 examples/iphone4/iphone4.html
  3. +15 −0 examples/iphone4/iphone4.js
  4. +72 −0 polymaps.js
  5. +64 −62 polymaps.min.js
  6. +2 −0 src/Interact.js
  7. +70 −0 src/Touch.js
View
@@ -17,6 +17,7 @@ JS_FILES = \
src/Wheel.js \
src/Arrow.js \
src/Hash.js \
+ src/Touch.js \
src/Interact.js \
src/Compass.js \
src/Grid.js \
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" />
+ <script type="text/javascript" src="../../polymaps.js"></script>
+ <style type="text/css">
+
+@import url("../example.css");
+
+ </style>
+ </head>
+ <body id="map">
+ <script type="text/javascript" src="iphone4.js"></script>
+ <span id="copy">
+ &copy; 2011
+ <a href="http://www.cloudmade.com/">CloudMade</a>,
+ <a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors,
+ <a href="http://creativecommons.org/licenses/by-sa/2.0/">CCBYSA</a>.
+ </span>
+ </body>
+</html>
@@ -0,0 +1,15 @@
+var po = org.polymaps;
+
+var map = po.map()
+ .container(document.getElementById("map").appendChild(po.svg("svg")))
+ .add(po.interact()); // built-in touch support
+
+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
+
+// no compass! pinch-to-zoom ftw
View
@@ -1840,18 +1840,90 @@ po.hash = function() {
return hash;
};
+po.touch = function() {
+ var touch = {},
+ map,
+ container,
+ locations = {}; // touch identifier -> location
+
+ window.addEventListener("touchmove", touchmove, false);
+ window.addEventListener("touchend", touchend, false);
+
+ function touchstart(e) {
+ var i = -1,
+ n = e.touches.length,
+ t;
+ while (++i < n) {
+ t = e.touches[i];
+ locations[t.identifier] = map.pointLocation(map.mouse(t));
+ }
+ e.preventDefault();
+ }
+
+ function touchmove(e) {
+ switch (e.touches.length) {
+ case 1: {
+ var t0 = e.touches[0];
+ map.zoomBy(0, map.mouse(t0), locations[t0.identifier]);
+ break;
+ }
+ case 2: { // TODO rotation!
+ var t0 = e.touches[0],
+ t1 = e.touches[1],
+ p0 = map.mouse(t0),
+ p1 = map.mouse(t1),
+ p2 = {x: (p0.x + p1.x) / 2, y: (p0.y + p1.y) / 2}, // center point
+ 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);
+ break;
+ }
+ }
+ e.preventDefault();
+ }
+
+ function touchend(e) {
+ e.preventDefault();
+ }
+
+ touch.map = function(x) {
+ if (!arguments.length) return map;
+ if (map) {
+ container.removeEventListener("touchstart", touchstart, false);
+ container = null;
+ }
+ if (map = x) {
+ container = map.container();
+ container.addEventListener("touchstart", touchstart, false);
+ }
+ return touch;
+ };
+
+ return touch;
+};
// Default map controls.
po.interact = function() {
var interact = {},
drag = po.drag(),
wheel = po.wheel(),
dblclick = po.dblclick(),
+ touch = po.touch(),
arrow = po.arrow();
interact.map = function(x) {
drag.map(x);
wheel.map(x);
dblclick.map(x);
+ touch.map(x);
arrow.map(x);
return interact;
};
Oops, something went wrong.

0 comments on commit 2035dac

Please sign in to comment.