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之后,小球运动暂停。

原文地址:https://www.cnblogs.com/cyrfr/p/6520113.html