JS:如何同步多个动画的时序?

2023-12-04

当我动态添加一个使用 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(使用前将#替换为@)

JS:如何同步多个动画的时序? 的相关文章

  • $_POST 返回空

    尝试练习一下 ajax 和 PHP 我不明白为什么每当我发送一些东西时 它都会返回空或未定义的索引 PHP 返回空 JS form submit function var meth this attr action var msg msg
  • 这段代码有什么问题。如果用户选择或不选择复选框,为什么它仍然显示 MsgBox? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 无论我是否选择复选框 它仍然会给出
  • Jquery文件上传插件进度条

    这个插件 https github com blueimp jQuery File Upload wiki管理网页中的文件上传 并且可以在上传过程中添加很多 UI 元素 您创建一个输入文件类型元素 然后绑定 js 文件 使用实例化代码和 w
  • 共享工作线程在重新加载页面时终止

    为什么 Shared Worker 在重新加载页面时死掉了 应该是复活了我该如何解决这个问题 重新加载前 重新加载后 在 example com 上按 F5 家长工人 var port new SharedWorker app worker
  • 将 Json 数据返回给 Ajax 调用

    我在 MVC 中有一个方法 我将其发布到它 并且我需要返回一些数据以进行处理 这是我发布到的 MVC 方法 返回值是 json 数据 HttpPost public JsonResult GetCalculateAmortizationSc
  • 如何精确缩放已翻译的d3地图

    我有一张已翻译的地图 以使其正确适合画布 我正在尝试实现一种缩放它的方法 它确实有效 但是当您放大时它会远离中心 而不是以鼠标甚至画布为中心 这是我的代码 function map data total views var xy d3 ge
  • 如何在单页应用程序中使用 #-URL?

    本文 http danwebb net 2011 5 28 it is about the hashbangs提出了一个非常令人信服的论点 因为 URL 是长期存在的 它们被添加书签并传递 所以它们应该是有意义的 并且使用哈希进行真正的路由
  • Cordova SQLite 保存 BLOB

    我的 Cordova SQLite 插件有问题 如何将 BLOB 图像保存到 SQLite 我在 JS 中有 BLOB 对象 Blob size 96874 type image jpeg proto Blob length 1 我试图拯救
  • 刷新页面后保留输入值

    我有一个带有输入字段的表单 该输入包含一个下拉菜单 从数据库中读取信息 如果用户输入值 并且当他到达下拉菜单时 他没有找到他想要的内容 他会转到另一个页面将此信息添加到下拉菜单 然后转到第一页继续输入信息 如果他转到另一个页面向下拉菜单添加
  • Javascript - 使数组索引 toLowerCase() 不起作用

    我试图将所有数组索引设置为小写字符串 但它不起作用 我在这里查看了其他答案并尝试了他们的解决方案 例如使用toString 添加之前toLowerCase但它不起作用 这很奇怪 我创建了一个问题的jsfiddlehere https jsf
  • 我可以用一个简单的函数制作一个迭代器吗? (没有生成器或 Symbol.iterator)

    我一直在尝试使用普通函数创建一个迭代器 而不使用生成器或使用Symbol iterator用于学术目的的协议 为此 我创建了一个函数 它返回一个带有next参数 但尝试将其作为iterable的论证for of循环会产生不需要的结果 这是到
  • 如何将节点 sqlite3 与 q (promise) 一起使用

    我正在尝试将 Promise 与 sqlite3 一起使用 这是我的源代码的一部分 this deleteTag function tag project var db this db if project return q nfcall
  • “move(-1)”作为 AngularJS 表达式有什么问题吗?

    我收到此错误 parse ueoe Unexpected end of expression move 从这段代码来看
  • Jquery 子元素发生变化

    我正在尝试使用 jquery 在子元素 在本例中为 select 更改时触发事件 这是我的 HTML div class row addForm div class col lg 2 col md 2 col sm 3 col xs 6 d
  • 如何在使用类型分散时将箭头添加到行尾

    如何在 y 不等于 0 且系列类型以线宽 2 分散的情况下正确地将箭头添加到行的每一端 在这里我可以看到箭头已添加但未正确添加 请看这个 部分工作小提琴 http jsfiddle net vnYCX 这是我的 JS 最初的原型是由 sta
  • Ajax 函数在重定向后不保存滚动位置

    正如标题所述 我编写了一个 ajax 函数 该函数应该滚动到用户在重定向之前所在的位置 我写了一个alert对于测试场景 它确实触发了 但滚动不断回到顶部 我在这里做错了什么 JavaScript ajax type GET url Adm
  • 如何获取从 Express (Node.js) 中的表单传递的数据

    我想获取使用表单从页面传递的数据 并在重定向的页面中使用该数据 我的客户端有这个表格
  • Dojo“正在加载”消息

    我是 Dojo 新手 所以我需要一些帮助 我的一些链接需要一段时间 当用户单击时 页面开始加载需要几秒钟 我想添加一条 正在加载 消息 我可以用 旧时尚方式 来做 但我想学习新的 更简单 更智能的 Dojo 方式 具体如何工作现在并不重要
  • 如何更改数据表中标题单元格的内容?

    我正在使用数据表 http datatables net plugin 在我的可排序列上 我想用按钮替换列文本 但是这样做 oSettings aoColumns i nTh text 我可以检索相应列的文本 但是 oSettings ao
  • 使用 javascript 从亚马逊 URL 中抓取 ASIN

    假设我有一个像这样的亚马逊产品 URL http www amazon com Kindle Wireless Reading Display Generation dp B0015T963C ref amb link 86123711 2

随机推荐