CSS动画缩放变换在Firefox中开始模糊

10

注意:这个问题是1.5年前提出的,而且从未有过回应... 我遇到了同样的问题,所以希望原作者 @Jaffa 不介意我跟进它,并在上面添加一个赏金,以[希望]引起一些兴趣!)

下面是原始问题,我的附加问题和示例在其下方。


 
[原始问题:]
我试图对 SVG 实现缩小动画效果。我已经让它工作了,但是第一帧被缩放为30时,在 Firefox 中会变得模糊/像素化。

Firefox: Chrome:

我在 Chrome 或 Edge 中没有看到相同的问题。初始帧应该是清晰的,因为它是一个 SVG。

html,
body {
  margin: 0px;
  padding: 0px;
}
.wrapper {
  padding: 50px 50px;
  max-width: 1200px;
  margin-left: auto;
  margin-right: auto;
  margin-top: 80px;
}
.img_zoom {
  width: 400px;
  height: 500px;
  margin: 2em auto 2em auto;
  overflow: hidden;
}
.zoom {
  width: 100%;
  height: 100%;
  background-position: center;
  background-size: cover;
  animation: zoom 5s ease-in-out 4s 1 normal forwards;
  transform: translate(3400px, -3600px) scale(30);
}
@keyframes zoom {
  to {
    margin-left: 0;
    transform: translate(0px, 0px) scale(0.7);
  }
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div class="wrapper">
    <div class="img_zoom">
      <div class="zoom"><img src="https://flexion.tech/images/box-con.svg"></div>
    </div>
  </div>
</body>
</html>

这里提供Code pen代码:

https://codepen.io/jaffa80/pen/KKpxgeQ

有没有什么建议可以解决Firefox中的模糊问题?

我还遇到了另一个问题,如果我从@keyframe中删除margin-left:0,事情就会停止工作。任何关于此的指针都将不胜感激。

 


编辑:

我有一个圆形div容器,其中包含几个元素来定位圆形内的文本。我需要在用户到达时“扩大”圆形,因此我想使用transform:scale()进行转换或动画。

然而,在Firefox中,只有在转换(或动画)完成之前,文字才会变得模糊。奇怪的是,圆形的边框保持完美清晰(我认为?)。

考虑可能需要一段时间进行预渲染,我尝试了仅使用setTimeout延迟,以及与事件(openDOMContentLoaded)和requestAnimationFrame结合使用。我还尝试使用css的animation而不是transition

在Firefox中似乎没有任何改变,但Chrome和Edge看起来很好。我不知道是否有什么前缀,或者这是Firefox中的渲染错误?

我的MCSE是下面的代码:

setTimeout(function(){ 
  circ.classList.remove('shrunk');
},500);
body{ font-family:'fira code'; font-size:20px; }
#circ{ position:relative; border:3px solid blue; border-radius:50%; text-align:center; white-space: nowrap; transition:transform 1000ms; }
#circ span{ position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); }
.shrunk{ transform:scale(0.1); }
<div class='shrunk' id='circ' style='width:336px; height:336px;'>
  <span>Lorem<br>Ipsum is simply<br>dummy text of the<br>printing and typesetting<br>industry. Lorem Ipsum has<br>been the industry's<br>standard dummy text ever<br>since the 1500s, when an<br>unknown printer took a<br>galley of type and<br>scrambled it to make<br>a type specimen<br>book.</span>
</div>

有什么建议或解决方法吗?

2个回答

6
我只能猜测这是为什么。Firefox 在动画 / 过渡开始之前(通过将类添加到标签)和结束时都会进行快照。也许 Firefox 拍摄了超过两个快照。但是,如您在下面的代码片段中所看到的那样,animation 标签仍然模糊,并等待动画完成;然后模糊立即消失。我认为 Firefox 为了更好的性能进行了这种优化。
CSS 属性 will-change 也无法解决此问题,即使重置为 initial

setTimeout(function() {
  circ.classList.add('shrunk');
}, 2000);
body {
  display: flex;
  flex-flow: column;
  font-family: 'fira code';
  gap: 2rem;
}

.circles,
.titles {
  width: 100%;
  display: flex;
  gap: 2rem;
}

h4 {
  width: 105px;
  font-size: 0.8rem;
}

#circ,
#circ2,
#circ3,
#circ4 {
  width: 100px;
  height: 100px;
  position: relative;
  border: 3px solid blue;
  border-radius: 50%;
  text-align: center;
  word-break: break-all;
}

#circ {
  transition: transform 1000ms;
  transform: scale(0.1);
}

#circ2 {
  animation: forwardAnim 5s linear forwards;
}

#circ3 {
  animation: forwardAnim 5s linear forwards;
  backface-visibility: hidden;
}

#circ4 {
  animation: forwardAnim 5s linear forwards;
  transform-style: preserve-3d;
}

#circ span,
#circ2 span,
#circ3 span,
#circ4 span {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

#circ.shrunk {
  transform: scale(1);
}

