TWaver可视化 2017-09-14
有一种动画书,就是快速翻动就可以看见里面的内容运动起来了。电脑动画和这个差不多,通过在动画区域内用一张新的图片代替旧的图片,并快速持续的改变,根据视觉暂留现象就在我们的大脑中形成了动画。
HTML5里面,我们通过下面的语句来实现画面的更替:
window.requestAnimationFrame()
还是一脸懵逼?我们先用代码把第一段话翻译一下吧:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <meta name="Author" content="sunsi"> <meta name="Keywords" content="webgl,animation"> <meta name="Description" content="webgl tutorial from blog.techcave.cn"> <script type="text/javascript"> <!-- var cv, ctx; function init() { //1. 获取canvas元素 cv = document.getElementById("cv"); //2. 获取2D上下文 ctx = cv.getContext('2d'); //3. 其他的准备初始化工作 //4. 开始我们的动画 window.requestAnimationFrame(animation) } function animation() { //1. 移走前一个画面 removePrevFrame(); //2. 放上一个新画面 newFrame(); //3. 持续的更新 window.requestAnimationFrame(animation) } function removePrevFrame() { //清空画布,比较简单的方法是clearRect ctx.clearRect(0,0,300,300); } function newFrame() { //根据当前的状态载入新的画面 } //--> </script> <title>Document</title> </head> <body onload="init()"> <canvas id="cv" width="600" height="600"></canvas> </body> </html>
首先,我们通过init方法绑定到body的onload事件,实现整个webgl画布和其他的初始化。里面关键第4点,使用 window.requestAnimationFrame语句来实现画面的刷新,该语句有个参数是个回调函数,在该函数中实现刷新逻辑,这里我们编写了animation方法实现。该回调方法通常、大致做几件事情:把冰箱门打开、把原来的大象拿出来,(读者:说人话。作者:请看注释)。好了,言归正传,是不是很简单。根据这个思路,我们把这个代码完善一下,画一根秒针——旋转的金箍棒。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <meta name="Author" content="sunsi"> <meta name="Keywords" content="webgl,animation"> <meta name="Description" content="webgl tutorial from blog.techcave.cn"> <script type="text/javascript"> <!-- var cv, ctx; var lastSeconds; function init() { //1. 获取canvas元素 cv = document.getElementById("cv"); //2. 获取2D上下文 ctx = cv.getContext('2d'); //3. 其他的准备初始化工作 //4. 开始我们的动画 window.requestAnimationFrame(animation) } function animation() { //1. 移走前一个画面 removePrevFrame(); //2. 放上一个新画面 newFrame(); //3. 持续的更新 window.requestAnimationFrame(animation) } function removePrevFrame() { //清空画布,比较简单的方法是clearRect //保存当前状态,每次刷新都以该状态开始 ctx.save(); ctx.clearRect(0, 0, 400, 400); } function newFrame() { //根据当前的状态载入新的画面 var now = new Date(); ctx.translate(200, 200); var sec = now.getSeconds(); //这里保存平移状态,意思原点移动到200,200并保持住 ctx.save(); ctx.rotate(sec * Math.PI / 30); //360 * sec / 60 * Math.PI / 180 ctx.lineWidth = 6; ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(150, 0); ctx.stroke(); //弹出状态栈,要不每个循环都会在上次基础上平移旋转 ctx.restore(); ctx.restore() } //--> </script> <title>Document</title> </head> <body onload="init()"> <canvas id="cv" width="600" height="600"></canvas> </body> </html>
效果如下所示:
原文地址:http://blog.techcave.cn/2017/09/14/WebGL-%E5%8A%A8%E7%94%BB/