You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rive中实现输入值变化时从当前帧播放动画N秒?

解决输入触发动画从当前帧平滑播放N秒的问题

核心思路

别再用scrub的跳帧逻辑了,换成时间驱动的平滑播放控制——输入变化时记好当前时间,算好要播到什么时候,跟着浏览器刷新帧一步步推进动画,直到凑够N秒,这样就不会卡顿。

具体操作步骤

  • 给输入控件绑input事件(要实时响应就用这个,要是只需要输入完再触发就用change)
  • 事件触发时,先把之前的播放循环清掉,避免冲突
  • 记录当前的精确时间戳,再算出播放结束的时间戳(当前时间 + N*1000)
  • 启动requestAnimationFrame循环:
    1. 每帧算一下已经播了多久
    2. 没到N秒的话,就按已播时长算出动画该走到哪个进度,平滑更新
    3. 到点了就停掉循环,暂停动画

示例代码(Web Animations API版)

// 假设你已经有了动画实例和输入控件
const targetAnim = document.getElementById('animated-element').animate(
  [{ transform: 'scale(1)' }, { transform: 'scale(1.5)' }],
  { duration: 3000, iterations: Infinity, paused: true }
);
const inputCtrl = document.getElementById('value-input');

let playId = null;
const playSeconds = 2; // 这里设置你要的N秒

inputCtrl.addEventListener('input', () => {
  // 先终止之前的播放
  if (playId) cancelAnimationFrame(playId);
  
  const start = performance.now();
  const end = start + playSeconds * 1000;

  const runPlay = () => {
    const now = performance.now();
    const elapsed = now - start;

    if (elapsed < playSeconds * 1000) {
      // 按已流逝时间更新动画进度,不是跳帧
      targetAnim.currentTime += (elapsed / 1000) * targetAnim.effect.getTiming().duration;
      playId = requestAnimationFrame(runPlay);
    } else {
      targetAnim.pause();
    }
  };

  runPlay();
});

避坑提示

  • 用performance.now()比Date.now()精度高,时间计算更准,减少跳帧概率
  • 每次输入都要清掉之前的循环,不然多个循环叠在一起会乱
  • 别直接设置currentTime跳帧,而是基于时间差累加,保证每帧的平滑过渡

内容的提问来源于stack exchange,提问作者elVengador

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 05:30:45