先上源码
/* 用于绘制雪花的js文件 */
var canvas = document.querySelector(".canvas");
if(canvas.getContext){
var ctx = canvas.getContext("2d");
}else{
/* 不支持canvas */console.log("no support");
}
var snow_img = new Image();
var snows = [];//储存所有的雪花对象
const snows_num = 50;//雪花数量的常量
const swingY = 50;//摇摆幅度,决定在y轴上的摇摆幅度
const swingX = 150;//摇摆幅度,决定在x轴上的摇摆幅度
const speed = 1;//左右周期速度
const fallSpeed = 1;//下坠速度
snow_img.onload = function(){
ctx.drawImage(snow_img,0,0,20,20);
}
snow_img.src= "img/snow.png";
function makeSnow(snow)//构造雪花的方法,并且这个方法可以重构雪花对象
{
if(snow != undefined){
snow.x = rnum(0,1600);
snow.y = 0;
snow.size = rnum(5,10)/10;
snow.per = rnum(0,100);
return;
}
/* 位置和大小,大小是倍数 */
var ret = {
x:0,y:0,
size:1,
dir:true,//动画行进的方向,true为正,false为反
per:0,//动画的进度,0~100
};
ret.x = rnum(0,1600);
ret.y = rnum(0,900);
ret.size = rnum(5,10)/10;
ret.per = rnum(0,100);
return ret;
}
function rnum(start,end)//生成随机数的方法
{ /* 包含开头,不包含结尾 */
return start + Math.floor(Math.random()*(end-start));
}
function update(){
ctx.clearRect(0,0,1600,900);
for(snow of snows){
snow.y += fallSpeed;
if(snow.y >= 900){
makeSnow(snow);
}
snow.per += speed;
if(snow.per>100){
snow.per -= 100;
snow.dir = !snow.dir;
}
//因为雪花是往返下降,所以需要计算实际进度
realPer = (snow.dir ? snow.per : 100 - snow.per)/100;
ctx.drawImage(snow_img,snow.x + snow.size*(realPer - 0.5)*swingX
,snow.y - swingY*Math.pow(realPer,2) + swingY*realPer,
40*snow.size,40*snow.size);
}
}
function init()//初始化方法
{
for(var i = 0;i < snows_num;i++){
snows.push(makeSnow());
}
}
init();
setInterval(update,10);
首先,先介绍一下canvas。canvas是HTML5新加入的特性,通过document的方法获取到其元素对象后,可以使用专有方法来获取绘制的对象。专有方法指的是getContext。通过getContext("2d")来获取一个绘制对象。
在此段代码开头用canvas.getContext来检测是否含有这个方法,从而确定浏览器是否支持canvas。
获取到绘制对象后,其中提供了很多绘制的方法,此处仅讲解drawIamge这个主要使用的方法。
drawIamge至少需要3个参数,分别是绘制的Iamge对象,以及xy轴上的位置。
还有一种5个参数的方法,后面跟的是图片的宽高,绘制出的图片会被强制缩放成这两个值
想要创建Iamge对象很简单,只需要new Iamge()
之后对其src属性进行赋值,将图片的地址传入即可。
注意!
1.图片的装载是需要时间的,如果你在图片装载完成前对其使用,可能会什么也不发生,甚至报错。所以一般对Iamge对象的onload
属性传入一个方法,当Iamge装载完成后,会调用此方法。
2.画布的默认大小是300x150像素,如果仅对css属性进行修改,虽然的确可以改变其大小,但是实际上是将canvas进行放大得到的(所以实际上canvas与img是很相似的,甚至可以理解为可以自由绘制的img)所以要直接设定其宽高属性来决定canvas的实际宽高(通过对标签上的属性进行修改,例如<canvas height='200' width='200'>
)
现在来介绍绘制相关的内容。首先,canvas的背景是透明的,你把这个元素放在其他元素之上,是不会遮盖底下的元素的(除非你绘制了背景,也就是填充了一个带有颜色的图形)。绘制的话直接使用drawIamge等其提供的方法即可。
在画布上绘制完图形后,画布的上的内容是不会自动消除的,需要使用clearRect
方法主动清除才行。这个方法接收4个参数,分别是开始清除的点的xy轴,以及结束点的xy轴。清除后的画布就会变成透明的。
了解完以上内容基本就可以实现简单的下雪效果了。但是先要实现飘落的效果,还有更多需要考虑的,我就不多讲了,提示一下:二次函数。
最后再说一点,如果把画布放在元素上面,但是你不想让画布阻挡鼠标事件,可以使用一个css属性:pointer-events:none。可以让指定元素不接收鼠标事件。
网友评论