断断续续的过渡:在 Safari 上转换缩放动画

Choppy transition: transform scalling animation on Safari

我很难在 Safari(移动)中制作不不稳定的缩放动画。断断续续的意思是您可以清楚地看到它不是 60FPS 的流畅动画。我需要说元素是绝对定位的,所以它不应该影响布局,对吗?

我尝试的第一件事是通过创建具有 2 个关键帧的 CSS 动画来为元素设置动画,从 transform: scale(0);transform: scale(1);。对于我想要达到的效果我也使用了transform-origin: top right;。我也尝试通过设置 will-change: transform; 来优化它,但它很不稳定。

我将其废弃并重新设计,因此它使用 transition: transform。所以默认情况下元素有 transform: scale(0);,当某些 class 附加到它时,它会得到 transform: scale(1); 哪个过渡正在动画,但它仍然不稳定。

经过一些研究,我发现您想避免需要浏览器重新计算布局的动画属性。我发现 this site 说 WebKit(据我所知 Safari 正在使用)几乎会为每个 属性 更改重新计算布局。是这样吗?如果是的话,你如何在移动版 Safari 上制作 60FPS 流畅的动画(在其他使用 Safari 的平台上,它并不那么引人注目,因为它们有更多的资源来重新计算所有内容,而且看起来比移动版更流畅)?

我不知道这是否有帮助,但您是否使用 javascript 添加 class 并使用 class 更改启动动画? jQuery 例如,在操作元素时可能会导致 dom 中的长深度分析,这可能会干扰实现所需 fps 所需的性能。

参考 this article 部分 Animate Changes in CSS Properties,您可以使用关键帧制作动画,但需要使用这样的百分比:

w3s article 中有更多示例。

PD:如果您添加示例,我会尽力帮助您。

function animateStart(){
  document.getElementById('ball').classList.add('bounce');
}

function animationPause(){
  document.getElementById('ball').style.webkitAnimationPlayState='paused';
}

function animationContinue(){
  document.getElementById('ball').style.webkitAnimationPlayState='running';
}
@-webkit-keyframes bounce {
    0% {top: 100px; left: 1px; -webkit-animate-timing-function: ease-in;}
    25% {top: 150px; left: 76px; -webkit-animate-timing-function: ease-out;}
    50% {top: 100px; left: 151px -webkit-animate-timing-function: ease-in;}
    75% {top: 150px; left: 226px -webkit-animate-timing-function: ease-out;}
    100% {top:100px; left: 301px;}
    }
 
.bounce {
    -webkit-animation-name: bounce;
    -webkit-animation-duration: 2s;
    -webkit-animation-timing-function: linear;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-direction: alternate;
    }
    
.ball-style {
    position:absolute; top: 100px; left: 10px;
    height:100px; width:100px; border-radius:50px;
    background:-webkit-radial-gradient(30% 30%, white, red 10%, black);;
}

.wall {
    position:absolute; left: 400px; top: 100px;
    height: 150px;
    background: black;
}
<input type="button" value="Animate alternative"
       onclick="document.getElementById('ball').classList.add('bounce');">
       
<input type="button" value="Animate" onclick="animateStart()">
<input type="button" value="Pause" onclick="animationPause()">
<input type="button" value="Continue" onclick="animationContinue()">

<div id="ball" class="ball-style"></div>
 
<div class="wall">&nbsp;</div>

您可以尝试 2 件事:

  • 避免使用 scale(0)。在某些浏览器中,这会带来问题。 scale(0.01) 几乎一样,对浏览器会更好。

  • 尝试让 GPU 处理动画而不是 CPU。这可以通过以下代码完成

    来自:{变换:比例(0.01)翻译Z(1px);}

    到:{变换:scale(1) translateZ(1px);}