我遇到了这个问题,不理解这种行为.

这里我们有一个简单的矩形,它应该在按下切换按钮时进行动画输入和输出.

当按钮被点击时,矩形类名称将在"animation-in"和"animation-out"之间切换.

"Scale-easeInOutBoss"和"Scale-easeInOutBoss-Out"的KeyFrame对象是相同的,只是名称引用不同.

一切都很完美.

当在css规则‘.Animation-Out’内的属性‘Animation-name:’从‘Scale-easeInOutBlip-Out’更改为‘Scale-easeInOutBounch’时,动画中断.

这里的问题是,为什么会发生这种情况?代码中是否存在逻辑错误,或者动画的实现是否不正确?

会很乐意理解这种行为.

这一行为在Windows 11上使用Chrome进行了复制


<!DOCTYPE html>
<html>
<head>
    <title>Rectangle Animation</title>
    <style>
        #myRectangle {
            width: 100px;
            height: 150px;
            background-color: green;
            margin: 20px;
            transform: scale(0);
            
        }

        .animation-out {
            animation-duration: 4s;
            animation-timing-function: ease; /*linear*/
            animation-delay: 0s;
            animation-iteration-count: 1;
            animation-direction: normal;
            animation-fill-mode: forwards;
            animation-play-state: running;
            animation-name: scale-easeInOutBounce;
            animation-timeline: auto;
            animation-range-start: normal;
            animation-range-end: normal;
        }

        .animation-in {
            animation-duration: 4s;
            animation-timing-function: ease;
            animation-delay: 0s;
            animation-iteration-count: 1;
            animation-direction: reverse;
            animation-fill-mode: forwards;
            animation-play-state: running;
            animation-name: scale-easeInOutBounce;
            animation-timeline: auto;
            animation-range-start: normal;
            animation-range-end: normal;
        }

        @keyframes scale-easeInOutBounce {
            0% { transform: scale(1); }
            2% { transform: scale(0.99); }
            4% { transform: scale(1); }
            10% { transform: scale(0.97); }
            14% { transform: scale(0.99); }
            22% { transform: scale(0.88); }
            32% { transform: scale(0.99); }
            42% { transform: scale(0.6); }
            50% { transform: scale(0.5); }
            58% { transform: scale(0.4); }
            68% { transform: scale(0.01); }
            78% { transform: scale(0.12); }
            86% { transform: scale(0.01); }
            90% { transform: scale(0.03); }
            96% { transform: scale(0); }
            98% { transform: scale(0.01); }
            100% { transform: scale(0); }
        }

        @keyframes scale-easeInOutBounce-out {
            0% { transform: scale(1); }
            2% { transform: scale(0.99); }
            4% { transform: scale(1); }
            10% { transform: scale(0.97); }
            14% { transform: scale(0.99); }
            22% { transform: scale(0.88); }
            32% { transform: scale(0.99); }
            42% { transform: scale(0.6); }
            50% { transform: scale(0.5); }
            58% { transform: scale(0.4); }
            68% { transform: scale(0.01); }
            78% { transform: scale(0.12); }
            86% { transform: scale(0.01); }
            90% { transform: scale(0.03); }
            96% { transform: scale(0); }
            98% { transform: scale(0.01); }
            100% { transform: scale(0); }
        }
    </style>
</head>
<body>

<div id="myRectangle"></div>
<button id="toggleButton">Toggle Animation</button>

<script>
    document.getElementById('toggleButton').addEventListener('click', function() {
        var rectangle = document.getElementById('myRectangle');
        if (rectangle.classList.contains('animation-in')) {
            rectangle.classList.remove('animation-in');
            rectangle.classList.add('animation-out');
        } else {
            rectangle.classList.remove('animation-out');
            rectangle.classList.add('animation-in');
        }
    });
</script>

</body>
</html>

https://jsfiddle.net/midnightstudios/vajqdcLo/2/

以下是被破解的代码:

<!DOCTYPE html>
<html>
<head>
    <title>Rectangle Animation</title>
    <style>
        #myRectangle {
            width: 100px;
            height: 150px;
            background-color: green;
            margin: 20px;
            transform: scale(0);
            
        }

        .animation-out {
            animation-duration: 4s;
            animation-timing-function: ease; /*linear*/
            animation-delay: 0s;
            animation-iteration-count: 1;
            animation-direction: normal;
            animation-fill-mode: forwards;
            animation-play-state: running;
            animation-name: scale-easeInOutBounce;
            animation-timeline: auto;
            animation-range-start: normal;
            animation-range-end: normal;
        }

        .animation-in {
            animation-duration: 4s;
            animation-timing-function: ease;
            animation-delay: 0s;
            animation-iteration-count: 1;
            animation-direction: reverse;
            animation-fill-mode: forwards;
            animation-play-state: running;
            animation-name: scale-easeInOutBounce;
            animation-timeline: auto;
            animation-range-start: normal;
            animation-range-end: normal;
        }

        @keyframes scale-easeInOutBounce {
            0% { transform: scale(1); }
            2% { transform: scale(0.99); }
            4% { transform: scale(1); }
            10% { transform: scale(0.97); }
            14% { transform: scale(0.99); }
            22% { transform: scale(0.88); }
            32% { transform: scale(0.99); }
            42% { transform: scale(0.6); }
            50% { transform: scale(0.5); }
            58% { transform: scale(0.4); }
            68% { transform: scale(0.01); }
            78% { transform: scale(0.12); }
            86% { transform: scale(0.01); }
            90% { transform: scale(0.03); }
            96% { transform: scale(0); }
            98% { transform: scale(0.01); }
            100% { transform: scale(0); }
        }
    </style>
</head>
<body>

