canvas小球动画原理
随着html5发展,canvas标签作为h5革命性的发展标志也越来越流行。canvas标签的强大之处,不仅在于它可以作为一个独立的画布,也可以利用canvas做一些动画而不用导入flash文件。同时,canvas还可以一些游戏、商城商品图片放大器功能等等。
这篇博客先写一些简单动画,同时描述一下原理。
首先,canvas标签不是一个独立的部分,它是要以js代码辅助而成的一个模块,所以js代码对其尤为重要。
body中写入canvas标签:
<canvas id="canvas" width="750" height="500"></canvas>
<input type="button" id="animatebutton" value="animate" /> //控制小球的运动与暂停
直接上js代码:
canvas的js开头都是固定的:
var canvas = document.getElementById('canvas'), cx= canvas.getContext('2d'),
paused = true ,//设置小球加载完成是否暂停,现在加载完成小球不动。
加载三个小球的数据:
discs = [ { x:150, y:250, velocityx:-3.2, //小球横向运动速度 velocityy:3.5, //小球纵向运动速度 radius:25, //小球半径 strokestyle:'gray', //小球填充颜色 }, { x:50, y:150, velocityx:2.2, velocityy:2.5, radius:25, strokestyle:'blue', }, { x:150, y:75, velocityx:1.2, velocityy:1.5, radius:25, strokestyle:'orange', }, ],
定义小球的数量以及找到控制小球暂停的button
numdiscs = discs.length, //小球数量 animatebutton = document.getElementById('animatebutton'); // 小球暂停开始按钮
用canvas画出小球:
function draw(){ var disc = discs[i]; //小球的索引 for(var i=0;i<numdiscs;i++) { disc = discs[i]; cx.save(); cx.beginPath(); cx.arc(disc.x,disc.y,disc.radius,0, Math.PI*2,false); cx.fillStyle=disc.strokestyle; //小球填充色 cx.fill(); cx.restore(); } }
设置碰撞及小球运动函数:
function update(){ var disc = null; for(var i=0;i<numdiscs;i++) { disc = discs[i]; if(disc.x +disc.velocityx+disc.radius > cx.canvas.width || disc.x + disc.velocityx -disc.radius<0) //小球横向撞墙后朝相反方向运动 disc.velocityx = -disc.velocityx; if(disc.y +disc.velocityy+disc.radius > cx.canvas.height || disc.y + disc.velocityy -disc.radius<0) //小球纵向向撞墙后朝相反方向运动 disc.velocityy = -disc.velocityy; disc.x+=disc.velocityx; //每次循环小球横向运动距离 disc.y+=disc.velocityy; //每次循环小球纵向运动距离
} }
设置小球的运动,这是一个循环函数,当按钮点击运动的时候,小球每隔一点时间循环运动,其中
window.requestAnimationFrame()函数是canvas标签中特有的,这个函数可以根据最佳流畅性自动选择循环一次的时间。
function animate(){ if(!paused){ cx.clearRect(0,0,canvas.width,canvas.height); update(); draw(); window.requestAnimationFrame(animate); } }
运行以上函数:
animatebutton.onclick = function (){ paused = paused? false:true; if(paused){ //点击按钮后,按钮文字改变 animatebutton.value = "animate"; } else{ window.requestAnimationFrame(animate); animatebutton.value = "pause"; //点击按钮后,按钮文字改变 } }
代码整合:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input type="button" id="animatebutton" value="animate" /> <canvas id="canvas" width="750" height="500"></canvas> </body> <script type="text/javascript"> var canvas = document.getElementById('canvas'), cx= canvas.getContext('2d'), paused = true , discs = [ { x:150, y:250, velocityx:-3.2, velocityy:3.5, radius:25, strokestyle:'gray', }, { x:50, y:150, velocityx:2.2, velocityy:2.5, radius:25, strokestyle:'blue', }, { x:150, y:75, velocityx:1.2, velocityy:1.5, radius:25, strokestyle:'orange', }, ], numdiscs = discs.length, animatebutton = document.getElementById('animatebutton'); function update(){ var disc = null; for(var i=0;i<numdiscs;i++) { disc = discs[i]; if(disc.x +disc.velocityx+disc.radius > cx.canvas.width || disc.x + disc.velocityx -disc.radius<0) disc.velocityx = -disc.velocityx; if(disc.y +disc.velocityy+disc.radius > cx.canvas.height || disc.y + disc.velocityy -disc.radius<0) disc.velocityy = -disc.velocityy; disc.x+=disc.velocityx; disc.y+=disc.velocityy; } } function draw(){ var disc = discs[i]; for(var i=0;i<numdiscs;i++) { disc = discs[i]; cx.save(); cx.beginPath(); cx.arc(disc.x,disc.y,disc.radius,0, Math.PI*2,false); cx.fillStyle=disc.strokestyle; cx.fill(); //cx.stroke(); cx.restore(); } } function animate(){ if(!paused){ cx.clearRect(0,0,canvas.width,canvas.height); update(); draw(); window.requestAnimationFrame(animate); } } animatebutton.onclick = function (){ paused = paused? false:true; if(paused){ animatebutton.value = "animate"; } else{ window.requestAnimationFrame(animate); animatebutton.value = "pause"; } } </script> </html>
效果:
没有点击运动前:
点击运动后:
小球是一直运动的,点击pause之后,小球运动暂停。