复杂下雨特效
上次的下雨效果比较简单,这个要复杂很多
对比:通过单个雨滴的位移达到下雨效果,上次是随机产生,然后刷新出来的,雨滴本身没有动
雨滴碰到鼠标和地面会溅射
鼠标能控制雨的速度和方向

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>rain</title>
</head>
<body>
<canvas id="canvas" style="position: absolute; height: 100%; width:100%;"></canvas>
<script>
window.onload=main;
function getRgb(r,g,b){
return "rgb("+ r+","+g+","+b+")";
}
function main(){
//drop来存放溅射的雨滴
var dropList=[];
//重力因素,保持溅射的雨滴不会飞远
var gravity=0.8;
//保存雨滴
var linelist=[];
var canvasEl = document.getElementById('canvas');
var ctx = canvasEl.getContext('2d');
//鼠标的开始点为
var mousePos = [0, 0];
var backgroundColor = '#000';
canvasEl.width=canvasEl.clientWidth;
canvasEl.height=canvasEl.clientHeight;
var speedx=0;
var maxspeedx=0;
//当改变浏览器窗口大小时
window.onresize=function () {
canvasEl.width=canvasEl.clientWidth;
canvasEl.height=canvasEl.clientHeight;
}
//当鼠标移动时,获取坐标
window.onmousemove=function (e) {
mousePos[0]=e.clientX;
mousePos[1]=e.clientY;
//最大速度-1到1个屏幕
maxspeedx=(e.clientX-canvasEl.clientWidth/2)/(canvasEl.clientWidth/2);
}
//给单个雨滴加属性
function createLine(e){
//长度在12.5-37.5之间
var temp= 0.25*( 50+Math.random()*100);
//速度在16.5-50.5之间
var myline={
speed:5.5*(Math.random()*6+3),
die:false,
posx:e,
posy:-200,
h:temp,
//颜色在
color:(getRgb(Math.floor(temp*255/75),Math.floor(temp*255/75),Math.floor(temp*255/75)))
};
//添加到数组中
linelist.push(myline);
}
update();
//生产小雨滴
function createDrop(x,y){
var mydrop={
die:false,
//溅射x坐标
posx:x,
//溅射的y坐标
posy:y,
//随机生成一个x轴速度
vx:(Math.random()-0.5)*8,
//随机生成一个y轴速度
vy:Math.random()*(-6)-3,
radius:Math.random()*1.5+1
};
return mydrop;
}
//溅射效果
function madedrops(x,y){
//溅射的雨滴数为5-10滴
var maxi=Math.floor(Math.random()*5+5);
for(var i=0;i<maxi;i++){
dropList.push(createDrop(x,y));
}
}
function update() {
//循环遍历小雨滴,显示溅射的雨滴,移除超出范围的雨滴
if(dropList.length>0){
dropList.forEach(function (e) {
//小雨滴的x轴速度=随机速度+雨滴初始速度
e.vx=e.vx+(speedx)/2;
//小雨滴的新坐标
e.posx=e.posx+e.vx;
//小雨滴的y轴速度=随机速度+重力
e.vy=e.vy+gravity;
e.posy=e.posy+e.vy;
//雨滴超出屏幕高度,则消失
if(e.posy>canvasEl.clientHeight){
e.die=true;
}
});
}
//移除超出范围的雨滴
for(var i=dropList.length-1;i>=0;i--){
if(dropList[i].die){
dropList.splice(i,1);
}
}
//鼠标的位置控制雨的速度
//当鼠标在中间maxspeedx为0,不倾斜,速度不加快
speedx=speedx+(maxspeedx-speedx)/50;
if(Math.random()>0){
//雨滴的出生点的X轴坐标在-0.5到1.5倍的屏幕,这样雨滴倾斜的时候,最角落也会有雨滴
createLine(Math.random()*1.5*canvasEl.width -Math.random()*0.5*canvasEl.width);
createLine(Math.random()*1.5*canvasEl.width -Math.random()*0.5*canvasEl.width);
createLine(Math.random()*1.5*canvasEl.width -Math.random()*0.5*canvasEl.width);
}
//雨滴到达近地面时,近地面(1到0.8的屏幕高度)
var mydeadline=canvasEl.clientHeight- Math.random()*canvasEl.clientHeight/5;
//监听雨滴,雨滴距离鼠标的直线距离小于35时,两点之间的距离公式
linelist.forEach(function (e) {
//雨滴距离鼠标的直线距离小于35时,两点之间的距离公式
var dis=Math.sqrt( ((e.posx+speedx*e.h)-mousePos[0])*((e.posx+speedx*e.h)-mousePos[0])+(e.posy+e.h-mousePos[1])*(e.posy+e.h-mousePos[1]));
if(dis<35){
//雨滴消失,产生小雨滴
madedrops(e.posx+speedx*e.h,e.posy+e.h);
e.die=true;
}
//当雨滴到达地面时,每个雨滴的地面不同,0.8到1个屏幕高度
//如果每个
if((e.posy+e.h)>mydeadline){
//每个雨滴都出水花太多了。给个0.9的概率
if(Math.random() > 0.9){
madedrops(e.posx+speedx*e.h,e.posy+e.h);
e.die=true;
}
}
//水滴超出屏幕高度,设置为消失
if(e.posy>=canvasEl.clientHeight){
e.die=true;
}else{
e.posy=e.posy+e.speed;
e.posx=e.posx+(e.speed*speedx);
}
});
//消失雨滴
for(var i=linelist.length-1;i>=0;i--){
if(linelist[i].die){
linelist.splice(i,1);
}
}
//清除界面
render();
//重绘页面
window.requestAnimationFrame(update);
}
function render() {
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, canvasEl.width, canvasEl.height);
linelist.forEach(
//绘制雨滴
function (line) {
ctx.strokeStyle =line.color;
ctx.lineWidth=4.5;
ctx.beginPath();
ctx.moveTo(line.posx,line.posy);
ctx.lineTo(line.posx+speedx*line.h,line.posy+line.h);
ctx.stroke();
});
ctx.lineWidth=1;
ctx.strokeStyle = "#fff";
//绘制溅射雨滴
dropList.forEach(function (e) {
ctx.beginPath();
ctx.arc(e.posx,e.posy,e.radius,Math.random()*Math.PI*2,1*Math.PI);
ctx.stroke();
});
}
}
</script>
</body>
</html>

浙公网安备 33010602011771号