简体   繁体   English

D3 Geo Azimuthal上的动画圆形剪辑

[英]Animating circle clip on D3 Geo Azimuthal

I'm messing around with a version of d3.geo.azimuthal as seen here: http://mbostock.github.io/d3/talk/20111018/azimuthal.html 我在弄乱d3.geo.azimuthal的版本,如下所示: http ://mbostock.github.io/d3/talk/20111018/azimuthal.html

I have a list of links that navigate to particular continents. 我有一个导航到特定大洲的链接列表。 These each call a custom function navigateGlobe with info on where to move to. 它们每个都调用一个自定义函数NavigationGlobe,其中包含要移动到的位置的信息。

function navigateGlobe(orig, scal) {
    projection.origin(orig);
    projection.scale(scal);
    refresh(1500);
}

The refresh function is the same as in the source example, and looks like this: 刷新功能与源示例中的相同,如下所示:

function refresh(duration) {
    (duration ? feature.transition().duration(duration) : feature).attr("d", clip);
}

On running navigateGlobe, it works correctly and the projection smoothly transitions to the required location and scale, however the clipping circle would not be updated until the next move of the globe by the mouse. 在运行navigationGlobe时,它可以正常工作,并且投影会平滑过渡到所需的位置和比例,但是,直到鼠标下一次移动地球时,裁剪圆才会更新。 I know that the clipping is done by the circle, to hide countries on the side of the globe facing away from the user, so I altered my function: 我知道剪裁是通过圆圈完成的,以隐藏地球远离用户的一面的国家,因此我更改了功能:

function navigateGlobe(orig, scal) {
    projection.origin(orig);
    projection.scale(scal);
    circle.origin(orig); // Need to animate this!
    refresh(1500);
}

The clipping circle now updates but does so immediately, ie the destination clipping point is reached on step 1 of animation. 剪切圆现在会更新,但会立即更新,即在动画的步骤1上达到了目标剪切点。 I would like to know if there's a way of transitioning the clipping circle at the same rate as the projection so that the entire animation looks smooth. 我想知道是否有一种以与投影相同的速率过渡剪切圆的方法,以使整个动画看起来很平滑。

For reference, again as in the source example, var circle is set up as: 作为参考,再次如源示例中所示,将var circle设置为:

var circle = d3.geo.greatCircle()
    .origin(projection.origin());

I will try to set up a fiddle as an example of what is going wrong. 我将尝试设置一个小提琴,以作为发生问题的示例。 Thanks! 谢谢!

Unfortunately, this is an example where D3's transitions fall a bit short -- you can't really transition just values. 不幸的是,这是一个示例,其中D3的转换有些短-您不能真正转换仅值。 You can set up your own easing function, but you'll need to call it manually with the right values. 您可以设置自己的缓动函数,但需要使用正确的值手动调用它。

To do this, you would set up an interpolation function between the old and new origins. 为此,您需要在新旧原点之间设置插值功能 Then, you would call navigateGlobe with intermediate origins recursively with setTimeout in the following fashion. 然后,你会打电话navigateGlobe与中间起源递归地setTimeout下面的方式。

var interpolator = d3.interpolate(...);
var iters = 10;
function setNewOrigin(count) {
    setTimeout(function() {
        navigateGlobe(interpolator(count/iters));
        if(count < iters) setNewOrigin(count + 1);
    }, 10);
}
setNewOrigin(1);

The duration of this transition is determined by the number of iterations (here 10) and the timeout value for the recursive call (here 10ms, ie total 100ms). 此过渡的持续时间由迭代次数(此处为10)和递归调用的超时值(此处为10ms,即总计100ms)确定。 The total would need to be the same as for your other transition. 总数必须与您的其他过渡相同。

this actually works, based on all what's been suggested, using requestAnimationFrame 实际上,根据所有建议,使用requestAnimationFrame

    var o = projection.origin();

    var si = d3.interpolate(projection.scale(), SCALE);
    var xi = d3.interpolate(o[0], -58.4459789 +10);
    var yi = d3.interpolate(o[1], -34.612869   -4); // buenos aires -4°

    function xanimate (fn, time) {
        var start = null;

        function step(timestamp) {
            var progress;
            if (start === null) start = timestamp;
            progress = timestamp - start;
            var p = progress / time;
            fn (p);
            if (progress < time) {
                requestAnimationFrame(step);
            }
        }

        requestAnimationFrame(step);
    }

    function navigateGlobe(orig, scal) {
        projection.origin(orig);
        projection.scale(scal);
        circle.origin(orig); // Need to animate this!
        refresh();
    }

    xanimate (function (t) {
        navigateGlobe ([xi(t), yi(t)], si(t));
    }, 2000);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM