javascript动画基础(四)--三角学在动画中的运用(3)

前面已经简单介绍了Math.sin,Math.cos和Math.atan2这三个用的最多的三角函数javascript方法,接下来,我们看看sin和cos的取值范围


上面的图很清楚的可以看出,不过不看我相信大家也知道,sin和cos的取值范围在-1和1之间,所以根据上图才有了正弦波和余弦波的说法。

根据正弦和余弦取值范围的这个特性,我们就可以做出很多动画效果,比如呼吸灯的效果,平滑上下运动,心跳效果(脉冲运动),甚至是不规则的运动轨迹都可以,首先来看看简单的平滑上下运动的效果

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style>
		canvas{
			border: 1px solid #ccc;
		}
	</style>
</head>
<body>
	<canvas id="myCanvas" width=500 height=500></canvas>
</body>
<script>
window.onload = function(){
	var myCanvas = document.getElementById('myCanvas');
	var ctx = myCanvas.getContext('2d');
	<span style="color:#ff0000;">var angleSpeed = 0;</span>
	var x = myCanvas.width/2;
	var y = myCanvas.height/2;
	//平滑上下移动的方块
	(function jump(){
		setTimeout(jump,1000/60);
		ctx.clearRect(0,0,myCanvas.width,myCanvas.height);
		//改变y的值,y值其实在250+50*[-1,1]之间变动,50其实就是波动范围
		y = myCanvas.height/2 + <span style="color:#ff0000;">Math.sin(angleSpeed)*50</span>;
		ctx.save()
		ctx.translate(x,y);
		ctx.beginPath();
		ctx.fillStyle = "red";
		ctx.fillRect(0,0,50,50);
		ctx.fill();
		ctx.restore();
		angleSpeed += 0.1;
	}());
}
</script>
</html>
运行上面的代码,可以看到一个红色的小方块在画布中平滑上下运动。

代码用到了canvas画布的矩阵变换translate(x,y)函数,这里有必须稍微说明一下:

方法 描述
scale(x,y) 缩放当前绘图至更大或更小
rotate(弧度) 旋转当前绘图
translate(x,y) 重新映射画布上的 (0,0) 位置
transform() 替换绘图的当前转换矩阵
setTransform() 将当前转换重置为单位矩阵。然后运行 transform()

具体的用法大家可以自己实验,不要需要说明一下这个几个矩阵变换API在使用的时候的注意事项

1.  变换方法是对下一次绘图起作用

2.  变换方法变换的整个画布,而不是哪一个图形,所以经常需要配合save()和restore()方法一起使用,这一点很重要

3.  需要注意使用clearRect()方法清除画布

4.  transform方法一共六个参数,1,4参数表示缩放,也就是scale ; 2,3参数表示斜拉skew,这个canvas没有提供单独方法,单独实际情况可以参考css3矩阵变换的skew;5,6参数表示位移,也就是translate;1,2,3,4参数按照cos,sin,-sin,cos 顺序就是旋转,也就是rotate

具体的API使用情况这里就不多做介绍,不过一定要注意第二点,矩阵变换方法变换的是整个画布

ok,上面的注意点如果你知道了,那么,直接跳过


上面的代码只是在y轴做上下的平滑运动,那么再上个列子,来看一下脉冲运动

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>pulse</title>
	<style>
		canvas{
			border: 1px solid #ccc;
		}
	</style>
</head>
<body>
	<canvas id="myCanvas" width=500 height=500></canvas>
</body>
<script>
window.onload = function(){
	var myCanvas = document.getElementById('myCanvas');
	var ctx = myCanvas.getContext('2d');
	var range = 0.5;	//脉冲范围
	var angleSpeed = 0; //角度变化速度
	var raduis = 100; //半径
	//默认缩放大小,这个参数其实是为了让scale(x,y)里面的参数不变为负数
	var centerScale = 1; 
	var x = myCanvas.width/2;
	var y = myCanvas.height/2;
	//脉冲运动
	(function pulse(){
		setTimeout(pulse,1000/60);
		ctx.clearRect(0,0,myCanvas.width,myCanvas.height);
		ctx.save()
		ctx.translate(x,y);
		//注意sin和cos的区别,这里使用sin从小变大,如果你想从大变小,使用cos
		//Math.sin(angleSpeed)*range 其实变动范围就在[-0.5,0.5]之间了
		ctx.scale(centerScale + Math.sin(angleSpeed)*range,centerScale + Math.sin(angleSpeed)*range);
		ctx.beginPath();
		ctx.fillStyle = "#99CCFF";
		ctx.arc(0,0,raduis,0,2*Math.PI,false);
		ctx.fill();
		ctx.restore();
		angleSpeed += 0.02;
	}());
}
</script>
</html>

