【问题标题】:CSS 3D transform intersection glitch in Chrome / WindowsChrome / Windows 中的 CSS 3D 变换交叉点故障
【发布时间】:2021-05-08 01:13:46
【问题描述】:

我一直在尝试对 HTML 元素进行 CSS 3D 转换的一些基本工作 - 但是在使用 Windows 时,我在 Chrome 中遇到了一个相当严重的故障。这个问题也出现在 Linux 上的 Chrome 上,但似乎不会出现在 Safari 上的 Chrome 上(使用 AMD、Nvidia 和 Intel GPU 加速测试):

当多个 3D 变换元素在关键帧动画期间相交时,尤其是当它们的父元素也被 3D 变换时,会导致视觉伪影,导致两个绘制的元素都无法正确显示,这也可能会完全覆盖浏览器的 UI .

* {
  backface-visibility: hidden;
}

body {
  background-color: #333;
}

#stage {
  transform-style: preserve-3d;
}

.box {
  width: 200px;
  height: 200px;
  position: relative;
  transform-style: preserve-3d;
}

.box_one {
  border: 1px solid blue;
  animation: rotate_x 10s infinite;
}

.box_two {
  border: 1px solid red;
  animation: rotate_y 10s infinite;
}

.side {
  width: 200px;
  height: 200px;
  position: absolute;
  border: 1px solid black;
  top: 0;
  left: 0;
}

.side_1 {
  transform: rotateX(90deg) translateZ(100px);
}

.side_2 {
  transform: rotateX(90deg) translateZ(-100px);
}

.side_3 {
  transform: rotateY(90deg) translateZ(100px);
}

.side_4 {
  transform: rotateY(90deg) translateZ(-100px);
}

.side_5 {
  transform: rotateZ(90deg) translateZ(100px);
}

.side_6 {
  transform: rotateZ(90deg) translateZ(-100px);
}

@keyframes rotate_x {
  0% {
    transform: translateX(100px) rotateX(0deg);
  }
  50% {
    transform: translateX(100px) rotateX(360deg);
  }
  100% {
    transform: translateX(100px) rotateX(-0deg);
  }
}

@keyframes rotate_y {
  0% {
    transform: rotateY(0deg);
  }
  50% {
    transform: rotateY(360deg);
  }
  100% {
    transform: rotateY(-0deg);
  }
}

.top {
  transform: rotateX(-90deg);
}
<body>
  <div id="stage" class="top">
    <div class="box box_one">
      <div class="side side_1">

      </div>
      <div class="side side_2">

      </div>
      <div class="side side_3">

      </div>
      <div class="side side_4">

      </div>
      <div class="side side_5">

      </div>
      <div class="side side_6">

      </div>
    </div>
    <div class="box box_two">
      <div class="side side_1">

      </div>
      <div class="side side_2">

      </div>
      <div class="side side_3">

      </div>
      <div class="side side_4">

      </div>
      <div class="side side_5">

      </div>
      <div class="side side_6">

      </div>
    </div>

  </div>

  </div>


</body>

有没有人有办法解决这个故障,或者有办法避免它发生?我一直在尽可能地避免重叠,但在中等复杂的变换和场景中似乎仍然会发生这种情况。

【问题讨论】:

  • 发生在我身上

标签: html css 3d css-animations css-transforms


【解决方案1】:

我不知道有什么明确的解决办法。
请注意,实际上并不是重叠元素导致渲染拙劣。
似乎父母也有一个transform:rotate,这是真正的罪魁祸首。
IE。您可以移除第一个框,仍然可以看到渲染工件。

似乎父窗格的有效宽度对此有很大影响。 当你rotateY(90deg).top div 时,渲染高度变为0 像素。 做一个稍微少一点的旋转,即 89 度似乎大大减少了伪影。

我不确定您的用例,您可能会在正确的位置应用overflow:hidden;。以可接受的方式包含渲染工件。

我为.top 应用了背景以显示实际大小。 另外,我只将backface-visibility:hidden 应用于.box

$(".no").click(function() {
  $(".top").toggleClass('no-rotate').removeClass('tiny-rotate')
})

$(".tiny").click(function() {
  $(".top").toggleClass('tiny-rotate').removeClass('no-rotate')
})
.box >* {
  backface-visibility: hidden;
}

body {
  background-color: #333;
}

#stage {
  transform-style: preserve-3d;
  transform: rotateX(-180deg)
}

#stage * {
  transform-style: preserve-3d;
}

.box {
  width: 200px;
  height: 200px;
  position: relative;
  transform-style: preserve-3d;
}

.box_one {
  border: 1px solid blue;
  animation: rotate_x 10s infinite;
}

.box_two {
  border: 1px solid red;
  animation: rotate_y 10s infinite;
}

.side {
  width: 200px;
  height: 200px;
  position: absolute;
  border: 1px solid black;
  top: 0;
  left: 0;
}

.side_1 {
  transform: rotateX(90deg) translateZ(100px);
}

.side_2 {
  transform: rotateX(90deg) translateZ(-100px);
}

.side_3 {
  transform: rotateY(90deg) translateZ(100px);
}

.side_4 {
  transform: rotateY(90deg) translateZ(-100px);
}

.side_5 {
  transform: rotateZ(90deg) translateZ(100px);
}

.side_6 {
  transform: rotateZ(90deg) translateZ(-100px);
}

@keyframes rotate_x {
  0% {
    transform: translateX(100px) rotateX(0deg);
  }
  50% {
    transform: translateX(100px) rotateX(360deg);
  }
  100% {
    transform: translateX(100px) rotateX(-0deg);
  }
}

@keyframes rotate_y {
  0% {
    transform: rotateY(0deg);
  }
  50% {
    transform: rotateY(360deg);
  }
  100% {
    transform: rotateY(-0deg);
  }
}

.top {
  transform: rotateX(-90deg);
  background-color: OldLace;
  transition: transform 2s;
}

.top.no-rotate {
  transform: rotateX(0deg);
}

.top.tiny-rotate {
  transform: rotateX(-89deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<body>
  <button class="no">toggle no rotate</button>
  <button class="tiny">toggle tiny rotate</button>
  <div id="stage">
    <div class="top no-rotate">
      <div class="box box_one">
        <div class="side side_1"> </div>
        <div class="side side_2"> </div>
        <div class="side side_3"> </div>
        <div class="side side_4"> </div>
        <div class="side side_5"> </div>
        <div class="side side_6"> </div>
      </div>
      <div class="box box_two">
        <div class="side side_1"> </div>
        <div class="side side_2"> </div>
        <div class="side side_3"> </div>
        <div class="side side_4"> </div>
        <div class="side side_5"> </div>
        <div class="side side_6"> </div>
      </div>
    </div>
  </div>


</body>

【讨论】:

    猜你喜欢
    • 2017-08-21
    • 2010-11-22
    • 2021-08-24
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    • 1970-01-01
    • 2015-12-05
    • 1970-01-01
    相关资源
    最近更新 更多