Tyler Graf Tyler Graf - 3 months ago 34
Javascript Question

d3 pan/zoom with DOM center point is off

I'm trying to zoom and pan using d3.

I took an example from here and switched out the svg for regular dom.


var section = d3.select("section"),
width = +section.attr("width"),
height = +section.attr("height");

var points = d3.range(2000).map(phyllotaxis(10));

var div = section.append("div");

.attr("style", function(d) { return 'left: '+d[0]+'px; top: '+d[1]+'px;' })

.scaleExtent([1 / 2, 4])
.on("zoom", zoomed));

function zoomed() {
div.attr("style", `transform: translate(${d3.event.transform.x}px, ${d3.event.transform.y}px) scale(${d3.event.transform.k})`);
div.attr("transform", d3.event.transform);

function phyllotaxis(radius) {
var theta = Math.PI * (3 - Math.sqrt(5));
return function(i) {
var r = radius * Math.sqrt(i), a = theta * i;
return [
960 / 2 + r * Math.cos(a),
500 / 2 + r * Math.sin(a)

Here's a codepen showing the issue.

Notice that pan works great, but the zoom center point is off. It should zoom in centered on wherever your mouse is.


Assuming you really needed that <div>s and <p>s instead of <g>s and <circle>s;

Your translate coefficients are a bit off.

Changing your

function zoomed() {
  g.attr("style", `transform: translate(${d3.event.transform.x}px, ${d3.event.transform.y}px) scale(${d3.event.transform.k})`);
  g.attr("transform", d3.event.transform);


function zoomed() {
  g.attr("style", `transform: translate(${d3.event.transform.x-480}px, ${d3.event.transform.y}px) scale(${d3.event.transform.k})`);
  g.attr("transform", d3.event.transform);

will "solve" your issue I think.

Here's the updated codepen: http://codepen.io/anon/pen/bBoPVx