了解为什么在 .attrTween 中使用三个嵌套函数



Mike Bostock的这个例子对我来说非常有用。它显示了沿曲线闭合路径无休止地流动的点。代码非常简单,除了我不明白的最后一行。我在下面写相关代码:

transition();
function transition() {
circle.transition()
.duration(10000)
.attrTween("transform", translateAlong(path.node()))
.each("end", transition);
}
// Returns an attrTween for translating along the specified path element.
function translateAlong(path) {
var l = path.getTotalLength();
return function(d, i, a) {
return function(t) {
var p = path.getPointAtLength(t * l);
return "translate(" + p.x + "," + p.y + ")";
};
};
}

为什么有三个嵌套函数?我知道外部函数translateAlong应该返回t(时间(的函数,但我不明白中间function(d, i, a)的作用。我只测试了它不能省略,但它的参数可以。

我们有3个函数。让我们命名它们的级别:

function translateAlong(path) {//1st level here
var l = path.getTotalLength();
return function(d, i, a) {//2nd level here
return function(t) {//3rd and last level
var p = path.getPointAtLength(t * l);
return "translate(" + p.x + "," + p.y + ")";
};
};
}

为了回答您的问题,了解这一点非常重要...

.attrTween("transform", translateAlong(path.node()))

。将立即调用translateAlong并获取其返回值。这是:

function(d, i, a) {//2nd level here
return function(t) {//3rd and last level
var p = path.getPointAtLength(t * l);
return "translate(" + p.x + "," + p.y + ")";
};
};

现在,让我们转到 D3 v3 API(链接中的版本(。它说:

transition.attrTween(name, tween(

根据指定的补间函数转换具有指定名称的属性的值。过渡的起始值和结束值由补间确定;补间函数在每个元素上开始过渡时被调用,传递当前基准 D、当前索引 i 和当前属性值 A,并将 this 上下文作为当前 DOM 元素。(强调我的(

正如你从我加粗的部分的参数名称中看到的(即使 Bostock 从不使用它们,这解释了你的正确观察"它的参数可以 [被省略]">(,补间函数正是你要问的函数:

return function(d, i, a) {//this is the tween
return function(t) {
var p = path.getPointAtLength(t * l);
return "translate(" + p.x + "," + p.y + ")";
};
};

值得一提的是,考虑到 JavaScript 闭包的工作原理,补间函数可以访问变量l(var l = path.getTotalLength();(。

最新更新