动画和过渡的组合不能正常工作

时间:2015-08-21 14:09:27

标签: javascript css3 css-transitions css-animations css-transforms

我一直试图放一些基本的CSS3动画。目标是在按钮的单击事件上切换类,并根据添加的类为div设置动画。该代码非常适合在Firefox中进行切换的第一次迭代,但对于Chrome等其他浏览器而言,在Firefox的下一次迭代中,转换是在眨眼之间切换。请帮我弄清楚出了什么问题。

段:

$('button').click(function() {
  $('div').toggleClass('clicked');
});
div {
  background-color: #ccc;
  height: 100px;
  width: 100px;
  transition-property: top, left;
  transition-duration: 1s;
  transition-timing-function: linear;
  position: relative;
  top: 0;
  left: 0;
}
.clicked {
  animation-name: clicked;
  animation-duration: 1s;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}
@keyframes clicked {
  0% {
    top: 0;
    left: 0;
  }
  100% {
    top: 100px;
    left: 100px;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button">Click Me!</button>
<div></div>

我还准备了一个小提琴here

2 个答案:

答案 0 :(得分:6)

这是Chrome的一种已知行为。 Firefox似乎能够通过转换顺利处理动画的删除,但Chrome不会这样做。我曾在this thread中看到过这种行为。

为什么删除动画不适用于Chrome中的转换?

虽然我无法提供100%傻瓜式的解释原因,但我们可以根据this HTML5Rocks article about Accelerated rendering in Chromethis one about GPU accelerated compositing in Chrome在某种程度上对其进行解码。

似乎发生的事情是元素获得了自己的渲染层,因为它在其上设置了显式位置属性。当图层(或部分图层)因动画而失效时,Chrome仅会重新绘制受更改影响的图层。当您打开Chrome开发者控制台时,打开“显示绘制矩形”选项,您会看到动画发生时Chrome仅绘制了动画的实际元素。

但是,在动画的开始和结束时,会发生整页重绘,这会立即将元素重新置于其原始位置,从而覆盖过渡行为。

$('button').click(function(){
  $('div').toggleClass('clicked');
});
div{
  background-color: #ccc;
  height: 100px;
  width: 100px;
  transition-property: top, left;
  transition-duration: 1s;
  transition-timing-function: linear;
  position: relative;
  top: 0;
  left: 0;
}
.clicked{
  animation-name: clicked;
  animation-duration: 1s;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
}
@keyframes clicked{
  0% {top: 0; left: 0;}
  100% {top: 100px; left: 100px;}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button">Click Me!</button>
<div></div>

解决方案是什么?

由于您的移动实际上是从一个位置到另一个位置的线性移动,因此无需任何动画即可实现。我们需要做的就是使用translate转换并将元素移动到所需的no。切换类时的像素数。由于通过另一个选择器为元素分配了转换,因此转换将以线性方式发生。当类被切换时,由于元素上的转换,元素以线性方式再次移回其原始位置。

$('button').click(function() {
  $('div').toggleClass('clicked');
});
div {
  background-color: #ccc;
  height: 100px;
  width: 100px;
  transition-property: transform;
  transition-duration: 1s;
  transition-timing-function: linear;
  position: relative;
  top: 0;
  left: 0;
}
.clicked {
  transform: translate(100px, 100px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<button type="button">Click Me!</button>
<div></div>

答案 1 :(得分:4)

这是一种预期的行为。您需要使用两个单独的动画或仅使用过渡。

  

转换是动画,只是在两个动作之间执行的动画   不同的状态 - 即开始状态和结束状态。就像一个抽屉   菜单,开始状态可以打开,结束状态可以关闭,   反之亦然。

     

如果你想执行一些不特别涉及的事情   开始状态和结束状态,或者你需要更精细的颗粒控制   转换中的关键帧,然后你必须使用动画。

这是通过转换为元素设置动画的方法:

&#13;
&#13;
$('button').click(function() {
  $('div').toggleClass('clicked');
});
&#13;
div {
  background-color: #ccc;
  height: 100px;
  width: 100px;
  transition-property: top, left;
  transition-duration: 1s;
  transition-timing-function: linear;
  position: relative;
  top: 0;
  left: 0;
}
.clicked {
  top: 100px;
  left: 100px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button">Click Me!</button>
<div></div>
&#13;
&#13;
&#13;