CSS animation-direction 没有像我预期的那样工作

CSS animation-direction not working as I would have expected

N.B. With the (more complex) setup I'm actually working with I can't use CSS Transitions. I recognise that CSS Transitions would be a perfectly good solution in the example below.

我遇到了一些问题

animation-direction: reverse

我以前从未使用过,但似乎 运行 不像我预期的那样。

解决我的问题的最简单方法是编写两个 CSS @keyframes 动画并使用其中一个。

但为了经济和优雅,我想使用 单个动画 并向前或向后播放。

下面的这个例子展示了我想要达到的效果。

页面加载时,按任一按钮将触发预期的动画。

但是,按下一个按钮后,动画不再运行,只显示前进或后退动画的结束帧。

我做错了什么?

工作示例:

const square = document.querySelector('.square');
const buttonOutbound = document.querySelector('button.outboundButton');
const buttonReturn = document.querySelector('button.returnButton');


buttonOutbound.addEventListener('click', () => {   
  square.className = 'square';   
  square.classList.add('outbound');
}, false);

buttonReturn.addEventListener('click', () => {   
  square.className = 'square';
  square.classList.add('return');
}, false);
.square {
  width: 100px;
  height: 100px;
  margin: 12px;
  background-color: red;
  transform: translateX(0) scale(1);
}

.square.outbound {
  animation: animateSquare 1s linear normal forwards;
}

.square.return {
  animation: animateSquare 1s linear reverse forwards;
}

@keyframes animateSquare {
  
  100% {
    background-color: blue;
    transform: translateX(200px) scale(0.5);
  }
}
<div class="square"></div>
<button type="button" class="outboundButton">Outbound animation</button>
<button type="button" class="returnButton">Return animation</button>

浏览器认为该动画已完成,因此它不会重新启动动画,您需要先删除 class 然后重新添加动画,以便浏览器识别此更改需要稍微延迟一下。添加 setTimeout 可以解决问题,即使超时为 0,因为 js 是单线程的。

const square = document.querySelector('.square');
const buttonOutbound = document.querySelector('button.outboundButton');
const buttonReturn = document.querySelector('button.returnButton');


buttonOutbound.addEventListener('click', () => {   
  square.classList.remove('return');
  square.classList.remove('outbound'); 
  setTimeout(() => {
      square.classList.add('outbound');
  }, 0) 
}, false);

buttonReturn.addEventListener('click', () => {  
  square.classList.remove('return');
  square.classList.remove('outbound'); 
  setTimeout(() => {
      square.classList.add('return');
  }, 0) 
}, false);
.square {
  width: 100px;
  height: 100px;
  margin: 12px;
  background-color: red;
  transform: translateX(0) scale(1);
}

.square.outbound {
  animation: animateSquare 1s linear normal forwards;
}

.square.return {
  animation: animateSquare 1s linear reverse forwards;
}

@keyframes animateSquare {
  
  100% {
    background-color: blue;
    transform: translateX(200px) scale(0.5);
  }
}
<div class="square"></div>
<button type="button" class="outboundButton">Outbound animation</button>
<button type="button" class="returnButton">Return animation</button>

我不在笔记本电脑屏幕上思考这个问题,然后意识到...我原来的设置中缺少的是 一个额外的静态 class,描述 .square .outbound 动画之后 .outbound 的呈现状态 运行:

.square.outbounded {
  background-color: blue;
  transform: translateX(200px) scale(0.5);
}

(N.B. 不需要对应的static class,描述.square后的状态.return 动画有 运行,因为 class 描述的表现状态已经在 .square)

的初始样式中描述

工作示例 (添加了 .outbounded class)

const square = document.querySelector('.square');
const buttonOutbound = document.querySelector('button.outboundButton');
const buttonReturn = document.querySelector('button.returnButton');


buttonOutbound.addEventListener('click', () => {

  square.className = 'square outbound';
  
  setTimeout(() => {
    square.classList.add('outbounded');
    square.classList.remove('outbound');
  }, 1000);
  
}, false);

buttonReturn.addEventListener('click', () => {

  square.className = 'square return';
  
  setTimeout(() => {
    square.classList.remove('return');
  }, 1000);
  
}, false);
.square {
  width: 100px;
  height: 100px;
  margin: 12px;
  background-color: red;
  transform: translateX(0) scale(1);
}

.square.outbounded {
  background-color: blue;
  transform: translateX(200px) scale(0.5);
}

.square.outbound {
  animation: animateSquare 1s linear normal forwards;
}

.square.return {
  animation: animateSquare 1s linear reverse forwards;
}

@keyframes animateSquare {
  
  100% {
    background-color: blue;
    transform: translateX(200px) scale(0.5);
  }
}
<div class="square"></div>
<button type="button" class="outboundButton">Outbound animation</button>
<button type="button" class="returnButton">Return animation</button>