可以同步,昂贵的CSS转换同步吗?

时间:2015-12-27 02:59:10

标签: css3 css-transitions jitter

有关于the absolute timing precision of CSS transitionsremoving jitter for inexpensive simultaneous transitions的问题。然而,答案并没有让我清楚地了解动画时序的相对准确性(例如,如果两个同时动画是“同相”),特别是当转换变得昂贵时。

使用图像时效果最明显,例如在this fiddle中,图像和容器在相反的方向上移动,同时试图将图像保持在相同的绝对位置,但异步会导致抖动:

/* CSS */
#container {
  position:absolute;
  width:200px;
  height:200px;
  left:200px;
  overflow:hidden;
  background-position:-200px -150px;

  -webkit-backface-visiblity:hidden;
  -webkit-transition:all 2s ease-in-out;
  -moz-transition:all 2s ease-in-out;
  -o-transition:all 2s ease-in-out;
  transition:all 2s ease-in-out;
}

/* JS */
$(function() {
  $('#container').css('left', 0).css('background-position', '0 -150px');
});

奇怪的是,抖动始终位于中性点,这意味着图像动画阶段比容器更先进。这很难看,但是将偏移帧与静止的最终帧进行比较,方向偏差是可见的。

enter image description here

有没有办法确保同时渲染两个过渡的每个步骤?

1 个答案:

答案 0 :(得分:1)

我认为您所看到的内容被称为 Jank

这是因为您尝试设置动画的CSS属性。这两个CSS属性都是​​left& background-position触发& 合成操作。此外,left属性也会触发布局

阅读 High Performance Animations 的主题,并了解哪些CSS属性会触发 CSS Triggers 上的哪个操作。< / p>

作为解决方案,您可能需要 animate translateX instead of left 属性。结果会好一些,但我们仍然需要处理background-position,这会继续引发重画的繁重操作。

我认为最好的解决方案,在我的拙见中,我在接近它时可能完全错误,就是在img元素中添加#container标记,将图像提供为{{1}并从CSS中删除所有src相关属性。

然后使用上面提到的background移动它。这样,希望你能得到最顺利的结果。

查看 this updated fiddle 或下面的代码段。

<强> 段:

translate
$(document).ready(function() {
  $('#container').css({
    '-webkit-transform': 'translateX(0)',
    '-moz-transform': 'translateX(0)',
    '-o-transform': 'translateX(0)',
    'transform': 'translateX(0)'
  });
  $('#container > img').css({
    '-webkit-transform': 'translate(0px, -150px)',
    '-moz-transform': 'translate(0px, -150px)',
    '-o-transform': 'translate(0px, -150px)',
    'transform': 'translate(0px, -150px)'
  });
});
#container {
  position: absolute;
  width: 200px;
  height: 200px;
  left: 0px;
  overflow: hidden;
  -webkit-transform: translateX(200px);
  -moz-transform: translateX(200px);
  -o-transform: translateX(200px);
  transform: translateX(200px);
  -webkit-transition: all 2s ease-in-out;
  -moz-transition: all 2s ease-in-out;
  -o-transition: all 2s ease-in-out;
  transition: all 2s ease-in-out;
}
#container > img {
  -webkit-transform: translate(-200px, -150px);
  -moz-transform: translate(-200px, -150px);
  -o-transform: translate(-200px, -150px);
  transform: translate(-200px, -150px);
  -webkit-transition: all 2s ease-in-out;
  -moz-transition: all 2s ease-in-out;
  -o-transition: all 2s ease-in-out;
  transition: all 2s ease-in-out;
}
body,
html {
  margin: 0;
  width: 100%;
  height: 100%;
}
span {
  display: inline-block;
}

希望这有帮助。

P.S。作为旁注,我是 GSAP (JavaScript动画工具套件)的忠实粉丝。这是 another example ,使用<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script> <span id="container"> <img src="https://images.unsplash.com/photo-1448975750337-b0290d621d6d?crop=entropy&dpr=2&fit=crop&fm=jpg&h=775&ixjsv=2.1.0&ixlib=rb-0.3.5&q=50&w=1450" /> </span>(GSAP中的一个工具),可以动画TweenMax属性(GSAP世界中x的简写和它还使用 .fromTo() 方法以更直观的方式在幕后处理所有浏览器前缀。这只是我的意见和一个不起眼的建议。选择当然是你的。查一查,你不会失望的。)