先来展示效果,效果如下:
废话不多说直接上代码:
var snows = [] //雪花对象数组
var count = 200 //雪花的个数
function Sonw(w, h, context) {
this.w = w
this.h = h
this.context = context
}
function into() {
let canvas = document.createElement('canvas')
canvas.setAttribute('style', 'position: fixed;left: 0;top: 0;pointer-events: none;');
canvas.setAttribute('id', 'canvas_snow');
document.getElementsByTagName('body')[0].appendChild(canvas);
var context = canvas.getContext('2d') //2d 即指二维平面
var w = window.innerWidth
var h = window.innerHeight
canvas.width = w; //全局分布
canvas.height = h;
let sonw = new Sonw(w, h, context)
for (var i = 0; i < count; i++) {
snows.push({
x: Math.random() * w, //Math.random()用于生成0~1的随机数
y: Math.random() * h,
r: Math.random() * 5,
})
}
//每毫秒刷新一次
// 控制雪花飘落的速度
sonw.draw()
setInterval(()=>{
sonw.draw()
},1)
}
Sonw.prototype.draw = function() {
this.context.clearRect(0, 0, this.w, this.h)
this.context.beginPath()
for (var i = 0; i < count; i++) {
var snow = snows[i];
this.context.fillStyle = "rgb(255,255,255)" //设置雪花的样式
this.context.shadowBlur = 10;
this.context.shadowColor = "rgb(255,255,255)";
//moveTo 移动到指定的坐标
this.context.moveTo(snow.x, snow.y)
// 使用canvas arc()创建一个圆形
//x,y,r:圆的中心的x坐标和y坐标,r为半径
//0,Math.PI * 2起始弧度和结束弧度
this.context.arc(snow.x, snow.y, snow.r, 0, Math.PI * 2)
}
//画布填充
this.context.fill()
this.move()
}
Sonw.prototype.move = function() {
for (var i = 0; i < count; i++) {
var snow = snows[i];
snow.y += (7 - snow.r) / 10 //从上往下飘落
snow.x += ((5 - snow.r) / 10)//从左到右飘落
if (snow.y > this.h) {
snows[i] = {
x: Math.random() * this.w,
y: Math.random() * this.h,
r: Math.random() * 5,
}
}
}
}
// 初始化
into()
看了这些代码之后,是否有一些疑惑呢?是否有一些跃跃欲试呢?
随着脚手架发展,这里再做一个Vue+Ts版本的ts文件。代码如下:
interface Snow {
x: number;
y: number;
r: number;
}
const snows: Snow[] = []; //雪花对象数组
const count = 200; //雪花的个数
let w = window.innerWidth;
let h = window.innerHeight;
class Sonw {
w: number;
h: number;
context: CanvasRenderingContext2D;
constructor(w: number, h: number, context: CanvasRenderingContext2D) {
this.w = w;
this.h = h;
this.context = context;
}
draw() {
this.context.clearRect(0, 0, this.w, this.h);
this.context.beginPath();
for (let i = 0; i < count; i++) {
const snow = snows[i];
this.context.fillStyle = "rgb(255,255,255)"; //设置雪花的样式
this.context.shadowBlur = 10;
this.context.shadowColor = "rgb(255,255,255)";
//moveTo 移动到指定的坐标
this.context.moveTo(snow.x, snow.y);
// 使用canvas arc()创建一个圆形
//x,y,r:圆的中心的x坐标和y坐标,r为半径
//0,Math.PI * 2起始弧度和结束弧度
this.context.arc(snow.x, snow.y, snow.r, 0, Math.PI * 2);
}
//画布填充
this.context.fill();
this.move();
}
move() {
for (let i = 0; i < count; i++) {
const snow = snows[i];
snow.y += (7 - snow.r) / 10; //从上往下飘落
snow.x += ((5 - snow.r) / 10);//从左到右飘落
if (snow.y > this.h) {
snows[i] = {
x: Math.random() * this.w,
y: Math.random() * this.h,
r: Math.random() * 5,
};
}
}
}
}
let snowStatic: boolean
let dinshi: string | number | NodeJS.Timer | undefined
export function into() {
snowStatic = true
let canvas = document.createElement('canvas');
canvas.setAttribute('style', 'position: fixed;left: 0;top: 0;pointer-events: none;');
canvas.setAttribute('id', 'canvas_snow');
document.getElementsByTagName('body')[0].appendChild(canvas);
const context = canvas.getContext('2d')!; //2d 即指二维平面
w = window.innerWidth;
h = window.innerHeight;
canvas.width = w; //全局分布
canvas.height = h;
for (let i = 0; i < count; i++) {
snows.push({
x: Math.random() * w, //Math.random()用于生成0~1的随机数
y: Math.random() * h,
r: Math.random() * 5,
});
}
// 创建一个雪花实例对象
let sonwItem = new Sonw(w, h, context)
// 待改进
sonwItem.draw()
//每毫秒刷新一次
dinshi = setInterval(() => sonwItem.draw(), 10);
}
export function snowDestoty() {
if (snowStatic) {
let child = document.getElementById("canvas_snow") as HTMLCanvasElement;
console.log(child);
child.parentNode!.removeChild(child);
clearInterval(dinshi)
} else {
console.log('暂无实例');
}
}
// 宽度自适应
window.onresize = () => {
let canvasSnow = document.getElementById('canvas_snow') as HTMLCanvasElement;
canvasSnow.width = window.innerWidth;
canvasSnow.height = window.innerHeight;
}
将上述代码复制到Vue脚手架之后,在vue文件中导入调用即可。
如果复制粘贴有问题的话,还可以查看我的gitee,准备了普通版本的案例。