How to change speed of translate and scale when zooming in and out in D3 (using zoom.on & d3.event.translate, d3.event.zoom)?
d3.js, javascript, zooming
Solution
You need adjust the scale inside the function with a mathematical function when you select the function the important is that for x=0 the y=0 you can use pow is easier in this case `Math.pow(d3.event.scale,.1)` the second parameter does the zoom more slowly when is smaller.
It´s not a good idea use a very complicated function because the browser will turn slow.
When you have the new scale, you need recalculate the translation. You don´t complicate the problem, in SVG you have the actual height with `this.getBBox().height` this ok, but it is not exactly because you are one iteration behind. You could calculate the new height with `(originalHeight * scale)` and the translate with `(originalHeight - (originalHeight * scale))/2`
Well origialHeight*scale is the newHeight
The originalHeight - newHeight is the difference, and you want the center, you need divide for 2, the half part of the square and the half part below.
Now we need do the action with the width. It is the same
The code:
var svg = d3.select("body").append("svg:svg")
.attr("width", 1000)
.attr("height", 2000)
.append("svg:g")
.call(d3.behavior.zoom().on("zoom", redraw))
.append("svg:g");
svg.append("svg:rect")
.attr("width", 200)
.attr("height", 300)
.attr("fill", 'green');
function redraw() {
var velocity = 1/10;
var scale = Math.pow(d3.event.scale,velocity);
var translateY = (300 - (300 * scale))/2;
var translateX = (200 - (200 * scale))/2;
svg.attr("transform", "translate(" + [translateX,translateY] + ")" + " scale(" +scale+ ")");
};
Note that I put the 200 and 300 hardcoded, you can use a property, use constant...
I created a fiddler: http://jsfiddle.net/t0j5b3e2/
Problem
Can you adjust the speed of the zoom when the user scrolls in and out using the mousewheel? My understanding is that the zoom.on (https://github.com/mbostock/d3/wiki/Zoom-Behavior#wiki-on) listener produces the two events d3.event.translate & d3.event.zoom, which contain matrices or coordinates that when passed to the translate or scale functions, allow panning and rescaling of the graphic. But how do I speed this up, so that if the user moves his mousewheel by a little, she rapidly zooms in or out? I have a large visualization that I want to allow users to zoom in and out of rapidly with the mousewheel. Can I simply modify/add arguments to the above existing events and functions or do I have to create my own? I have a feeling some of the above is inaccurate/patchy in terms of understanding, so please explain if so. Very simple jsfiddle example here: http://jsfiddle.net/fiddler86/6jJe6/, with identical code below: ``` var svg = d3.select("body").append("svg:svg") .attr("width", 1000) .attr("height", 2000) .append("svg:g") .call(d3.behavior.zoom().on("zoom", redraw)) .append("svg:g"); svg.append("svg:rect") .attr("width", 200) .attr("height", 300) .attr("fill", 'green'); function redraw() { svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")"); }; ```