关键要点
transform
和opacity
等属性,避免增加之前步骤的负担。left
、top
、right
、bottom
属性进行动画过渡,它们会导致不流畅的动画;应使用影响合成步骤的transform
属性,让浏览器在动画开始前确定图层稳定性。will-change
属性将元素提升到另一个图层,避免浏览器处理布局渲染或绘制。本文最初发表于OutSystems。感谢支持SitePoint的合作伙伴。
在移动应用中制作动画很容易。如果遵循以下技巧,在移动应用中正确地制作动画也很容易……尽管如今每个人都在移动设备上使用CSS3动画,但许多人使用方式不正确。开发人员经常忽略最佳实践。这是因为人们不理解这些实践存在的原因以及为什么它们受到如此强烈的支持。设备规格范围很广。因此,如果不优化代码,就会为大部分用户提供低于标准的体验。记住:一些高端旗舰设备功能强大,但世界上大多数人使用的设备与这些高性能设备相比,就像带有LCD屏幕的算盘。我们希望帮助您正确地利用CSS3的强大功能。为此,我们需要先了解一些事情。
理解时间线
浏览器在渲染和处理元素时会做什么?这个时间线称为关键渲染路径:
图片来源:www.csstriggers.com
为了实现流畅的动画,我们需要专注于更改影响合成步骤的属性,而不是增加之前步骤的负担。
样式 浏览器开始计算要应用于元素的样式——重新计算样式。
布局 在接下来的步骤中,浏览器生成每个元素的形状和位置——布局。在这里,浏览器设置页面属性,例如宽度和高度,以及例如其边距或
left
、top
、right
、bottom
。
绘制 浏览器将每个元素的像素填充到图层中。它参考这些属性:
box-shadow
、border-radius
、color
、background-color
等。
合成 这是您想要执行动画的地方,因为这是浏览器将所有图层绘制到屏幕上的时候。 现代浏览器可以很好地动画化四个样式属性,利用
transform
和opacity
属性。
transform: translateX(n) translateY(n) translateZ(n);
transform: scale(n);
transform: rotate(ndeg);
opacity: n;
如何达到每秒60帧
记住这一点,现在是撸起袖子加油干的时候了。让我们从HTML开始。我们将创建一个非常简单的结构并将我们的app-menu
放在一个layout
类中。
<div> <div></div> <div> <div></div> </div> </div>
错误的方法
.app-menu { left: -300px; transition: left 300ms linear; } .app-menu-open .app-menu { left: 0px; transition: left 300ms linear; }
看到我们更改的属性了吗?应避免使用left
、top
、right
、bottom
属性进行过渡。这些不会创建流畅的动画,因为它们每次都会强制浏览器执行布局传递,这会影响所有元素的子元素。结果是这样的:
该动画不够流畅。我们使用DevTools时间线检查幕后发生了什么,结果如下:
绿色区域表示渲染动画所花费的时间。此数据显示帧率不规则且性能缓慢。“绿色条表示FPS。高条表示动画以60 FPS渲染。低条表示低于60 FPS。因此,理想情况下,您希望绿色条在整个时间线上始终保持较高。红色条也表示卡顿,因此,另一种衡量进度的方法是消除这些红色条。”感谢Kayce Basques!
使用Transform
.app-menu { -webkit-transform: translateX(-100%); transform: translateX(-100%); transition: transform 300ms linear; } .app-menu-open .app-menu { -webkit-transform: none; transform: none; transition: transform 300ms linear; }
transform
属性影响合成步骤,而不是布局。在这里,我们告知浏览器我们的图层在动画开始前是稳定的,因此在渲染动画时遇到的障碍更少。
时间线正是这样反映的:
结果开始变得更好,帧率似乎已经稳定,因此动画运行更流畅。
在GPU中运行动画
然后,让我们更上一层楼。为了真正使其运行流畅,我们将使用GPU渲染动画。
<div> <div></div> <div> <div></div> </div> </div>
尽管一些浏览器仍然需要translateZ()
或translate3d()
作为后备,但will-change
属性是未来。此属性将元素提升到另一个图层,因此浏览器不必考虑布局渲染或绘制。
看到它有多流畅了吗?时间线证实了这一点:
动画的帧率更恒定,动画渲染速度更快。但在开头仍然有一个很长的帧运行:开头有点瓶颈。还记得我们一开始创建的HTML结构吗?让我们看看我们如何在JavaScript中控制app-menu
div:
.app-menu { left: -300px; transition: left 300ms linear; } .app-menu-open .app-menu { left: 0px; transition: left 300ms linear; }
啊哈!我们在这里通过向layout
div添加类导致了一个问题。这迫使浏览器重新生成我们的样式树——这影响了渲染性能。
每秒60帧的黄油般顺滑的解决方案
如果我们将菜单创建在视口区域之外呢?将菜单放在隔离区域将确保我们只影响我们希望动画化的元素。因此,我们建议使用以下HTML结构:
.app-menu { -webkit-transform: translateX(-100%); transform: translateX(-100%); transition: transform 300ms linear; } .app-menu-open .app-menu { -webkit-transform: none; transform: none; transition: transform 300ms linear; }
现在我们必须以稍微不同的方式控制菜单的状态。我们将使用JavaScript中的transitionend
函数来操作在动画结束时删除的类中的动画。
.app-menu { -webkit-transform: translateX(-100%); transform: translateX(-100%); transition: transform 300ms linear; will-change: transform; }
让我们将所有内容放在一起并检查结果。这是一个完整的启用CSS3的示例,所有内容都放在正确的位置:
function toggleClassMenu() { var layout = document.querySelector(".layout"); if(!layout.classList.contains("app-menu-open")) { layout.classList.add("app-menu-open"); } else { layout.classList.remove("app-menu-open"); } } var oppMenu = document.querySelector(".menu-icon"); oppMenu.addEventListener("click", toggleClassMenu, false);
时间线向我们展示了什么?
全是绿色的条,宝贝。想看一个实际例子吗?点击这里。(此处应插入实际链接)
(此处应添加关于移动动画的常见问题解答部分,内容与原文档中的FAQs部分一致)
以上是使用CSS3实现60 fps移动动画3的详细内容。更多信息请关注PHP中文网其他相关文章!