上面代码使用scale()方法,实现了圆的放大变小,但是还是要提醒大家,scale缩放实际上缩放的是画布,是以画布左上的点作为缩放的源点,所以上面代码中ctx.translate(x,y)这一句并不只是简单的把画布移动到中间,还会让scale的缩放依据自身的圆点来做放大缩小

再来看一个随机波动的效果,这个效果就像一只小鸟在画布上飞来飞去。

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>RandomWave</title>
	<style>
		canvas{
			border: 1px dashed #ccc;
			background-color: #eee;
		}
	</style>
</head>
<body>
	<canvas id="myCanvas" width=500 height=500></canvas>
</body>
<script>
window.onload = function(){
	var myCanvas = document.getElementById('myCanvas');
	var ctx = myCanvas.getContext('2d');
	var range = 50;	//脉冲范围
	var angleSpeedX = 0; //x角度变化速度
	var angleSpeedY = 0; //y角度变化速度
	var raduis = 50; //半径	
	var originX = myCanvas.width/2; 
	var originY = myCanvas.height/2;
	var x = 0;
	var y = 0;
	//不规则波形运动
	(function randomWave(){
		setTimeout(randomWave,1000/60);
		ctx.clearRect(0,0,myCanvas.width,myCanvas.height);

		x = originX + Math.sin(angleSpeedX) * range;
		y = originY + Math.sin(angleSpeedY) * range;

		ctx.save();
		ctx.translate(x,y);
		ctx.beginPath();
		ctx.fillStyle = "#FF9966";
		ctx.arc(0,0,raduis,0,2*Math.PI,false);
		ctx.fill();
		ctx.restore();
		angleSpeedX += 0.05;
		angleSpeedY += 0.15;
	}());
}
</script>
</html>

虽然叫做随机波动,其实通过数学原理还是可以预测出它的飞行轨迹的,只是看起来好像随机而已,因为上面代码中变化的角度,angleSpeedX,和angleSpeedY都不一样,而且变动使用的都是sin进行变化,但是如果你想想,angleSpeedX,和angleSpeedY变化一样,并且x,y的变化一个使用cos,一个使用sin

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>circleWave</title>
	<style>
		canvas{
			border: 1px dashed #ccc;
			background-color: #eee;
		}
	</style>
</head>
<body>
	<canvas id="myCanvas" width=500 height=500></canvas>
</body>
<script>
window.onload = function(){
	var myCanvas = document.getElementById('myCanvas');
	var ctx = myCanvas.getContext('2d');
	var range = 50;	//脉冲范围
	var angleSpeedX = 0; //x角度变化速度
	var angleSpeedY = 0; //y角度变化速度
	var raduis = 50; //半径	
	var originX = myCanvas.width/2; 
	var originY = myCanvas.height/2;
	var x = 0;
	var y = 0;
	//圆形轨迹移动
	(function circleWave(){
		setTimeout(circleWave,1000/60);
		ctx.clearRect(0,0,myCanvas.width,myCanvas.height);

		x = originX + Math.cos(angleSpeedX) * range;
		y = originY + Math.sin(angleSpeedY) * range;

		ctx.save();
		ctx.translate(x,y);
		ctx.beginPath();
		ctx.fillStyle = "#FF99CC";
		ctx.arc(0,0,raduis,0,2*Math.PI,false);
		ctx.fill();
		ctx.restore();
		angleSpeedX += 0.05;
		angleSpeedY += 0.05;
	}());
}
</script>
</html>

如果上面的代码把originX和originY改成不一样的长度,那么你会发现会出现椭圆轨迹的运动的小圆球

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值