【问题标题】:CSS animation scale transform starts blurry in FirefoxCSS 动画比例变换在 Firefox 中开始模糊
【发布时间】:2020-07-02 21:15:28
【问题描述】:

注意:这是 [确切地] 1½ 年 前提出的,并且 [确切地] 零活动......我显然有同样的问题,所以希望 OP @Jaffa 不会介意我捎带它,并在它上面打赏以[希望]引起一些兴趣!

OP 的原始问题是 below,而我添加的问题和示例是 below that


 
[原问题:]
我正在尝试在 SVG 上制作缩小效果的动画。我已经让它工作了,但是第一帧,缩放到 30,在 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>

代码笔在这里供审核:

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

有什么办法可以解决 Firefox 中的模糊问题吗?

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

 


编辑:

我有一个圆形 div 容器,其中包含几个元素以在圆圈内定位文本。当用户到达它时,我需要圆圈“增长”,所以我想我会使用 transform:scale() 与过渡或动画。

但是,仅在 Firefox 中,在过渡(或动画)完成之前,文本是模糊的。奇怪的是,圆圈的边界仍然非常清晰(我认为?)。

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

在 Firefox 中似乎没有什么不同,但 Chrome 和 Edge 似乎还不错。是否有我不知道的 prefix,或者这可能是 Firefox 中的渲染 bug

我的 MCSE 是 sn-p below

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>

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

【问题讨论】:

    标签: css firefox css-animations rendering css-transforms


    【解决方案1】:

    几年前我遇到过这个问题,虽然我认为我在 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>

    至于它为什么起作用,我真的不知道。但是请尝试一下,如果适合您,请告诉我。

    【讨论】:

      【解决方案2】:

      我只能猜测为什么会发生这种情况。 Firefox 在开始动画/过渡(通过将类添加到标签)之前拍摄快照,然后在过渡结束时拍摄。也许 Firefox 正在拍摄两个以上的快照。但是在下面的sn-p中可以看到,animation标签仍然是模糊的,等待动画结束;然后模糊立即消失。我认为 Firefox 进行此优化是为了获得更好的性能。

      如果重置为 initial,CSS 属性 will-change 也不能解决此问题。

      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;as @nullptrtransform-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>

      【讨论】:

      • 很难决定哪个答案应该获得赏金......两者都包含对我有用的解决方案 (backface-visibility: hidden) 并且都以不同的形式提供了很好的信息。可悲的是我can't split 两者之间的点。因此,我承认决胜局是这样一个事实,即赏金代表对一个用户的整体声誉有 500% 以上的影响(我记得通过第一个 2k 是背后真正的痛苦!)。感谢这两个答案。 ?
      猜你喜欢
      • 2011-03-05
      • 2014-10-26
      • 1970-01-01
      • 2019-09-23
      • 2021-08-24
      • 2014-04-24
      • 2016-01-18
      • 2016-10-20
      • 1970-01-01
      相关资源
      最近更新 更多