<div id="myRectangle"></div>
<button id="toggleButton">Toggle Animation</button>

<script>
    document.getElementById('toggleButton').addEventListener('click', function() {
        var rectangle = document.getElementById('myRectangle');
        if (rectangle.classList.contains('animation-in')) {
            rectangle.classList.remove('animation-in');
            rectangle.classList.add('animation-out');
        } else {
            rectangle.classList.remove('animation-out');
            rectangle.classList.add('animation-in');
        }
    });
</script>

</body>
</html>

推荐答案

我可以解释行为的原因,以及你可以做些什么来解决它.

Cause

向外动画似乎中断的原因是因为它实际上似乎是从中间开始的.更具体地说,如果你按下按钮,向内的动画将播放4秒,对吗?然后,假设您等待8秒后再按下第二次按钮.出于某种原因,向外动画将在其动画开始12秒后开始.作为证据,try 将向外动画的持续时间设置为20秒,然后再次try 按下按钮.您会注意到,向外动画在中途开始.

Solution

如果您希望继续使用相同的动画名称并保持代码的原样,一种解决方案实际上是在添加类之前添加延迟.我编辑了这个示例,并在下面展示了它.例如,您可以使用类似setTimeout(() => rectangle.classList.add('animation-out'), 0)的函数,但更好的函数应该是requestAnimationFrame(),因为它最大限度地减少了延迟.

document.getElementById('toggleButton').addEventListener('click', function() {
        var rectangle = document.getElementById('myRectangle');
        if (rectangle.classList.contains('animation-in')) {
            rectangle.classList.remove('animation-in');
            requestAnimationFrame(() => {rectangle.classList.add('animation-out');})
            
        } else {
            rectangle.classList.remove('animation-out');
            requestAnimationFrame(() => {rectangle.classList.add('animation-in');})
        }
    });
#myRectangle {
            width: 100px;
            height: 150px;
            background-color: green;
            margin: 20px;
            transform: scale(0);
        }

.animation-out {
  animation-duration: 4s;
  animation-timing-function: ease;
  animation-direction: normal;
  animation-fill-mode: forwards;
  animation-name: scale-easeInOutBounce;
}

.animation-in {
  animation-duration: 4s;
  animation-timing-function: ease;
  animation-direction: reverse;
  animation-fill-mode: forwards;
  animation-name: scale-easeInOutBounce;
}

@keyframes scale-easeInOutBounce {
  0% { transform: scale(1); }
  2% { transform: scale(0.99); }
  4% { transform: scale(1); }
  10% { transform: scale(0.97); }
  14% { transform: scale(0.99); }
  22% { transform: scale(0.88); }
  32% { transform: scale(0.99); }
  42% { transform: scale(0.6); }
  50% { transform: scale(0.5); }
  58% { transform: scale(0.4); }
  68% { transform: scale(0.01); }
  78% { transform: scale(0.12); }
  86% { transform: scale(0.01); }
  90% { transform: scale(0.03); }
  96% { transform: scale(0); }
  98% { transform: scale(0.01); }
  100% { transform: scale(0); }
}

@keyframes scale-easeInOutBounce-out {
  0% { transform: scale(1); }
  2% { transform: scale(0.99); }
  4% { transform: scale(1); }
  10% { transform: scale(0.97); }
  14% { transform: scale(0.99); }
  22% { transform: scale(0.88); }
  32% { transform: scale(0.99); }
  42% { transform: scale(0.6); }
  50% { transform: scale(0.5); }
  58% { transform: scale(0.4); }
  68% { transform: scale(0.01); }
  78% { transform: scale(0.12); }
  86% { transform: scale(0.01); }
  90% { transform: scale(0.03); }
  96% { transform: scale(0); }
  98% { transform: scale(0.01); }
  100% { transform: scale(0); }
}
<!DOCTYPE html>
<html>
<head>
    <title>Rectangle Animation</title>
</head>
<body>

<div id="myRectangle"></div>
<button id="toggleButton">Toggle Animation</button>
</body>
</html>

为什么这种行为一开始就会发生?我不确定.一般来说,在各种情况下交换关键帧时,您可能会遇到一些非常奇怪的行为(无论是涉及纯CSS还是JavaScript WAAPI)--这是我个人的经验.在这种情况下,交换类可能会立即使它感到困惑,并认为它只是将关键帧交换为单个动画,而不是完全交换动画,因此它错误地保持持续时间,而不是从0开始?

Javascript相关问答推荐

在JavaScript中对大型级联数组进行切片的最有效方法?

获取表格的左滚动位置

如何在不分配整个数组的情况下修改包含数组的行为主体?

仅圆角的甜甜圈图表

深嵌套的ng-container元素仍然可以在Angular 布局组件中正确渲染内容吗?

PrivateRoute不是路由组件错误

如何从调整大小/zoom 的SVG路径定义新的d属性?""

如何在Vue 3中创建自定义 Select 组件,并将选项作为HTML而不是props 传递?

如何在每次单击按钮时重新加载HighChart/设置HighChart动画?

如何在文本字段中输入变量?

Vaadin定制组件-保持对javascrip变量的访问

在表单集中保存更改时删除';禁用';

Node.js API-queryAll()中的MarkLogic数据移动

如何根据输入数量正确显示alert ?

MongoDB通过数字或字符串过滤列表

在将元素追加到DOM之前,createElement()是否会触发回流?混淆abt DocumentFragment行为

如何使pdf.js上的文本呈现为可选?

如何在单击链接时设置一个JavaScript变量(以打开弹出窗口的特定部分)

:host::ng-Deep不将样式应用于material 复选框

如何让noWrap在嵌套在Alert/AlertTitle组件中的排版组件中工作?