首页 > 解决方案 > 移动设备上的平滑关键帧动画?

问题描述

我正在努力提高关键帧动画的平滑度。它似乎在桌面上完美运行,但在移动设备上非常滞后且不流畅。我需要如何更改我的代码以使其顺利进行?

见 JSBin:https ://jsbin.com/hecifu/6/edit?html,css,js,output

@keyframes overlayAnimation {
  0% {
    width:  100vw;
    height: 100vh;
    transform: translate3d(0px, 0px, 0);
    background: transparent;
  }
  25%{
    width:  10px;
    height: 200px;
    transform: translate3d(calc(50vw - 5px), calc(50vh - 100px), 0);
  }
  50%{
    width:  10px;
    height: 200px;
    transform: translate3d(calc(50vw - 5px), calc(50vh - 100px), 0) rotate(90deg);
  }
  50.1%{
    width:  200px;
    height: 10px;
    transform: translate3d(calc(50vw - 100px), calc(50vh - 5px), 0) rotate(0deg);
  }
  75%{
    width:  200px;
    height: 100vh;
    transform: translate3d(calc(50vw - 100px), 0px, 0) rotate(0deg);
  }
  100%{
    width:  100vw;
    height: 100vh;
    transform: translate3d(0px, 0px, 0) rotate(0deg);
    visibility:hidden;
  }

标签: cssanimationcss-transitions

解决方案


有几个问题可能会导致减速。但主要嫌疑人:删除box-shadow.

详细说明

CSS可以利用硬件加速动画......但仅限于动画transform-opacity所有其他动画都在CPU上运行,优化程度较低:https ://www.smashingmagazine.com/2016/12/gpu-animation-doing-对的/

您的动画会更改元素的widthheight属性 - 您可能需要考虑更改它,以便通过transform: scale(x, y)更改来更改大小:https ://developer.mozilla.org/en-US/docs/Web/CSS/变换函数/尺度

但可能动画中最大的消耗实际上是box-shadow- 你有一个全方位的box-shadow集合2000px- 这将在智能手机上产生相当大的影响,因此必须计算(即使它不必渲染所有of) 一个至少4000px大于设备宽度和高度的盒子。在最好的情况下渲染可能Box-shadows会很昂贵。这些记录在案的案例用于滚动性能,但我应该想象动画 a具有类似的性能影响。box-shadow

这里可能更好的是尝试使用 aclip-path来剪辑内容,而不是用box-shadow. 这将像这样工作(基于您的 JSBin):

var $pages = $(".page");
var $overlay = $("#overlay");

$('.page a').on("click", function(){
  if($overlay.hasClass("overlayAnimation")) return;
  $pages.fadeToggle(4000);
  $overlay.addClass("overlayAnimation").on("animationend", function(){
    $(this).removeClass("overlayAnimation");
  });
});
*{margin:0; box-sizing:border-box;}
html, body{height:100%;}


h1{   
  font: 60px/2 Helvetica;
  color: #fff;
  font-weight: normal;
  text-align: center;
}
.page{
  position: absolute;
  overflow: hidden;
  width:  90vw;
  height: 90vh;
  top:  5vh;
  left: 5vw;
  color: white;
}
#page1{
  background: #008562;
}
#page2{
  display: none;
  background: #ff8600;
}
.page a{
  font-family: Helvetica;
  color: #fff;
  border: 2px solid #fff;
  padding: 10px 15px;
  display: block;
  text-align: center;
  margin: 0 auto;
  width: 20%;
  text-decoration: none;
}

#overlay{
  position: fixed;
  z-index:999;
  width:  100vw;
  height: 100vh;
}

#overlay.overlayAnimation{
  animation: overlayAnimation 4s forwards;
}

@keyframes overlayAnimation {
  0% {
    clip-path: inset(0 0);
    background: transparent;
  }
  25%{
    clip-path: inset(calc(50% - 100px) calc(50% - 5px));
    transform: rotate(0deg);
  }
  50%{
    clip-path: inset(calc(50% - 100px) calc(50% - 5px));
    transform: rotate(90deg);
  }
  50.1%{
    clip-path: inset(calc(50% - 5px) calc(50% - 100px));
    transform: rotate(0deg);
  }
  75%{
    clip-path: inset(0 calc(50% - 100px));
  }
  100%{
    clip-path: inset(0 0);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="overlay">
    <div class="page" id="page1">
        <h1>PAGE 1</h1>
        <a href="#">Click here</a>
    </div>
      
    <div class="page" id="page2">
        <h1>PAGE 2</h1>
        <a href="#">Click here</a>
    </div>
</div>

https://jsbin.com/pojewujoko/edit?html,css,js,输出

也许试一试,看看它是否更高效?它肯定是更优雅的 IMO,并且对于直接查看代码的人来说更有意义。


推荐阅读