Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
491 views
in Technique[技术] by (71.8m points)

javascript - How to change speed of translate and scale when zooming in and out in D3 (using zoom.on & d3.event.translate, d3.event.zoom)?

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 + ")");
};     
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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/


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...