【问题标题】:CSS transform:translateX animation render problemsCSS transform:translateX 动画渲染问题
【发布时间】:2021-06-24 06:56:43
【问题描述】:

首先让我解释一下这个问题,然后是我试图解决的问题。包括有效的东西,但性能不太好,因此我的问题。

问题是当使用 translateX(或 translateY)为元素设置动画时,它的一部分根本不会被渲染。这适用于 CSS 动画和 CSS 过渡。仅在大型元素上发生。

在 300vw(动画元素的宽度)时,它很少发生。在 700vw 时,它总是会发生。

Example with 300vw Example with 700vw

在这两种情况下,相关元素都是伪元素,并且被 translateX 100% - 100vw(始终保持可见)

这是该伪元素的 CSS,这是复制此元素所需的所有代码(并将 svg_divider 类赋予容器);

.svg_divider{
overflow:hidden;
position:relative;
}
.svg_divider::before{ 
content:'';
position: absolute;
z-index: 3;
pointer-events: none;
background-repeat: no-repeat;   
bottom: -0.1vw;
left: -0.1vw;
right: -600.1vw;
top: -0.1vw; 
animation: 4s infinite alternate animateHorShape linear;
background-position: 50% 100%;
background-size: 100% 90px;   background-image: url('data:image/svg+xml;charset=utf8, <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320" preserveAspectRatio="none"><path fill="%23fbd8c2" d="M0 32l48 32c48 32 144 96 240 106.7 96 10.3 192-31.7 288-21.4 96 10.7 192 74.7 288 69.4 96-5.7 192-79.7 288-106.7s192-5 240 5.3l48 10.7v192H0z"/><path fill="%23fbd8c2" opacity=".66" d="M0 64l48 16c48 16 144 48 240 48s192-32 288-26.7C672 107 768 149 864 144s192-59 288-80 192-11 240-5.3l48 5.3v256H0z"/></svg>'); 
}
@media (min-width:2100px){
.svg_divider::before{
background-size: 100% calc(2vw + 90px);
}
}


@keyframes animateHorShape {
   100% {
           transform: translateX(calc( -100% + 100vw));
   } 
   }

/* Only for preview*/
.preview{
  display:flex;
  flex-direction:column;
  height:100vh;
}
.preview div{
  flex-grow:1;
}
<div class="preview">
    <div class="svg_divider"></div>
    <div></div>
  </div>

全屏运行代码sn-p,看清楚。您会注意到,在任何滚动事件中,它都会“快速”回到视图中。

代码用于 700vw 元素,它总是显示错误(至少在 Chrome 和 Safari 中)。

我尝试了以下方法使其变得更好:

使用过渡而不是关键帧动画,通过 setInterval 函数切换类来更改 translateX 值。存在完全相同的问题。

试图通过调度窗口调整大小事件和窗口滚动事件来触发浏览器的强制重绘。没用。

以下工作,但性能不太好

使用 rAF 用 JS 编写。那行得通,没有渲染问题。但是,当您在页面上有几个时,CPU 开销会达到约 60%(@ 6x 慢 CPU 设置)。 translateX 版本仍为 ~2%。 See that rAF version here

直接动画背景位置也可以。因此,将形状保持在 100vw,但将其拉伸为背景大小,然后为背景位置设置动画。类似的问题,性能不太好,动画不太流畅。

对此的任何帮助将不胜感激。

干杯

【问题讨论】:

    标签: javascript css browser rendering


    【解决方案1】:

    终于解决了这个问题。这是我的理解和解决方案:

    浏览器呈现可见的元素。因此,如果您有一些大的东西超出了视口,浏览器就不会费心渲染不在视图中的部分。这一切都很好,应该是这样。

    在我的情况下,虽然它意味着您在该页面上看到的内容...形状未呈现,因此它在某个时候“停止”。

    这是因为 CSS 转换不会渲染内容,它会转换已经渲染的元素。这就是为什么它如此高效且性能如此出色的原因。然而,这导致了大元素的错误。

    但是通过让元素从一开始就在视口中(宽度约为 100vw),然后通过变换 scaleX (100) 拉伸它,所有的形状都被考虑在内,因为它最初是由浏览器完全渲染的.

    .svg_divider {
      overflow: hidden;
      position: relative;
    }
    .svg_divider::before {
      content: "";
      position: absolute;
      z-index: 3;
      pointer-events: none;
      background-repeat: no-repeat;
      bottom: -0.1vw;
      left: -0.1vw;
      right: -0.1vw;
      top: -0.1vw;
      transform-origin: 100% 0;
      transform: scaleX(100);
      animation: 14s infinite alternate animateHorShapee linear;
      background-position: 50% 0%;
      background-size: 100% 90px;
      background-image: url('data:image/svg+xml;charset=utf8, <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 35.28 2.17" preserveAspectRatio="none">><path d="M0 .5c3.07.55 9.27-.42 16.14 0 6.88.4 13.75.57 19.14-.11V0H0z" fill="%23FBD8C2"/><path d="M0 1c3.17.8 7.29-.38 10.04-.55 2.75-.17 9.25 1.47 12.67 1.3 3.43-.17 4.65-.84 7.05-.87 2.4-.02 5.52.88 5.52.88V0H0z" opacity=".5" fill="%23FBD8C2"/><g><path d="M0 1.85c2.56-.83 7.68-.3 11.79-.42 4.1-.12 6.86-.61 9.58-.28 2.73.33 5.61 1.17 8.61 1 3-.19 4.73-.82 5.3-.84V.1H0z" opacity=".5" fill="%23FBD8C2"/></g></svg>');
    }
    @media (min-width: 2100px) {
      .svg_divider::before {
        background-size: 100% calc(2vw + 90px);
      }
    }
    
    @keyframes animateHorShapee {
      100% {
        transform: scaleX(100) translateX(98%);
      }
    }
    
        /* Only for preview*/
        .preview{
          display:flex;
          flex-direction:column;
          height:100vh;
        }
        .preview div{
          flex-grow:1;
        }
    <div class="preview">
        <div class="svg_divider"></div>
        <div></div>
      </div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-07
      • 1970-01-01
      • 2014-04-27
      • 2011-07-30
      • 1970-01-01
      • 2011-05-19
      • 1970-01-01
      相关资源
      最近更新 更多