JS写一个雪花特性(普通版本与Vue脚手架版)

文章展示了如何使用JavaScript和Vue+TypeScript分别创建Canvas雪花飘落的动画效果。代码包括创建雪花对象、设置飘落速度和方向以及窗口自适应调整。此外,还提供了销毁雪花效果的函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先来展示效果,效果如下:

 废话不多说直接上代码:

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,准备了普通版本的案例。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值