javascript 更新动画参数时CSS动画之间的平滑过渡

6psbrbz9  于 2023-01-01  发布在  Java
关注(0)|答案(2)|浏览(126)

我有一个动画HTML元素(box)如下:

<div id="box"></div>

该框最初被设置为向右200像素的动画,持续时间为4秒。

.anim {
    animation-name: anim;
    animation-duration: 4s; 
    animation-timing-function: linear; /* cubic-bezier(0.1, -0.6, 0.2, 0); */
}

@keyframes anim {
    0% { left: var(--xs); }
    100% { left: var(--xe); }
}

下面是启动动画的JavaScript:

var box = document.getElementById('box');

box.style.setProperty('--xs', '0px');
box.style.setProperty('--xe', '200px');
box.classList.add('anim');

一秒后,最终位置更新为400像素:

setTimeout(() => {
    box.style.setProperty('--xe', '400px');
},1000)

当然,当最后的位置更新时,盒子从一个位置跳到另一个位置,有没有办法得到平滑的过渡,以避免“心灵传输”效应?
以下是JSFiddle:https://jsfiddle.net/Imabot/53hLe2zq/

dwbf0jvd

dwbf0jvd1#

将其animation-duration更改为8秒:

setTimeout(() => {
    box.style.setProperty('--xe', '400px');
    box.style.animationDuration = '8s';
}, 1000);

最初,这个盒子的目的是在4秒内移动200个像素;通过简单的除法,我们知道它的速度被设置为50 px/s。

┌──────┐
│ 50/s │                            (4s away)
└──────┘
|-------------------|-------------------|
0                  100                 200

一秒后,回调炒的时候,长度突然翻倍到400;这会导致盒子的速度增加到100 px/s。但是,由于它已经从原始位置移动了50 px,它必须“传送”到100 px才能在3秒内移动其余的位置。

┌──────┐
          │ 50/s │                                                          (3s away)
          └──────┘
|---------|---------|-------------------|-------------------|-------------------|
0         50       100                 200                 300                 400

                    ┌──────┐
                    │ 100/s│                                                (3s away)
                    └──────┘
|---------|---------|-------------------|-------------------|-------------------|
0         50       100                 200                 300                 400

因此,为了防止它瞬移,我们需要给予它更多的时间,使它的速度保持一致。同样,我们需要数学:

( 400  -  50 ) /  50   = 7    (seconds)
To_be_traveled / Speed = Time

将其添加到我们已经用于遍历前50个像素的1秒,我们有最终答案:8秒。
这就是它的全部内容!如果实际输入发生变化,您可以简单地将上面的公式转换为函数。请注意,这对linear以外的任何animation-timing-function都不起作用。
试试看:

var box = document.getElementById('box');

box.style.setProperty('--xs', '0px');
box.style.setProperty('--xe', '200px');
box.classList.add('anim');

setTimeout(() => {
    box.style.setProperty('--xe', '400px');
    box.style.animationDuration = '8s';
}, 1000)
#box {
    width: 40px;
    height: 40px;
    background-color: red;
    border-radius: 15px;
    position: relative; 
}

.anim {
    animation-name: anim;
    animation-duration: 4s; 
    animation-timing-function: linear;
}

@keyframes anim {
    0% { left: var(--xs); }
    100% { left: var(--xe); }
}
<div id="box"></div>
dgenwo3n

dgenwo3n2#

您可以使用以下代码在两种状态之间创建平滑过渡:
CSS:

#box {
  width: 50px;
  height: 50px;
  background-color: red;
  position: relative;
  left: 0px;
  border-radius: 15px;
  transition: left 4s ease-out;
}

#box.animate {
   left: 400px;
}

@keyframes anim {
    0% { left: var(--xs); }
    100% { left: var(--xe); }
}

HTML:

<div id="box"></div>

联森:

var box = document.getElementById('box');
setTimeout(function() { box.classList.add('animate'); }, 1000);

这将在两个状态之间创建平滑过渡,持续时间为4s。
以下是JSFiddle:https://jsfiddle.net/1fuq9ebL/

相关问题