【问题标题】:Can simultaneous, expensive CSS transitions be in phase?可以同时进行昂贵的 CSS 过渡吗?
【发布时间】:2021-09-08 22:16:39
【问题描述】:

有关于the absolute timing precision of CSS transitionsremoving jitter for inexpensive simultaneous transitions 的问题。但是,答案并没有让我清楚地了解动画时间的相对准确性(例如,如果两个同时的动画是“同相”的),尤其是在过渡变得昂贵时。 p>

在处理图像时效果最为明显,例如在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');
});

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

有什么方法可以确保两个转换的每一步都同时渲染?

【问题讨论】:

    标签: css css-transitions


    【解决方案1】:

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

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

    阅读 High Performance Animations 的主题,并查看 CSS Triggers 上哪些 CSS 属性触发了哪些操作。

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

    我认为最好的解决方案,以我的拙见,我可能完全错误地接近它,是在你的 #container 元素内有一个 img 标签,提供图像作为它的 src 并删除所有background CSS 中的相关属性。

    然后使用上述相同的translate 移动它。希望通过这种方式,您将获得最顺畅的结果。

    看看 this updated fiddle 或下面的 sn-p。

    片段:

    $(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;
    }
    <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(JavaScript 动画工具套件)的忠实粉丝。这是 another example 使用 TweenMax(GSAP 的工具之一),它动画 x 属性(GSAP 世界中 translateX 的简写,它还负责所有浏览器在幕后为您添加前缀)以更直观的方式使用 .fromTo() 方法。

    【讨论】:

      猜你喜欢
      • 2016-06-13
      • 1970-01-01
      • 2023-03-19
      • 2017-08-09
      • 1970-01-01
      • 2021-10-09
      • 2022-01-16
      • 2020-06-20
      • 2020-12-23
      相关资源
      最近更新 更多