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

问题描述

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

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

我将它报废并重新加工,使其使用 transition: transform。所以认元素有 transform: scale(0);,当某个类附加到它时,它会得到 transform: scale(1); 哪个过渡正在动画,但它仍然断断续续。

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

解决方法

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

this 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>

,

您可以尝试两件事:

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

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

    来自:{transform: scale(0.01) translateZ(1px);}

    to: {transform: scale(1) translateZ(1px);}

,

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