簡體   English   中英

D3 Geo Azimuthal上的動畫圓形剪輯

[英]Animating circle clip on D3 Geo Azimuthal

我在弄亂d3.geo.azimuthal的版本,如下所示: http ://mbostock.github.io/d3/talk/20111018/azimuthal.html

我有一個導航到特定大洲的鏈接列表。 它們每個都調用一個自定義函數NavigationGlobe,其中包含要移動到的位置的信息。

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

刷新功能與源示例中的相同,如下所示:

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

在運行navigationGlobe時,它可以正常工作,並且投影會平滑過渡到所需的位置和比例,但是,直到鼠標下一次移動地球時,裁剪圓才會更新。 我知道剪裁是通過圓圈完成的,以隱藏地球遠離用戶的一面的國家,因此我更改了功能:

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

剪切圓現在會更新,但會立即更新,即在動畫的步驟1上達到了目標剪切點。 我想知道是否有一種以與投影相同的速率過渡剪切圓的方法,以使整個動畫看起來很平滑。

作為參考,再次如源示例中所示,將var circle設置為:

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

我將嘗試設置一個小提琴,以作為發生問題的示例。 謝謝!

不幸的是,這是一個示例,其中D3的轉換有些短-您不能真正轉換僅值。 您可以設置自己的緩動函數,但需要使用正確的值手動調用它。

為此,您需要在新舊原點之間設置插值功能 然后,你會打電話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);

此過渡的持續時間由迭代次數(此處為10)和遞歸調用的超時值(此處為10ms,即總計100ms)確定。 總數必須與您的其他過渡相同。

實際上,根據所有建議,使用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