使用 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;
完;

原文地址:https://www.cnblogs.com/Grewer/p/8283562.html

时间: 2024-10-08 21:40:29

使用 typescript 和 canvas 重构snow效果的相关文章

canvas之太阳系效果

星球 变量名 公转周期 光色 暗色 水星 Mercury 87.70 #a69697 #5c3e40 金星 Venus 224.701.70 #c4bbac #1f1315 地球 Earth 365.2422 #78b1e8 #050c12 火星 Mars 686.98 #cec9b6 #76422d 木星 Jupiter 4332.589 #c0a48e #322 土星 Saturn 10759.95 #f7f9e3 #5c4553 天王星 Uranus 30799.095 #a7e115 #

canvas动画文字效果

Doughnut Chartvar c=document.getElementById("canvas");var ctx=c.getContext("2d");ctx.font="50px sans-serif";ctx.fillText("75%",40,92);//ctx.clearRect(40, 52, 74, 68); var c=document.getElementById("canvas"

canvas制作雪花效果

<!DOCTYPE html><html> <head>    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />    <title>圣诞主题</title>    <link rel='stylesheet' href='common.css' />    <link rel="

用Canvas制作剪纸效果

在做剪纸效果之前,先介绍剪纸效果运用到的一些知识: 1.阴影: 在Canvas之中进行绘制时,可以通过修改绘图环境中的如下4个属性值来指定阴影效果: shadowColor:CSS格式的颜色字串.默认值为rgba(0,0,0,0),即完全透明的黑色. shadowOffsetX:阴影在X轴方向的偏移量,以像素为单位.默认值为0 shadowOffsetY:阴影在Y轴方向的偏移量,以像素为单位.默认值为0 shadowBlur:表示阴影效果如何延伸的double值.默认值为0.该值用于高斯模糊方程

HTML5之Canvas时钟(网页效果--每日一更)

今天,带来的是使用HTML5中Canvas标签实现的动态时钟效果. 话不多说,先看效果:http://webfront.verynet.cc/pc/canvas-clock.html 众所周知,Canvas标签是HTML5中的灵魂,HTML5 Canvas是屏幕上的一个由JavaScript控制的即时模式位图区域.即时模式是指在画布上呈现像素的方式, HTML5 Canvas通过JavaScript调用CanvasAPI,在每一帧完全重绘屏幕上的位图.详细将在下面代码进行说明. HTML结构代码

【HTML5】Canvas 实现放大镜效果

目录 图片放大镜 效果 原理 初始化 画背景图片 计算图片被放大的区域的范围 绘制放大镜区域 添加鼠标事件 图表放大镜 原理 绘制原始线段 计算原始区域和放大镜区域 计算线段在新坐标系统的位置 绘制放大镜中心点 绘制放大镜 添加事件 图片放大镜 效果 在线演示    源码 原理 首先选择图片的一块区域,然后将这块区域放大,然后再绘制到原先的图片上,保证两块区域的中心点一致, 如下图所示: 初始化 <canvas id="canvas" width="500"

canvas刮奖效果

上次写刮奖效果都一年前了,那时候还是百度找的源码给改的,自己其实也是迷迷糊糊的,这次因为让妹子写,然后想着自己也重新整理下. <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0,

canvas水波纹效果

先看效果 演示效果 自然界中水波纹效果十分麻烦,我这里只是根据水波纹的几个特性,在理想环境下模拟水波纹的扩散效果. 这里应用到的属性有:扩散.波动.折射. 扩散:很好理解,水波纹会从触发原点开始向周围扩散 波动:水波纹就一直波,在切面上观看,就是一个正弦函数的波形图 折射:光在不同介质中传播速度不同导致出现折射效果. 如果在平静条件下,在垂直方向上看水底事物,很正常. 在波动条件下,因为水的上下波动,导致垂直方向上看到的水底物体,因为波的角度不同,导致水下事物反射的光到人眼的时候,出现一些偏移.

canvas刮刮效果实现

网页特效——刮刮效果实现. 首先分析一下,实现刮刮效果的原理,需要用到html5中的画布canvas,这是一个强大的提供绘制功能的标签,主要用在网页中的图表呈现,比如一些折线图.扇形图等,甚至在游戏开发当中也有广泛的运用,过多的介绍就不多说,刮刮效果需要会使用canvas实现基本的路径绘制,另外需要知道如何获取手指在页面当中的位置(方便跟踪手指移动并绘制),其次需要用到一个核心属性globalCompositeOperation,该属性设置或返回如何将一个源(新的)图像绘制到目标(已有的)的图像