1、概述:
以任意图片作为背景,在背景上添加雪花下落的特效效果,此处使用随机颜色、随机大小的彩色雪花实现。
2、效果实现功能:
(1)雪花随机出现并随机消失;
(2)雪花出现时大小随机;
(3)雪花颜色随机;
(4)雪花颜色逐渐变淡并消失;
(5)雪花消失后删除其对象,减轻系统负担。
3、实现原理:
采用<canvas></canvas>画布标签实现,在画布上完成背景图片的添加,使用对象创建出雪花的模型,在定义的画布上用画笔功能,根据雪花对象构建的模板画出所需数量的雪花,并将画出的雪花的透明度和分别递减和递增,任意雪花透明度为小于0时,再随机位置创建出新的雪花。
4、完整实现代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>屏幕雪花效果练习</title>
<style type="text/css">
*{margin:0;padding:0;}
canvas{background: url(images/snow.jpg) no-repeat;background-size: 100% 100%;overflow: hidden;}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript">
/**
* 定义<canvas>画布;
* @type {[type]}
*/
var width=window.innerWidth;//获取系统显示宽度;
var height=window.innerHeight;//获取系统显示高度;
var canvas=document.querySelector("#canvas");
var context=canvas.getContext("2d");
var snowArray=[];//声明一个数组,用于存放创建出来的雪花对象;
canvas.width=width;//设置画布的宽度为系统显示宽度;
canvas.height=height;//设置画布的高度为系统显示高度;
cartoon(); //调用动画;
/**
* 定义雪花类;
*/
class Snowflake{
constructor(){
this.init();//构造函数,调用定义好的init()方法;
}
init(){
this.position={ //雪花对象的位置;
x:Math.random()*width,//x坐标随机;
y:Math.random()*height,//y坐标随机;
}
this.speed=Math.random()*10;//雪花下落速度为0-10以内的随机数;
this.r=Math.random()*6;//雪花的半径为0-6以内的随机数;
this.transparency=Math.random();//设置雪花的透明度为随机;
this.color={
r1:Math.random()*255,//雪花颜色随机;
g:Math.random()*255,
b:Math.random()*255,
}
}
draw(){//雪花绘制方法;
this.position.y++;//y坐标每次递增1像素;
this.transparency-=0.01;//透明度每次递减0.01;
if(this.transparency<=0){//透明度小于0,即雪花消失,重新绘制雪花;
this.init();
}
context.beginPath();//开始一个新的图形绘制;
context.fillStyle="rgba("+this.color.r1+","+this.color.g+","+this.color.b+","+this.transparency+")";//根据类模型绘制圆形雪花;
context.arc(this.position.x,this.position.y,this.r,0,Math.PI*2);//填充雪花的颜色;
context.fill();
}
}
for(var i=0;i<1000;i++){
var snow=new Snowflake();//实例化1000个雪花对象;
snowArray.push(snow);//将雪花对象添加到数组中;
}
// var length=snowArray.length;
/**
* 定义动画效果;
* @return {[type]} [description]
*/
function cartoon(){
context.clearRect(0,0,width,height);//动画完成一次进行清屏操作;
for(var j=0;j<snowArray.length;j++){
snowArray[j].draw();//将实例化好的每个雪花对象在画布上画出来;
}
requestAnimationFrame(cartoon);//递归调用动画效果;
}
</script>
</body>
</html>
5、注意事项:
动画效果定义完成后必须在js代码块中进行调用,这里的动画使用了requestAnimationFrame(cartoon);方法来递归反复调用动画,不需要设置定时器即可随时刷新,该方法比定时器 setTimeout/setInterval的优势在于,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,减轻CPU压力。