##概述相關免費學習推薦:javascript#(影片)
.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 屬性,這實際上就是動畫的運動速度方式,該參數會在之後詳細介紹。
p class="box"> Sample content.
var boxElements = document.getElementsByClassName('box'), boxElementsLength = boxElements.length, i; for (i = 0; i 上面的程式碼片段是為所有包含 <p>box<code> 類別的元素為其添加 </code>move<code> 類別以觸發動畫。 </code></p>這樣做可以為你的應用提供良好的平衡。你可以專注於使用 JavaScript 管理狀態,只需在目標元素上設定適當的類,讓瀏覽器處理動畫。如果沿著這條路線前進,你可以在元素上監聽<p>transitionend<code> 事件,但前提是放棄舊版Internet Explorer 的支援:</code></p><p><img src="https://img.php.cn/upload/image/590/600/983/1607592778931586.png" title="1607592778931586.png" alt="詳解CSS和JS動畫底層原理及如何優化它們的性能">##監聽</p>transitionend<p> 觸發的事件如下所示:<code><pre class="brush:php;toolbar:false">var boxElement = document.querySelector('.box'); boxElement.addEventListener('transitionend', onTransitionEnd, false); function onTransitionEnd() { // Handle the transition finishing. }
關鍵影格用於指示瀏覽器 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 的前綴,這樣就不需要在原始檔中帶樣式前綴。
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 動畫,你可以在每一步完全控制元素的樣式。這意味著你可以放慢動畫速度,暫停動畫,停止它們,翻轉它們,並根據需要操縱元素。如果你正在建立複雜的物件導向的應用程序,這尤其有用,因為你可以正確地封裝你想要的動畫行為。
Easing 定義
当然,没有任何东西从一个点到另一个点线性移动。 实际上,当事物在我们周围的物理世界中移动时,事物往往会加速或减速,因为我们不是在真空中,并且有不同的因素会影响这一点。 人类的大脑会期望感受这样的移动,所以当为网络应用制作动画的时候,利用此类知识会对自己会有好处。
以下是一些术语需要了解一下:
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 比较可靠。
以上是詳解CSS和JS動畫底層原理及如何優化它們的性能的詳細內容。更多資訊請關注PHP中文網其他相關文章!