• 使用 typescript 和 canvas 重构snow效果


    前言:之前做过一个 snow 效果,但是是直接用 HTML 做的 点击此处查看 ,几个星期前,我用 typescript 和 canvas 重构了一下,
    snow效果是一个很简单的效果,但是用来练手还是不错的;

    • 首先创建基本变量:
    let canvas = <HTMLCanvasElement>document.getElementById('canvas');
    let ctx = canvas.getContext('2d');
    let H = canvas.height = window.innerHeight;
    let W = canvas.width = window.innerWidth;
    ctx.fillStyle = "#53B7F6";
    
    

    在获取 canvas 的 dom 时可能后报错,所以要用断言或者 let canvas:any 这样来写,不然会报错;
    这里让 canvas 的长,宽分别等于浏览器视窗的长宽,颜色为蓝色,如果想做背景,可以去掉;

    • 获取图片文件:
    const renderImg = (x: number = 10, y: number = 10): void => {
        ctx.drawImage(snowImg, x, y, 42, 30);
    };
    
    let readStatus: boolean = false;
    
    let snowImg: any = new Image();
    snowImg.onload = (): void => {
        readStatus = true;
    };
    
    snowImg.src = 'snow.jpg';
    

    要记得读取图片的函数是异步执行的,所以添加一个状态,来判断图片是否已加载,而 renderImg 函数呢,就是在 canvas 上绘制图片,
    他有初始值x=10,y=10,后面的42,30 是图片的大小,这个如果你换一个图片的话需要好好调节这2个数值;

    • 创建例子存储数组:
    const snowNum: number = 8;
    
    interface snowType {
        x: number,
        y: number,
        stepX: number,
        stepY: number
    }
    
    
    let store: snowType[] = [];
    
    const add = (): void => {
        let num: number = snowNum * Math.random() | 0;
        while (num--) {
            store.push({
                x: Math.random() * W | 0,
                y: 0,
                stepX: (Math.random() * 5 - 2) | 0,
                stepY: ((Math.random() * 8) | 0) + 2
            })
        }
    };
    

    snowNum 的作用是每秒最多出现8片 snow,store 中存储了 snow 的坐标位置,和每秒的移动速度;

    • 渲染函数:
    const render = (): void => {
        if (!readStatus) return;
        clearBg();
        let length: number = store.length;
        while (length--) {
            let {x, y, stepX, stepY}:snowType = store[length];
            renderImg(x, y);
            store[length].x += stepX;
            store[length].y += stepY;
            if (check(store[length])) {
                store.splice(length, 1);
            }
        }
    };
    

    通过坐标来渲染图片并添加移动,做出判断,当 snow 移动到浏览器底部时删除他;

    • 时间计时:
    let addTime: number = 0;
    let lastTime: number = 0;
    
    const animotion = (timestamp: number = 0): void => {
        if (timestamp - lastTime > 50) {
            render();
            lastTime = timestamp;
        }
        if (timestamp - addTime > 1000) {
            add();
            addTime = timestamp;
        }
        try {
            window.requestAnimationFrame(animotion);
        } catch {
            alert('你的浏览器不支持rAF,请更新或更换浏览器')
        }
    };
    animotion();
    

    之前的计时我都是拿 setInterval 来做计时器的,但是会有一个缺点,不知道大家有没碰到过,就是在 chrome 里
    切换到其他页面是,数组仍在添加,但是已经停止了渲染,所以再切回来的时候,会出现一大堆的东西,而这个用 rAF 是没有的,
    但是他需要较高的兼容(IE>10),不过网上已经有了用 setInterval 做兼容方法,百度一下就有了,我这里就不讲了;

    最后:
    demo: 点击此处查看
    GitHub:https://github.com/Grewer/JsDemo/tree/master/snow

    如果该文章帮到了你,还请推荐或 star;
    完;

  • 相关阅读:
    redis接入sentinelPool的配置
    02.Redis主从集群的Sentinel配置
    淘宝大秒系统设计详解
    关于Thread.currentThread()和this的差异
    App开放接口api安全性—Token签名sign的设计与实现
    使用Spring Session做分布式会话管理
    PowerDesigner 15.1 安装步骤详细图解及破解
    解密ThreadLocal
    深入分析 ThreadLocal 内存泄漏问题
    一个经典例子让你彻彻底底理解java回调机制
  • 原文地址:https://www.cnblogs.com/Grewer/p/8283562.html
Copyright © 2020-2023  润新知