Flavio
Flavio

Reputation: 1587

How to apply d3.zoom() to a HTML element

I can't figure out how to properly apply the d3.zoom behaviour to an HTML element (not SVG). In the documentation the only advice on how to do this is this:

Similarly, to apply the transformation to HTML elements via CSS:

div.style("transform", "translate(" + transform.x + "px," + transform.y + "px) scale(" + transform.k + ")");

So what I did was this: ("Working" example)

var zoom = d3.zoom()
  .scaleExtent([0.1, 1])
  .on('zoom', zoomed);

var root = d3.select('.root').call(zoom);

function zoomed() {
  var transform = d3.event.transform;
  root.style("transform", "translate(" + transform.x + "px," + transform.y + "px) scale(" + transform.k + ")");
}

The problem here is that, if you zoom out, the zoom will eventually stop because the mouse is not inside the zoomable area anymore.

So what I did was using a parent element to attach the zoom behaviour and a child element that gets transformed. Here's an example of that. The problem now is that the transforms are messed up. I cannot fully comprehend what exactly is messed up and why but if I zoom with the mouse wheel, the transformed canvas is definitely not doing what it should (moving away from the mouse instead of towards it when zooming in etc.).

Unfortunately I couldn't find any example of how to use d3.zoom with HTML. Is there a better way to do this? Or can I somehow fix the transform when using a child element?

Upvotes: 2

Views: 2661

Answers (2)

Leaf the Legend
Leaf the Legend

Reputation: 481

Set the transform origin to 0,0:

root.style("transform", "translate(" + transform.x + "px," + transform.y + "px) scale(" + transform.k + ")").style("transform-origin","0 0");

Upvotes: 1

davcs86
davcs86

Reputation: 3935

Only change the scale value,

canvas.style("transform", "translate(0,0) scale(" + transform.k + ")");

Working demo

Upvotes: 1

Related Questions