首页 > 解决方案 > 有什么方法可以在不重新启动动画的情况下通过 element.animate 更新动画集的持续时间?

问题描述

我正在用 HTML5 开发游戏引擎。字符是使用动画精灵作为背景的 div 元素。由于精灵动画具有可变参数并且必须由代码设置,它们不能在静态 CSS 定义中预定义,因此我使用element.animate知道我的比例和帧数的给定速度将精灵动画设置到给定行。

// Applies the given frame and animation to the sprite
// Frame is an angle, clockwise direction: 0 = up, 1 = right, 2 = down, 3 = left
set_animation(frame, duration) {
    const scale_x = this.settings.sprite.scale_x * this.settings.sprite.frames_x;
    const pos_y = this.settings.sprite.scale_y * -frame;

    // Cancel the existing animation
    if(this.data_actors_self.anim) {
        this.data_actors_self.anim.cancel();
        this.data_actors_self.anim = null;
    }

    // Play the animation for this row or show the first frame if static
    if(duration > 0) {
        this.data_actors_self.anim = this.element.animate([
            {
                backgroundPosition: px([0, pos_y])
            }, {
                backgroundPosition: px([scale_x, pos_y])
            }
        ], {
            duration: duration * 1000,
            direction: "normal",
            easing: "steps(" + this.settings.sprite.frames_x + ")",
            iterations: Infinity
        });
        this.data_actors_self.anim.play();
    } else {
        this.element.style.backgroundPosition = px([0, pos_y]);
    }
}

显然,这是一个演员类函数的片段:this.element是 div,this.settings是一个带有要使用的参数的对象,在这种情况下谁的名字应该有意义,该px()函数是一个简单的转换器,用于将数组转换为 HTML 的像素字符串(例如:[0, 0]to "0px 0px") .

我遇到的问题:虽然我总是可以运行此函数来设置新动画,但我希望能够在不重置动画的情况下更改动画的速度。它不需要是一个平滑的过渡,因为我关心的是新速度可以在下一次迭代中应用......我只想避免在应用更改时出现视觉快照或任何类型的重置。设置动画后,我不知道如何访问和更新其duration参数。有没有人有什么建议?

在使用console.log时,this.data.anim我被正确地告知它是一个动画对象。我尝试使用JSON.stringify来获取更多信息,但没有打印任何相关信息。this.data.anim.duration返回undefined,因此设置必须存储在其他属性下。即使我知道该属性,我也想确保网络浏览器会同意我将其更改为this.data.anim.options.duration = new_duration.

标签: javascripthtmlcssgame-engine

解决方案


如果需要,您可以在更改动画持续时间之前等待迭代结束。

此代码段仅在您单击按钮以提高速度时为动画迭代事件设置事件侦听器。

function upthespeed() {
  const div = document.querySelector('div');
  div.addEventListener('animationiteration', function() {
    div.style.animationDuration = '1s';
  });
  document.querySelector('button').style.display = 'none';
}
div {
  width: 10vmin;
  height: 10vmin;
  background-color: magenta;
  animation: move 10s linear infinite;
}

@keyframes move {
  0% {
    transform: translateX(50vw);
  }
  50% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(50vw);
  }
}
<div></div>
<button onclick="upthespeed()">Click me to increase the speed at the end of the next iteration (you may have to wait!)</button>


推荐阅读