思路
将雪花看成一个个对象,有x轴和y轴的速度,有不同的缩放比例和不同的旋转角度和旋转速度。使用一个for循环和定时器生成一定数量的雪花对象,然后根据速度进行运动。考虑画板的宽和高,运用模运算使这些对象一直在画板中。
步骤:
1. 雪花构造函数
function Snow(x, y, scale, rotate, speedX, speedY, speedR) {
this.x = x;
this.y = y;
this.scale = scale;
this.rotate = rotate;
this.speedX = speedX;
this.speedY = speedY;
this.speedR = speedR;
}
2.绘制雪花
使用在原型链上编程的方法,给雪花添加绘制的方法。
Snow.prototype.render = function () {
context.save(); //- 保存画布原来的位置
context.beginPath(); //- 开启路径
context.translate(this.x, this.y) //- 移动画布 x y
context.scale(this.scale, this.scale) //- 缩放比例
context.rotate(this.rotate * Math.PI / 180);
context.moveTo(-20, 0); //- 线的开始位置
context.lineTo(20, 0) //- 线结束的位置
context.strokeStyle = '#fff'; //- 颜色
context.lineWidth = 10; //- 宽度
context.lineCap = 'round'; //- 圆角
context.stroke(); //- 开始进行绘画
//- 角度转弧度的计算
var disX = Math.sin(30 * Math.PI / 180) * 20;
var disY = Math.sin(60 * Math.PI / 180) * 20;
/* 第二条线 */
context.moveTo(-disX, disY);
context.lineTo(disX, -disY);
//- 第三条线
context.moveTo(-disX, -disY);
context.lineTo(disX, disY);
context.stroke(); //- 开始进行重复绘画
context.restore(); //- 绘画完成恢复原来的位置
context.closePath(); //- 关闭绘画路径
}
3.程序入口
生成雪花、让雪花开始运动。
使用for循环,生成100个雪花。
不能让这100个雪花一起生成,因此使用setTimeout定时器,让这些雪花在8秒内生成。
注意: 要使用闭包!
var init = function () {
for (var i = 0; i < 100; i++) {
var x = Math.random() * canvas.width;
var scale = Math.random() + 0.5; //- 缩放比例欸
var rotate = Math.random() * 60; //- 旋转的角度
var speedX = Math.random() + 1; //- x轴移动的速度
var speedY = Math.random() + 5; //- 下降的速度
var speedR = Math.random() * 4 + 2; //- 旋转的速度
(function (x, y, scale, rotate, speedX, speedY, speedR) {
setTimeout(function () {
var snow = new Snow(x, y, scale, rotate, speedX, speedY, speedR);
snow.render();
snowArr.push(snow);
}, Math.random() * 8000)
})(x, 0, scale, rotate, speedX, speedY, speedR)
}
snowing();
}
4.雪花运动函数
清除画布内容,重新绘制。
注意画布的宽高,使用模运算使雪花一直在画布中。
function snowing() {
//- 收集生成的雪花对象,进行重置操作,改变生成位置,
setInterval(function () {
//- 之前的信息进行清除操作
context.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < snowArr.length; i++) {
snowArr[i].x = (snowArr[i].x + snowArr[i].speedX) % canvas.width;
snowArr[i].y = (snowArr[i].y + snowArr[i].speedY) % canvas.height
snowArr[i].rotate = (snowArr[i].rotate + snowArr[i].speedR) % 60;
snowArr[i].render();
}
}, 30);
}
完整代码
var canvas = document.getElementById('snow');
var context = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// function snow () {
// context.save(); //- 保存画布原来的位置
// context.beginPath(); //- 开启路径
// context.translate(100, 100) //- 移动画布 x y
// context.moveTo(-20, 0); //- 线的开始位置
// context.lineTo(20, 0) //- 线结束的位置
// context.strokeStyle = '#fff'; //- 颜色
// context.lineWidth = 10; //- 宽度
// context.lineCap = 'round'; //- 圆角
// context.stroke(); //- 开始进行绘画
// //- 角度转弧度的计算
// var disX = Math.sin(30 * Math.PI / 180) * 20;
// var disY = Math.sin(60 * Math.PI / 180) * 20;
// /* 第二条线 */
// context.moveTo(-disX, disY);
// context.lineTo(disX, -disY);
// //- 第三条线
// context.moveTo(-disX, -disY);
// context.lineTo(disX, disY);
// context.stroke(); //- 开始进行重复绘画
// context.restore(); //- 绘画完成恢复原来的位置
// context.closePath(); //- 关闭绘画路径
// }
// snow();
function Snow(x, y, scale, rotate, speedX, speedY, speedR) {
this.x = x;
this.y = y;
this.scale = scale;
this.rotate = rotate;
this.speedX = speedX;
this.speedY = speedY;
this.speedR = speedR;
}
Snow.prototype.render = function () {
context.save(); //- 保存画布原来的位置
context.beginPath(); //- 开启路径
context.translate(this.x, this.y) //- 移动画布 x y
context.scale(this.scale, this.scale) //- 缩放比例
context.rotate(this.rotate * Math.PI / 180);
context.moveTo(-20, 0); //- 线的开始位置
context.lineTo(20, 0) //- 线结束的位置
context.strokeStyle = '#fff'; //- 颜色
context.lineWidth = 10; //- 宽度
context.lineCap = 'round'; //- 圆角
context.stroke(); //- 开始进行绘画
//- 角度转弧度的计算
var disX = Math.sin(30 * Math.PI / 180) * 20;
var disY = Math.sin(60 * Math.PI / 180) * 20;
/* 第二条线 */
context.moveTo(-disX, disY);
context.lineTo(disX, -disY);
//- 第三条线
context.moveTo(-disX, -disY);
context.lineTo(disX, disY);
context.stroke(); //- 开始进行重复绘画
context.restore(); //- 绘画完成恢复原来的位置
context.closePath(); //- 关闭绘画路径
}
// var s = new Snow(50,50,1,10);
// s.render();
var snowArr = [];
var init = function () {
for (var i = 0; i < 100; i++) {
var x = Math.random() * canvas.width;
var scale = Math.random() + 0.5; //- 缩放比例欸
var rotate = Math.random() * 60; //- 旋转的角度
var speedX = Math.random() + 1; //- x轴移动的速度
var speedY = Math.random() + 5; //- 下降的速度
var speedR = Math.random() * 4 + 2; //- 旋转的速度
(function (x, y, scale, rotate, speedX, speedY, speedR) {
setTimeout(function () {
var snow = new Snow(x, y, scale, rotate, speedX, speedY, speedR);
snow.render();
snowArr.push(snow);
}, Math.random() * 8000)
})(x, 0, scale, rotate, speedX, speedY, speedR)
// setTimeout(function () {
// var snow = new Snow(x, 0, scale, rotate, speedX, speedY, speedR);
// snow.render();
// snowArr.push(snow);
// }, Math.random() * 8000)
}
// snowing();
}
function snowing() {
//- 收集生成的雪花对象,进行重置操作,改变生成位置,
setInterval(function () {
//- 之前的信息进行清除操作
context.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < snowArr.length; i++) {
snowArr[i].x = (snowArr[i].x + snowArr[i].speedX) % canvas.width;
snowArr[i].y = (snowArr[i].y + snowArr[i].speedY) % canvas.height
snowArr[i].rotate = (snowArr[i].rotate + snowArr[i].speedR) % 60;
snowArr[i].render();
}
}, 30);
}
init();