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/
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…