Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multitouch pan and zoom support #59

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ JS_FILES = \
src/GeoJson.js \
src/Dblclick.js \
src/Drag.js \
src/Touch.js \
src/Wheel.js \
src/Arrow.js \
src/Hash.js \
Expand Down
47 changes: 47 additions & 0 deletions examples/touch/map.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<!-- width, initial-scale, maximum-scale and user-scalable are from iphone docs -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<script type="text/javascript" src="../../lib/jquery/jquery.min.js"></script>
<script type="text/javascript" src="../../polymaps.js"></script>
<style type="text/css">

@import url("../example.css");

html, body {
overflow: hidden;
}

.compass .chevron, .compass .fore {
stroke: #666;
}

#map {
background: #132328;
}

#logo {
position: absolute;
right: 0;
bottom: 0;
pointer-events: none;
}

#copy {
width: 33%;
color: #ccc;
pointer-events: none;
}

</style>
</head>
<body id="map">
<script type="text/javascript" src="map.js"></script>
<div id="copy"></div>
<img id="logo"/>
</body>
</html>
71 changes: 71 additions & 0 deletions examples/touch/map.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
var po = org.polymaps;

var div = document.getElementById("map");

var map = po.map()
.container(div.appendChild(po.svg("svg")))
.add(po.touch())
// .add(po.hash());

/*
* Load the "AerialWithLabels" metadata. "Aerial" and "Road" also work. For more
* information about the Imagery Metadata service, see
* http://msdn.microsoft.com/en-us/library/ff701716.aspx
* You should register for your own key at https://www.bingmapsportal.com/.
*/
var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
script.setAttribute("src", "http://dev.virtualearth.net"
+ "/REST/V1/Imagery/Metadata/AerialWithLabels"
+ "?key=AmT-ZC3HPevQq5IBJ7v8qiDUxrojNaqbW1zBsKF0oMNEs53p7Nk5RlAuAmwSG7bg"
+ "&jsonp=callback");
document.body.appendChild(script);

function callback(data) {

/* Display each resource as an image layer. */
var resourceSets = data.resourceSets;
for (var i = 0; i < resourceSets.length; i++) {
var resources = data.resourceSets[i].resources;
for (var j = 0; j < resources.length; j++) {
var resource = resources[j];
map.add(po.image()
.url(template(resource.imageUrl, resource.imageUrlSubdomains)))
.tileSize({x: resource.imageWidth, y: resource.imageHeight});
}
}

/* Display brand logo. */
document.getElementById("logo").src = data.brandLogoUri;

/* Display copyright notice. */
document.getElementById("copy").appendChild(document.createTextNode(data.copyright));

/* Display compass control. */
map.add(po.compass()
.pan("none"));

}

/** Returns a Bing URL template given a string and a list of subdomains. */
function template(url, subdomains) {
var n = subdomains.length,
salt = ~~(Math.random() * n); // per-session salt

/** Returns the given coordinate formatted as a 'quadkey'. */
function quad(column, row, zoom) {
var key = "";
for (var i = 1; i <= zoom; i++) {
key += (((row >> zoom - i) & 1) << 1) | ((column >> zoom - i) & 1);
}
return key;
}

return function(c) {
var quadKey = quad(c.column, c.row, c.zoom),
server = Math.abs(salt + c.column + c.row + c.zoom) % n;
return url
.replace("{quadkey}", quadKey)
.replace("{subdomain}", subdomains[server]);
};
}
90 changes: 86 additions & 4 deletions polymaps.js
Original file line number Diff line number Diff line change
Expand Up @@ -1543,6 +1543,88 @@ po.drag = function() {

return drag;
};
po.touch = function() {
var touch = {},
map,
last;

touch.map = function(x) {
if (!arguments.length) return map;
if (map) {
var container = map.container();
container.removeEventListener("touchstart", touchstart, false);
container.removeEventListener("touchmove", touchmove, false);
container.removeEventListener("touchend", touchend, false);
container.removeEventListener("touchcancel", touchend, false);
}
if (map = x) {
var container = map.container();
container.addEventListener("touchstart", touchstart, false);
container.addEventListener("touchmove", touchmove, false);
container.addEventListener("touchend", touchend, false);
container.addEventListener("touchcancel", touchend, false);
}
return touch;
}

function updateMap(last, now) {
var delta = {
x: now.clientX - last.clientX,
y: now.clientY - last.clientY,
scale: now.scale - last.scale
};
if (delta.x || delta.y || delta.scale) {
var oldPoint = map.mouse(last),
location = map.pointLocation(oldPoint);
map.zoomBy(delta.scale, map.mouse(now), location);
}
}

function touchstart(e) {
if (last) {
// if new finger being added, finish current move sequence first
touchend();
}
e.preventDefault();

last = touchesCenter(e);
}

function touchmove(e) {
if (!last) {
// if finger was lifted, start new move sequence instead
return touchstart(e);
}
e.preventDefault();

var now = touchesCenter(e);
updateMap(last, now);
last = now;
}

function touchend(e) {
last = null;
}

function touchesCenter(e) {
var touches = e.touches;
var sumX = 0, sumY = 0;
for (var i = 0; i < touches.length; ++i) {
var touch = touches[i];
sumX += touch.clientX;
sumY += touch.clientY;
}
return {
clientX: sumX / touches.length,
pageX: sumX / touches.length,
clientY: sumY / touches.length,
pageY: sumY / touches.length,
scale: e.scale
};
}

return touch;
};
po.wheel = function() {
var wheel = {},
timePrev = 0,
Expand Down Expand Up @@ -1763,10 +1845,9 @@ po.hash = function() {
lat = 90 - 1e-8, // allowable latitude range
map;

var parser = function(s) {
var parser = function(map, s) {
var args = s.split("/").map(Number);
if (args.length < 3 || args.some(isNaN))
move(); // replace bogus hash
if (args.length < 3 || args.some(isNaN)) return true; // replace bogus hash
else {
var size = map.size();
map.zoomBy(args[0] - map.zoom(),
Expand All @@ -1791,7 +1872,8 @@ po.hash = function() {

function hashchange() {
if (location.hash === s0) return; // ignore spurious hashchange events
parser((s0 = location.hash).substring(1));
if (parser(map, (s0 = location.hash).substring(1)))
move(); // replace bogus hash
}

hash.map = function(x) {
Expand Down
Loading