写之前:不当之处还请指正,欢迎留言探讨~
html页面动画的实现方式:
1、canvas 着重于图像处理,弱于交互效果,所以动画只能借由定时器或requestAnimationFrame不停的重绘来实现
2、svg 以Html标签为基础,标签改变时即时渲染
3、transition 可控制元素的css属性值(如left、top等)在一定时间内平滑过渡,即简单动画
4、transform 控制元素的变形,如旋转、伸缩等,是静态的变化,如果想以动画的形式看到变化需配合transition或animation。该属性可触发gpu加速
5、animation css3的动画实现属性
6、Js定时器或requestAnimationFrame控制元素的属性,如left、top等以实现动画
下述示例公用样式:
1 .tt { 2 width: 200px; 3 height: 200px; 4 background: red; 5 z-index: 100; 6 position: absolute; 7 }
上述几种方式在页面上的表现:
1、Js定时器和requestAnimationFrame
动画效果:平行移动。
问题:当主线程、渲染线程被占用16ms(1秒60帧的动画为流畅动画,所以每帧的间隔大约是16ms)以上时,会出现卡顿的现象;当主线程、渲染线程被占用时,出现计时执行间隔不准确的问题
描述及解决办法:可以使用多线程,如Worker来准确的计时,但不能解决卡顿的问题
示例代码Html:
<div onclick="toggleFloatPanel()" id="leftView" style="width:353px;background:green;height:500px;position:absolute;"> 点我用定时器平行移动</div>
示例代码Js:
1 function toggleFloatPanel() { 2 var panelState = 1; //1 展开 0 折叠 3 var left = 0; 4 var leftPanel = document.getElementById("leftView"); 5 var originalLeft = 40; 6 var originalRight = 40; 7 var min = -352; 8 var leftState = true; 9 timeOutFn(); 10 11 function timeOutFn() { 12 // setTimeout(function () { 13 // setLeft(); 14 // timeOutFn(); 15 // }, 16); 16 setLeft(); 17 requestAnimationFrame(timeOutFn); 18 } 19 20 function setLeft() { 21 panelState == 1 22 ? (left = left - 10) 23 : (left = left + 10); 24 left <= min 25 ? (panelState = 0) 26 : left >= originalLeft 27 ? (panelState = 1) 28 : ""; 29 leftPanel.style.left = left + "px"; 30 } 31 32 }
2、canvas
动画效果:平行移动。
问题:同Js定时器
原因:因为canvas的动画借助于定时器或requestAnimationFrame不停的重绘来实现,所以见第1关于定时器和requestAnimationFrame的说明
示例代码Html:
1 <div id="divTransitionCanvasTest" class="tt" 2 style=" margin: 0 0px 0px 59%;background:none;width:600px;border:solid 1px red;" onclick="canvasChange()"> 3 <div style="position: absolute;color:yellow;">点击观看canvas移动</div> 4 <canvas id="canvas" height="200" width="600"></canvas> 5 </div>
示例代码Js:
1 var canvasX = 0; 2 var canvasColor = 'green'; 3 var liner = 1; //1 向右 0向左 4 var leftChange = 10; 5 function canvasRoate() { 6 var oCanvas = document.getElementById("canvas"); 7 var context = oCanvas.getContext("2d"); 8 context.fillStyle = canvasColor; 9 context.fillRect(canvasX, 0, 200, 200); 10 } 11 function canvasChange() { 12 var oCanvas = document.getElementById("canvas"); 13 var context = oCanvas.getContext("2d"); 14 context.clearRect(canvasX, 0, 200, 200); 15 liner == 1 ? canvasX += leftChange : canvasX -= leftChange; 16 liner == 1 && canvasX > 400 ? (liner = 0, canvasX = 400 - leftChange) : liner == 0 && canvasX < 0 ? (liner = 1, canvasX = leftChange) : ''; 17 context.fillStyle = canvasColor; 18 context.fillRect(canvasX, 0, 200, 200); 19 setTimeout(function () { 20 canvasChange(); 21 }, 16); 22 23 // var worker = new Worker("./toggleWork.js"); 24 // worker.onmessage = function (event) { 25 // var _obj = event.data; 26 // var oCanvas = document.getElementById("canvas"); 27 // // var webglContext = oCanvas.getContext("webgl"); 28 // // console.log(webglContext); 29 // var context = oCanvas.getContext("2d"); 30 // context.clearRect(_obj.oldCanvasX, 0, 200, 200); 31 // context.fillStyle = canvasColor; 32 // context.fillRect(_obj.newCanvasX, 0, 200, 200); 33 // }; 34 }
3、svg
动画效果:无限旋转。
问题:在主线程或渲染线程被其他操作占用16ms以上时出现卡顿,其他时候运行流畅
原因:svg的动画会持续性的引起页面的重绘,然后调用渲染线程重新渲染。当页面的主线程或者渲染线程被占用时,造成svg动画卡顿
示例代码Html:
1 <div id="divSvgContainer" style="margin:0 0 0 20%;background:none;position:absolute;z-index:100;"> 2 <svg xmlns="http://www.w3.org/2000/svg"> 3 <g> 4 <rect x="0" y="0" width="200" height="200" fill="yellow" stroke="red" stroke-width="1" transform="rotation"> 5 <animateTransform attributeType="XML" attributeName="transform" begin="0s" dur="5s" type="rotate3d" 6 from="0 100 100" to="360 100 100" repeatCount="indefinite" /> 7 </rect> 8 <text x="0" y="15" fill="red">svg无限旋转</text> 9 </g> 10 </svg> 11 </div>
4、transition和transform
动画效果:旋转一周。
问题:动画开始前和结束后,此时若主线程或渲染线程被其他操作占用则现卡顿,动画运行过程中不会卡顿
原因:同第5 animation 的描述
示例代码Html:
1 <div id="divTransitionTest" class="tt" style=" margin: 0 0px 0px 33%;">悬浮时使用transition和transform旋转一周</div>
示例代码Css:
1 /**悬浮时旋转一周start 使用transition */ 2 #divTransitionTest:hover { 3 -webkit-transform: rotate(360deg); 4 transform: rotate(360deg); 5 -webkit-transition: -webkit-transform 3s linear; 6 transition: transform 3s linear; 7 } 8 9 /**悬浮时旋转一周end 使用transition */
5、animation和transform
动画效果:无限旋转。
问题:同4。
原因:动画即将开始前和结束后各触发一次页面的重绘,所以在重绘时,如果主线程或者渲染线程被占用,则会卡顿,但在动画运行期间内不会卡顿。
示例代码Html:
1 <div id="divTransitionAniTest" class="tt" style=" margin: 0 0px 0px 46%;">悬浮时使用animation和transform无限旋转</div>
示例代码Css:
1 /**悬浮时无限旋转start 使用transition和animation */ 2 #divTransitionAniTest:hover { 3 -webkit-animation: spin 2s linear infinite; 4 animation: spin 2s linear infinite; 5 6 } 7 8 @-webkit-keyframes spin { 9 from { 10 -webkit-transform: rotate(0deg); 11 } 12 13 to { 14 -webkit-transform: rotate(360deg); 15 } 16 } 17 18 @keyframes spin { 19 from { 20 transform: rotate(0deg); 21 } 22 23 to { 24 transform: rotate(360deg); 25 } 26 } 27 28 /**悬浮时无限旋转end 使用transition和animation */
6、transition
动画效果:平行移动
问题:在主线程或渲染线程被其他操作占用16ms以上时出现卡顿,其他时候运行流畅。
原因:transition在过渡元素属性的过程中,会持续性的引起重绘,如果主线程或者渲染线程被占用超过16ms,则会卡顿
示例代码Html:
1 <div id="divTransition" class="tt" style="margin: 12% 0px 0px 46%;" 2 onclick="$('#divTransition').addClass('divTransition_run');">使用transition平行移動</div>
示例代码Css:
1 /**悬浮时平行移动start 使用transition */ 2 .divTransition_run { 3 margin-left: 80% !important; 4 transition: left 2000ms linear 1ms; 5 -webkit-transition: margin-left 3000ms linear 1ms; 6 -moz-transition: left 2000ms linear 1ms; 7 -o-transition: left 2000ms linear 1ms; 8 9 } 10 11 /**悬浮时平行移动end 使用transition */
浙公网安备 33010602011771号