摘要: 理解浏览器渲染。javascript
Fundebug经受权转载,版权归原做者全部。css
这是专门探索 JavaScript 及其所构建的组件的系列文章的第 13 篇。html
若是你错过了前面的章节,能够在这里找到它们:前端
你确定知道,动画在建立引人注目的 Web 应用程序中扮演着重要的角色。随着用户愈来愈多地将注意力转移到用户体验上,商户开始意识到完美、愉快的用户体验的重要性,结果 Web 应用程序变得愈来愈重,并具备更动态交互的 UI。这一切都须要更复杂的动画,以便用户在整个过程当中更平稳地进行状态转换。今天,这甚至不被认为是什么特别的事情。用户正变得愈来愈挑剔,默认状况下,他们指望的是具备高响应性和交互性的用户界面。java
然而,界面的动画化并不必定是简单的。什么是动画,何时该用动画,动画应该有什么样的视频效果,这些都是棘手的问题。git
建立 Web 动画的两种主要方法是使用JavaScript和 CSS。选择哪一种没有对或错,这彻底取决于你想要达到的效果。github
用CSS制做动画是让元素在屏幕上移动的最简单方法。web
这里将从如何让元素在 X 和 Y 轴上移动 50px 简单示例开始,经过持续 1 秒的 CSS 过渡来移动元素。编程
.box { -webkit-transform: translate(0, 0); -webkit-transition: -webkit-transform 1000ms; transform: translate(0, 0); transition: transform 1000ms; } .box.move { -webkit-transform: translate(50px, 50px); transform: translate(50px, 50px); }
当元素加上 move
类时,改变 transform
的值而后开发发生过渡效果。小程序
除了转换持续时间外,还有 easing
属性,这实际上就是动画的运动速度方式,该参数会在以后详细介绍。
若是像上面的代码片断同样,建立单独的 CSS 类来实现动画,固然也可使用 JavaScript 来切换每一个动画。
以下元素:
<div class="box"> Sample content. </div>
而后,使用 JavaScript 来切换每一个动画。
var boxElements = document.getElementsByClassName('box'), boxElementsLength = boxElements.length, i; for (i = 0; i < boxElementsLength; i++) { boxElements[i].classList.add('move'); }
上面的代码片断是为全部包含 box
类的元素为其添加 move
类以触发动画。
这样作能够为你的应用提供良好的平衡。 你能够专一于使用 JavaScript 管理状态,只需在目标元素上设置适当的类,让浏览器处理动画。 若是沿着这条路线前进,你能够在元素上监听 transitionend
事件,但前提是放弃旧版 Internet Explorer 的支持:
监听 transitionend
触发的事件以下所示:
var boxElement = document.querySelector('.box'); boxElement.addEventListener('transitionend', onTransitionEnd, false); function onTransitionEnd() { // Handle the transition finishing. }
除了使用 CSS 过渡以外,你还可使用 CSS 动画,CSS 动画可让你更好地控制单独的动画关键帧,持续时间以及循环次数。
关键帧用于指示浏览器 CSS 属性在给定时间点上应有的 CSS 属性,而后填充空白。
来个简单的例子:
.box { /* 动画的名字 */ animation-name: movingBox; /* 动画的持续时间 */ animation-duration: 2300ms; /* 动画的运行次数 */ animation-iteration-count: infinite; /* 设置对象动画在循环中是否反向运动的方法 */ animation-direction: alternate; } @keyframes movingBox { 0% { transform: translate(0, 0); opacity: 0.4; } 25% { opacity: 0.9; } 50% { transform: translate(150px, 200px); opacity: 0.2; } 100% { transform: translate(40px, 30px); opacity: 0.8; } }
效果示例: https://sessionstack.github.i...
使用CSS动画,你能够独立于目标元素定义动画自己,并使用 animation-name 属性来选择所需的动画。
CSS 动画在某种程度仍然须要加浏览器前缀的,在 Safari、Safari Mobile 和 Android 中都使用了 -webkit。 Chrome、 Opera、Internet Explorer 和 Firefox 都不须要添加前缀。许多工具能够帮助你建立所需 CSS 的前缀,这样就不须要在源文件中带样式前缀。
和 CSS 过渡或者 CSS 动画相比,使用 JavaScript 建立动画更加复杂,但它一般为开发人员提供了更强大的功能。
JavaScript 动画是做为代码的一部份内联编写的。你还能够将它们封装在其余对象中。如下为用 JavaScript 来实现最开始的 CSS 过渡的代码:
var boxElement = document.querySelector('.box'); var animation = boxElement.animate([ {transform: 'translate(0)'}, {transform: 'translate(150px, 200px)'} ]) animation.addEventListener('finish', function() { boxElement.style.transform = 'translate(150px, 200px)'; })
默认状况下,Web 动画仅修改元素的展现效果。 若是要将对象停留在移动后的位置,则应在动画完成时修改其基础样式。 这就是为何在上面的例子中监听 finish
事件,并将 box.style.transform
属性设置为 translate(150px, 200px)
,该属性值和 CSS 动画执行的第二个样式转换是同样的。
使用 JavaScript 动画,你能够在每一步彻底控制元素的样式。 这意味着你能够放慢动画速度,暂停动画,中止它们,翻转它们,并根据须要操纵元素。 若是你正在构建复杂的面向对象的应用程序,这尤为有用,由于你能够正确地封装你想要的动画行为。
代码部署后可能存在的BUG无法实时知道,过后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给你们推荐一个好用的BUG监控工具Fundebug。
天然过渡效果会让你的用户对你的 Web 应用程序感受更舒服,从而带来更好的用户体验。
固然,没有任何东西从一个点到另外一个点线性移动。 实际上,当事物在咱们周围的物理世界中移动时,事物每每会加速或减速,由于咱们不是在真空中,而且有不一样的因素会影响这一点。 人类的大脑会指望感觉这样的移动,因此当为网络应用制做动画的时候,利用此类知识会对本身会有好处。
如下是一些术语须要了解一下:
CSS 过渡和动画容许你选择要使用的 easing
类型。 不一样的关键字会影响动画的 easing
,你也能够彻底自定义 easing
方法。
如下为能够选择用来控制 easing
的 CSS 关键字:
让咱们深刻来了解一下这几个兄弟,并看它们各自展现的效果是怎么样。
easing
方法的的默认为 linear,如下为 linear 过渡效果的图示:
随着时间增长,值等比增长,使用 linear 动效,会让动画不天然,通常来讲,避免使用 linear 动效。
如下是如何实现简单的线性动画:
transition: transform 500ms linear;
如前所述,与线性动画相比,easing out
动画开始时快,结束时候间慢,过渡效果的图示以下:
通常来讲,easing out
过渡效果是最适合作界面体验的,由于快速地启动会给人以快速响应的动画的感受,而结束时让人感受很平滑这得归功于不一致的移动速度。
有不少方法能够实现 ease-out 效果,但最简单的是 CSS 中的 ease-out
关键字:
transition: transform 500ms ease-out;
和 ease-out
动画相反-开始时快,结束时候间慢,过渡效果图以下:
与 ease-out
动画相比, ease-in
可能会让人感到不寻常,因为启动缓慢给人以反应卡顿的感受,所以会产生一种无反应的感受。 动画结束很快也会产生一种奇怪的感受,由于整个动画正在加速,而现实世界中的物体在忽然中止时每每会减速。
和 ease-out
和 linear
动画相似,使用 CSS 关键字来实现 ease-in 动画:
transition: transform 500ms ease-in;
该动画为 ease-in 和 ease-out 的合集,过渡效果图以下:
不要使用太长的动画持续时间,由于它们会让你的 UI 感受没有响应。
用 ease-in-out
CSS 关键字来实现 ease-in-out
动画:
transition: transform 500ms ease-in-out;
你也能够定义本身的 easing
曲线,这能够更好地建立本身想要的动画效果。
实际上, ease-in
,linear
及 ease
关键字映射到预约义 贝塞尔曲线 ,能够在 CSS transitions specification 和 Web Animations specification 中查找更多关于贝塞尔曲线的内容。
Bézier curve(贝塞尔曲线)是应用于二维图形应用程序的数学曲线。 曲线定义:起始点、终止点(也称锚点)、控制点。经过调整控制点,贝塞尔曲线的形状会发生变化。 1962年,法国数学家Pierre Bézier第一个研究了这种矢量绘制曲线的方法,并给出了详细的计算公式,所以按照这样的公式绘制出来的曲线就用他的姓氏来命名,称为贝塞尔曲线。
CSS3 transition-timing-function 属性,其语法以下:
transition-timing-function: linear|ease|ease-in|ease-out|ease-in-out|cubic-bezier(n,n,n,n);
总而言之能够用cubic-bezier(n,n,n,n)的形式来表示所有的属性值,这里就涉及到贝塞尔曲线(Bézier curve)。
让咱们看看贝塞尔曲线的工做原理。 贝塞尔曲线须要四个值,或者更准确地说它须要两对数字。 每对描述立方贝塞尔曲线控制点的 X
和 Y
坐标。贝塞尔曲线的起点有一个坐标 (0, 0)
,结束坐标是 (1, 1)
。 你能够设置两个对号,两个控制点的 X
值必须在 [0,1]
范围内,而且每一个控制点的 Y
值能够超过 [0,1] 限制,尽管规定不清楚多少。
即便每一个控制点的 X
和 Y
值稍有变化,也会获得彻底不一样的曲线。让咱们看两张贝塞尔曲线的图,两张图相近但坐标的控制结点却不一样。
和
如您所见,两张图有很大的不一样, 第一个控制点矢量差为 (0.045,0.183)
矢量差,而第二控制点矢量差为 (-0.427, -0.054)
。
第二条曲线的样式为:
transition: transform 500ms cubic-bezier(0.465, 0.183, 0.153, 0.946);
前两个数字是第一个控制点的 X
和 Y
坐标,后两个数字是第二个控制点的 X
和 Y
坐标。
当你在使用动画的时候,你应该维持 60 帧每秒,不然会影响用户体验。
和世界上的其余事物同样,动画也会有性能的开销。一些属性的动画性能开销相比其它属性要小。例如,为元素的 width
和 height
作动画会更改其几何结构而且可能会形成页面上的其它元素移动或者大小的改变,这个过程称为布局。咱们在以前的一篇文章 中更详细地讨论了布局和渲染。
一般,你应该避免动画触发布局或重绘的属性。 对于大多数现代浏览器,这意味着把动画局限于 opacity
和 transform
属性。
你可使用 will-change 知浏览器你打算更改元素的属性,这容许浏览器在进行更改以前进行最适当的优化。可是,不要过分使用 will-change
,由于这样作会致使浏览器浪费资源,从而致使更多的性能问题。
will-change
用法以下:
.box { will-change: transform, opacity; }
该属性在 Chrome, Firefox,Opera 获得很好的兼容。
transforms
和 opacity
,这时整个 CSS 动画得以在 合成线程 完成(而JS动画则会在 主线程 执行,而后触发合成线程进行下一步操做),在 JS 执行一些昂贵的任务时,主线程繁忙,CSS 动画因为使用了合成线程能够保持流畅transforms
和 opacity
属性值的更改。若是动画只是简单的状态切换,不须要中间过程控制,在这种状况下,css 动画是优选方案。它可让你将动画逻辑放在样式文件里面,而不会让你的页面充斥 Javascript 库。然而若是你在设计很复杂的富客户端界面或者在开发一个有着复杂 UI 状态的 APP。那么你应该使用 js 动画,这样你的动画能够保持高效,而且你的工做流也更可控。因此,在实现一些小的交互动效的时候,就多考虑考虑 CSS 动画。对于一些复杂控制的动画,使用 javascript 比较可靠。
原文: https://blog.sessionstack.com...
Fundebug专一于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了9亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎你们免费试用!