CSS动画应用到元素后,CSS过渡效果变得卡顿了。

6
我正在构建一个AngularJS应用程序,该应用程序通过转换其不透明度来显示和隐藏元素。该元素还通过应用CSS关键帧动画进行旋转。我遇到的问题是过渡或动画会出现卡顿。
当元素的不透明度为1时,过渡将其淡出到0,然后该元素似乎回到了几个帧之前。这在GIF中更好地演示。您可以看到它在不透明度改变之前跳回去了。
这是我的CSS。
.square {
  width: 100px;
  height: 100px;
  margin: 50px;
  background: black;
}

.appear.ng-hide-add {
   -webkit-transition: opacity 300ms linear;
  opacity: 1;
}

.appear.ng-hide-add.ng-hide-add-active {
  opacity: 0;
}

.appear.ng-hide-remove {
  -webkit-transition: opacity 300ms linear;
  opacity: 0;
}

.appear.ng-hide-remove.ng-hide-remove-active {
  opacity: 1;
}

@-webkit-keyframes rotate {
  from {
    -webkit-transform: rotate(0deg);
  }

  to {
    -webkit-transform: rotate(360deg);
  }
}

.rotate {
  -webkit-animation: rotate 1.5s infinite linear;  
}

这是我的HTML代码。
<div ng-app="app" ng-init="show = true">
  <p>Toggle the opacity of the square. Sometimes the rotation is interrupted when the opacity transitions from 1 to 0.</p>
  <button ng-click="show =!show">Toggle</button>
  <div class="square appear rotate" ng-show="show"></div>
</div>

你可以在这个 CodePen 中尝试操作。希望有人能指导我正确的方向。

我尝试过(我相信你也是)将方块包裹在另一个元素中,并隐藏/显示这个包装器,但似乎没有帮助:http://codepen.io/anon/pen/DctGj - Henrik N
是的,那对我也没用。最终采用了你的答案。https://dev59.com/CoHba4cB1Zd3GeqPMRBR#24474564 - Tate Johnson
4个回答

2

以下是另一种解决方法,仅供参考。比我之前提出的第一种方法稍微好看一些。改变方框背景颜色的透明度:http://codepen.io/anon/pen/DpuEh

HTML:

<div ng-app="app" ng-init="show = true">
  <button ng-click="show = !show">Toggle</button>
  <div class="square appear rotate" ng-class="{'hidden': !show}"></div>
</div>

CSS(层叠样式表):
.square {
  width: 100px;
  height: 100px;
  margin: 50px;
   -webkit-transition: background 300ms linear;
  background: black;
}

.square.hidden {
  background: rgba(0, 0, 0, 0);
}

我正在使用rgba设置背景透明度。在这种简单情况下,只设置背景为white也可以达到同样的效果。

谢谢 Henrik。将此更改为问题的已接受答案,因为它是100%的CSS解决方案。如果您可以利用jQuery,则可以考虑包装.animate。第一次更加平滑,之后完全平滑。请参见https://gist.github.com/tatey/3f1933d2d6d8b4dbe801 - Tate Johnson

1

对于您的情况可能或可能不适用的丑陋解决方法:而不是隐藏元素(显示错误)或容器(也显示错误),您可以在其上面淡入一个带有背景颜色的元素。

HTML:

<div ng-app="app" ng-init="show = false">
  <button ng-click="show =!show">Toggle</button>
  <div class="appear" ng-show="show"></div>
  <div class="square rotate"></div>
</div>

CSS:
.appear {
  background: white;
  width: 200px;
  height: 200px;
  position: absolute;
  top: 30px;
  left: 0;
  z-index: 2;
}

显然,对于更复杂的布局,您可能需要更复杂的CSS,但希望您能理解这个想法。
CodePen: http://codepen.io/anon/pen/IwBHj

丑陋但是聪明。幸运的是,它目前只包含在一个模板中。如果需要重复使用,我会考虑将其封装在指令中。谢谢! - Tate Johnson

1
这显然是一个WebKit的bug。这显然不是CSS应该表现的方式,如果你删除供应商前缀,它会像预期的那样在Firefox中运行。当应用其他动画/过渡时,您会注意到动画会重置。这类似于最近修复的已知错误,在不同时间应用多个CSS过渡会导致布局闪烁。我建议向WebKit团队报告此错误,以便修复。

这并没有真正回答问题。如果你有不同的问题,可以通过点击提问来提出。你也可以添加赏金来吸引更多人关注这个问题。 - ccjmne
2
@ccjmne 这不是一个解决方案,但我正在努力指导他朝正确的方向前进,因为他要求这样做。显然这是浏览器的bug,应该向 WebKit 团队报告。 - Alexander O'Mara
1
我并不是在批评他的问题或要求澄清,我是在告诉他他没有做错任何事情,这显然是一个类似于以往已知的错误,应该报告给相关人员。如果我的回答不够清晰,我已经进行了澄清。 - Alexander O'Mara
我会向 Webkit 项目提出一个 bug,并从这里链接回去。感谢您的建议。 - Tate Johnson

0

我会考虑在变换中使用translate3D来强制硬件加速。

    -webkit-transform: translate3d(0,0,0);

这个使用硬件加速(GPU)来进行CSS过渡。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接