我正在尝试按顺序运行动画。这是一个例子。
function rect1() {
d3.select("svg")
.append("rect")
.attr("id", "r1")
.attr("x", 300)
.attr("y", 100)
.attr("height", 0)
.attr("width", 0)
.transition()
.duration(1000)
.attr("height", 30)
.attr("width", 50);
}
function rect2() {
d3.select("svg")
.append("rect")
.attr("id", "r2")
.attr("x", 300)
.attr("y", 50)
.attr("height", 0)
.attr("width", 0)
.transition()
.duration(1000)
.attr("height", 30)
.attr("width", 50);
}
function highlightRect(id) {
d3.select(id)
.style("fill", "yellow")
}
所以我想创建一个这样的函数,以便可以依次rect1()
,rect2()
,highlightRect()
(在每个动画结束之后)运行它们。
function startAnim (f1, f2, f3, f3a) {
f1();
f2();
f3(f3a);
}
startAnim(rect1, rect2, highlightRect, "#r1");
我已经尝试过类似的操作,但是当有更多动画时,它会变得混乱。
// rect1
d3.select("svg")
.append("rect")
.attr("id", "r1")
.attr("x", 300)
.attr("y", 100)
.attr("height", 0)
.attr("width", 0)
.transition()
.duration(1000)
.attr("height", 30)
.attr("width", 50)
.on("end", () => {
// rect2
d3.select("svg")
.append("rect")
.attr("id", "r2")
.attr("x", 300)
.attr("y", 50)
.attr("height", 0)
.attr("width", 0)
.transition()
.duration(1000)
.attr("height", 30)
.attr("width", 50)
.on("end", ....);
});;
这可能是一个无知的问题,可以用诺言来做到吗?
谢谢
答案 0 :(得分:-1)
您可能不需要Promises,因为您似乎想在开始下一个动画之前等待每个动画完成,因此这不是异步操作。我很难测试一下,但是我认为您可以将每个连续的函数作为上一个函数的参数来传递。看起来像这样:
function rect1(next) {
d3.select("svg")
.append("rect")
.attr("id", "r1")
.attr("x", 300)
.attr("y", 100)
.attr("height", 0)
.attr("width", 0)
.transition()
.duration(1000)
.attr("height", 30)
.attr("width", 50);
next();
}
function rect2(next) {
d3.select("svg")
.append("rect")
.attr("id", "r2")
.attr("x", 300)
.attr("y", 50)
.attr("height", 0)
.attr("width", 0)
.transition()
.duration(1000)
.attr("height", 30)
.attr("width", 50);
next();
}
function highlightRect(id, next) {
d3.select(id)
.style("fill", "yellow")
next();
}
然后...
function startAnim(f1, f2, f3, f3a) {
f1(f2(f3(f3a)));
startAnim(rect1, rect2, highlightRect, '#r1');
坦率地说,我不确定这是否适合您的情况,但值得尝试。
答案 1 :(得分:-1)
对这些进行承诺实际上很容易:
首先,我们将使函数返回要链接的对象。
function rect1() {
return d3.select("svg")
.append("rect")
.attr("id", "r1")
.attr("x", 300)
.attr("y", 100)
.attr("height", 0)
.attr("width", 0)
.transition()
.duration(1000)
.attr("height", 30)
.attr("width", 50);
}
function rect2() {
return d3.select("svg")
.append("rect")
.attr("id", "r2")
.attr("x", 300)
.attr("y", 50)
.attr("height", 0)
.attr("width", 0)
.transition()
.duration(1000)
.attr("height", 30)
.attr("width", 50);
}
function highlightRect(id) {
return d3.select(id)
.style("fill", "yellow")
}
然后,我们可以使用通用的高阶函数为我们分配那些函数。
// Returns a promise that resolves after the given
// animation function finishes. Can optionally take args as a second parameter
// obviously this could just take a function and allow consumers
// to use anonymous functions for parameter-binding, but this function
// relies on the return value, so this is, maybe, slightly less easy to
// break on accident.
function runAnimation(fn, ...args) {
return new Promise(resolve => fn(...args).on("end", resolve));
}
然后将它们链接起来非常简单:
runAnimation(rect1)
.then(() => runAnimation(rect2))
.then(() => runAnimation(highlightRect, "#r1"))
在这里创建一个需要一系列功能的助手也很容易。
未经测试,但我认为总体思路可以解决。