当我动态添加一个使用 JS 制作动画的项目时,如何让它们在同一时间线上同步,如下所示:?我看到一个教程,展示了使用 JS 动画与 CSS 相比的好处是它们继承了相同的时间轴。
<div class="body"></div>
<button onclick="addItem()">Add</button>
function addItem() {
let body = document.querySelector('.body');
let newEl = document.createElement('div');
newEl.innerText = "I am a new Item";
newEl.animate([
{
transform: 'translate(0px, 0px)',
transform: 'translate(500px, 500px)',
}
],
{
duration: 2000,
iterations: Infinity,
});
body.appendChild(newEl);
}
如果你所有的动画片对象确实共享相同的duration如果您希望它们同时开始和结束,您只需设置iterationStart新的效果时间动画片反对计算时序 .progress
已运行的值。
但是请注意,您必须等待新的动画对象准备好,然后才能获取前一个动画对象的计算值,否则您将晚一帧。为此,您只需等待animation.ready承诺。
要获取之前的Animation对象,您可以通过以下方式在创建时存储它Element.animate(),或者您可以通过以下方式访问文档上当前正在运行的动画集document.getAnimations(),然后从那里选择它。
let i = 0;
async function addItem() {
i++;
const body = document.querySelector(".body");
const newEl = document.createElement("div");
newEl.classList.add("item");
newEl.textContent = "I am a new Item " + i;
// get a previous Animation if any
const previous_animation = document.getAnimations()[0];
// create the new Animation object
// slightly offset on the x axis only
// to check if they are indeed in sync
const anim = newEl.animate([{
transform: "translate(" + (i * 10) + "px, 0px)",
transform: "translate(" + (i * 10 + 250) + "px, 250px)",
}], {
duration: 2000,
iterations: Infinity
});
// when it's ready to start
await anim.ready;
// get the current progress of the first Animation object
const computed_timing = previous_animation?.effect.getComputedTiming();
if( computed_timing ) {
// update our new Animation object to the same progress value
anim.effect.updateTiming( {
iterationStart: computed_timing.progress
});
}
body.appendChild(newEl);
}
.item {
position: absolute;
}
<div class="body"></div>
<button onclick="addItem()">Add</button>
请注意,正如用户指出的布赖恩舍尔德 in a 下面评论, the startTime财产动画的时间可以设置为更早的时间。这样做会让它像动画一样did从这个时候开始。
因此,为了同步两个动画,这可能是最好的方法:
let i = 0;
function addItem() {
i++;
const body = document.querySelector(".body");
const newEl = document.createElement("div");
newEl.classList.add("item");
newEl.textContent = "I am a new Item " + i;
// get a previous Animation if any
const previous_animation = document.getAnimations()[0];
// create the new Animation object
// slightly offset on the x axis only
// to check if they are indeed in sync
const anim = newEl.animate([{
transform: "translate(" + (i * 10) + "px, 0px)",
transform: "translate(" + (i * 10 + 250) + "px, 250px)",
}], {
duration: 2000,
iterations: Infinity
});
if( previous_animation ) {
// set the startTime to the same
// as the previously running's one
// note this also forces anim.ready to resolve directly
anim.startTime = previous_animation.startTime;
}
body.appendChild(newEl);
}
.item {
position: absolute;
}
<div class="body"></div>
<button onclick="addItem()">Add</button>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)