@keyframes forwardAnim {
  0% {
    transform: scale(0.1);
  }
  45% {
    transform: scale(0.1);
  }
  50% {
    transform: scale(1);
  }
  100% {
    transform: scale(1);
  }
}
<div class="circles">
  <div id="circ">
    <span>This is my text!</span>
  </div>
  <div id="circ2">
    <span>This is my text!</span>
  </div>

  <div id="circ3">
    <span>This is my text!</span>
  </div>
  <div id="circ4">
    <span>This is my text!</span>
  </div>
</div>
<div class="titles">
  <h4>Add class with transition</h4>
  <h4>Animation</h4>
  <h4>Animation with backface-visibility: hidden</h4>
  <h4>Animation with transform-style: preserve-3d</h4>
</div>

为了避免这种情况,您可以使用backface-visibility: hidden;,就像@nullptr上面提到的那样,或者使用transform-style: preserve-3d;*以获得更平滑的过渡效果。

setTimeout(function() {
  circ.classList.remove('shrunk');
}, 500);
setTimeout(function() {
  circ2.classList.remove('shrunk');
}, 500);
body {
  display: flex;
  flex-flow: column;
  font-family: 'fira code';
  gap: 2rem;
  font-size: 0.9rem;
}

.circles,
.titles {
  width: 100%;
  display: flex;
  gap: 2rem;
}

h4 {
  width: 255px;
  font-size: 0.8rem;
  text-align: center;
}

#circ,
#circ2 {
  width: 250px;
  height: 250px;
  position: relative;
  border: 3px solid blue;
  border-radius: 50%;
  text-align: center;
  white-space: nowrap;
  transition: transform 1000ms;
}

#circ {
  backface-visibility: hidden;
}

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

#circ span,
#circ2 span {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

.shrunk {
  transform: scale(0.1);
}
<div class="circles">
  <div class="shrunk" id="circ">
    <span>Lorem<br />Ipsum is simply<br />dummy text of the<br />printing and
          typesetting<br />industry. Lorem Ipsum has<br />been the industry's<br />standard
          dummy text ever<br />since the 1500s, when an<br />unknown printer
          took a<br />galley of type and<br />scrambled it to make<br />a type
          specimen<br />book.</span
        >
      </div>
      <div class="shrunk" id="circ2">
        <span
          >Lorem<br />Ipsum is simply<br />dummy text of the<br />printing and
          typesetting<br />industry. Lorem Ipsum has<br />been the industry's<br />standard
          dummy text ever<br />since the 1500s, when an<br />unknown printer
          took a<br />galley of type and<br />scrambled it to make<br />a type
          specimen<br />book.</span
        >
      </div>
    </div>
    <div class="titles">
      <h4>backface-visibility: hidden;</h4>
      <h4>transform-style: preserve-3d;</h4>
    </div>

避免圆形内模糊内容的另一种方法是,如果没有必要,可以删除position: absolute,并改用父元素上的display: flex来对齐内容。

setTimeout(function() {
  circ.classList.remove('shrunk');
}, 500);
body {
  font-family: 'fira code';
  font-size: 20px;
}

#circ {
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  border: 3px solid blue;
  border-radius: 50%;
  text-align: center;
  white-space: nowrap;
  transition: transform 1000ms;
}

.shrunk {
  transform: scale(0.1);
}
<div class="shrunk" id="circ" style="width: 336px; height: 336px">
  <span>Lorem<br />Ipsum is simply<br />dummy text of the<br />printing and
        typesetting<br />industry. Lorem Ipsum has<br />been the industry's<br />standard
        dummy text ever<br />since the 1500s, when an<br />unknown printer took
        a<br />galley of type and<br />scrambled it to make<br />a type
        specimen<br />book.</span
      >
    </div>


1
很难决定哪个答案应该获得悬赏...两个答案都包含了对我有用的解决方案(backface-visibility: hidden),并且都提供了不同形式的好信息。遗憾的是,我无法分割这些点数。因此,我承认决定胜负的关键因素是悬赏声望对某个用户整体声望的影响要高出500%(我记得通过前2k真的很痛苦!)。感谢两位回答者。 - ashleedawg

5
我几年前也遇到过这个问题,不过我想当时是在 Chrome 上而不是 Firefox 上。但这似乎也可以解决 Firefox 中的问题。
在你的转换组件中添加 backface-visibility: hidden。这将使得只有元素的正面被动画化,而不是前后两面都动画化。

setTimeout(function(){ 
  circ.classList.remove('shrunk');
},500);
body{ font-family:'fira code'; font-size:20px; }
#circ{ position:relative; border:3px solid blue; border-radius:50%; text-align:center; white-space: nowrap; transition:transform 1000ms; backface-visibility: hidden; }
#circ span{ position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); }
.shrunk{ transform:scale(0.1); }
<div class='shrunk' id='circ' style='width:336px; height:336px;'>
  <span>Lorem<br>Ipsum is simply<br>dummy text of the<br>printing and typesetting<br>industry. Lorem Ipsum has<br>been the industry's<br>standard dummy text ever<br>since the 1500s, when an<br>unknown printer took a<br>galley of type and<br>scrambled it to make<br>a type specimen<br>book.</span>
</div>

至于为什么它有效,我真的不知道。但请尝试一下并让我知道它是否适用于您。


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