Permalink
Browse files

Use webkit-transform: matrix3d.

Also, add scrolling example.
  • Loading branch information...
mbostock committed Aug 29, 2011
1 parent 9ff1720 commit e0224e8dceb5044aacb17f1174cabac80ced6884
Showing with 109 additions and 48 deletions.
  1. +11 −3 examples/{cloudmade/midnight-commander.html → drag.html}
  2. +69 −0 examples/scroll.html
  3. +14 −22 pixymaps.js
  4. +1 −1 pixymaps.min.js
  5. +14 −22 src/image.js
@@ -10,10 +10,18 @@
font: 10px sans-serif;
}
+#container {
+ width: 960px;
+ height: 500px;
+ overflow: hidden;
+}
+
</style>
</head>
<body>
- <canvas id="map" width="960" height="500"></canvas>
+ <div id="container">
+ <canvas id="map"></canvas>
+ </div>
<script type="text/javascript">
var canvas = d3.select("#map").call(drag),
@@ -39,7 +47,7 @@
+ "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register
+ "/999/256/{Z}/{X}/{Y}.png")
.hosts(["a.", "b.", "c.", ""]))
- .render(context);
+ .render(canvas.node());
function drag(selection) {
var p0;
@@ -56,7 +64,7 @@
if (p0) {
var p1 = [d3.event.pageX, d3.event.pageY];
view.panBy([p1[0] - p0[0], p1[1] - p0[1]]);
- image.render(context);
+ image.render(canvas.node());
p0 = p1;
d3.event.preventDefault();
}
View
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script type="text/javascript" src="../../pixymaps.js"></script>
+ <script type="text/javascript" src="../../lib/d3/d3.js"></script>
+ <script type="text/javascript" src="../../lib/d3/d3.geo.js"></script>
+ <style type="text/css">
+
+body {
+ font: 10px sans-serif;
+}
+
+#container {
+ width: 960px;
+ height: 500px;
+ overflow: hidden;
+}
+
+ </style>
+ </head>
+ <body>
+ <div id="container">
+ <canvas id="map"></canvas>
+ </div>
+ <script type="text/javascript">
+
+var canvas = d3.select("#map"),
+ context = canvas.node().getContext("2d");
+
+var w = 960,
+ h = 500,
+ lon = -122.41948,
+ lat = 37.76487;
+
+var project = d3.geo.mercator()
+ .scale(1)
+ .translate([.5, .5]);
+
+var view = pixymaps.view()
+ .size([w, h])
+ .center(project([lon, lat]))
+ .zoom(12);
+
+var image = pixymaps.image()
+ .view(view)
+ .url(pixymaps.url("http://{S}tile.cloudmade.com"
+ + "/1a1b06b230af4efdbb989ea99e9841af" // http://cloudmade.com/register
+ + "/999/256/{Z}/{X}/{Y}.png")
+ .hosts(["a.", "b.", "c.", ""]))
+ .render(canvas.node());
+
+var speed = 0,
+ acceleration = -.05;
+
+d3.timer(function() {
+ speed = Math.max(-5, speed + acceleration);
+ view.panBy([speed, 0]);
+ image.render(canvas.node());
+});
+
+ </script>
+ <div 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>.
+ </div>
+ </body>
+</html>
View
@@ -89,8 +89,9 @@ pixymaps.image = function() {
return image;
};
- image.render = function(context, callback) {
- var viewSize = view.size(),
+ image.render = function(canvas, callback) {
+ var context = canvas.getContext("2d"),
+ viewSize = view.size(),
viewAngle = view.angle(),
viewCenter = view.center(),
viewZoom = viewCenter[2],
@@ -119,42 +120,33 @@ pixymaps.image = function() {
dx = coordinateSize[0],
dy = coordinateSize[1];
- // allocate an offscreen buffer to draw tiles
- var offcanvas = document.createElement("canvas"),
- offcontext = offcanvas.getContext("2d");
-
- // disable offscreen antialiasing; that happens at the end
- offcontext.antialias = "none";
- offcanvas.width = (x1 - x0) * dx;
- offcanvas.height = (y1 - y0) * dy;
-
// compute the set of visible tiles using scan conversion
var tiles = [], z = c0[2], remaining = 0;
scanTriangle(c0, c1, c2, push);
scanTriangle(c2, c3, c0, push);
function push(x, y) { remaining = tiles.push([x, y, z]); }
+ // set the canvas size and transform
+ var tx = viewSize[0] / 2 + dx * (x0 - viewCenter[0] * kz) | 0,
+ ty = viewSize[1] / 2 + dy * (y0 - viewCenter[1] * kz) | 0;
+ canvas.style.webkitTransform = "matrix3d(1,0,0,0,0,1,0,0,0,0,1,0," + tx + "," + ty + ",0,1)";
+ canvas.width = (x1 - x0) * dx;
+ canvas.height = (y1 - y0) * dy;
+
// load each tile (hopefully from the cache) and draw it to the canvas
tiles.forEach(function(tile) {
var key = url(tile);
// If there's something to show for this tile, show it.
return key == null ? done() : pixymaps_cache(key, function(image) {
- offcontext.drawImage(image, dx * (tile[0] - x0), dy * (tile[1] - y0));
+ context.drawImage(image, dx * (tile[0] - x0), dy * (tile[1] - y0));
done();
});
- // if that was the last tile, draw onscreen and callback!
+ // if that was the last tile, callback!
function done() {
- if (!--remaining) {
- context.save();
- context.translate(viewSize[0] / 2, viewSize[1] / 2);
- context.rotate(viewAngle);
- context.scale(1 / kz, 1 / kz);
- context.drawImage(offcanvas, dx * (x0 - viewCenter[0] * kz) | 0, dy * (y0 - viewCenter[1] * kz) | 0);
- context.restore();
-
- if (callback) callback();
+ if (!--remaining && callback) {
+ callback();
}
}
});
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View
@@ -22,8 +22,9 @@ pixymaps.image = function() {
return image;
};
- image.render = function(context, callback) {
- var viewSize = view.size(),
+ image.render = function(canvas, callback) {
+ var context = canvas.getContext("2d"),
+ viewSize = view.size(),
viewAngle = view.angle(),
viewCenter = view.center(),
viewZoom = viewCenter[2],
@@ -52,42 +53,33 @@ pixymaps.image = function() {
dx = coordinateSize[0],
dy = coordinateSize[1];
- // allocate an offscreen buffer to draw tiles
- var offcanvas = document.createElement("canvas"),
- offcontext = offcanvas.getContext("2d");
-
- // disable offscreen antialiasing; that happens at the end
- offcontext.antialias = "none";
- offcanvas.width = (x1 - x0) * dx;
- offcanvas.height = (y1 - y0) * dy;
-
// compute the set of visible tiles using scan conversion
var tiles = [], z = c0[2], remaining = 0;
scanTriangle(c0, c1, c2, push);
scanTriangle(c2, c3, c0, push);
function push(x, y) { remaining = tiles.push([x, y, z]); }
+ // set the canvas size and transform
+ var tx = viewSize[0] / 2 + dx * (x0 - viewCenter[0] * kz) | 0,
+ ty = viewSize[1] / 2 + dy * (y0 - viewCenter[1] * kz) | 0;
+ canvas.style.webkitTransform = "matrix3d(1,0,0,0,0,1,0,0,0,0,1,0," + tx + "," + ty + ",0,1)";
+ canvas.width = (x1 - x0) * dx;
+ canvas.height = (y1 - y0) * dy;
+
// load each tile (hopefully from the cache) and draw it to the canvas
tiles.forEach(function(tile) {
var key = url(tile);
// If there's something to show for this tile, show it.
return key == null ? done() : pixymaps_cache(key, function(image) {
- offcontext.drawImage(image, dx * (tile[0] - x0), dy * (tile[1] - y0));
+ context.drawImage(image, dx * (tile[0] - x0), dy * (tile[1] - y0));
done();
});
- // if that was the last tile, draw onscreen and callback!
+ // if that was the last tile, callback!
function done() {
- if (!--remaining) {
- context.save();
- context.translate(viewSize[0] / 2, viewSize[1] / 2);
- context.rotate(viewAngle);
- context.scale(1 / kz, 1 / kz);
- context.drawImage(offcanvas, dx * (x0 - viewCenter[0] * kz) | 0, dy * (y0 - viewCenter[1] * kz) | 0);
- context.restore();
-
- if (callback) callback();
+ if (!--remaining && callback) {
+ callback();
}
}
});

0 comments on commit e0224e8

Please sign in to comment.