前言:之前做过一个 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;

完;

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

  1. 使用Canvas实现动画效果 | DKlogs -- 设计 | 生活

    使用Canvas实现动画效果 | DKlogs -- 设计 | 生活 使用Canvas实现动画效果

  2. canvas实现倒计时效果示例(vue组件内编写)

    前言: 此事例是在vue组件中,使用canvas实现倒计时动画的效果.其实,实现效果的逻辑跟vue没有关系,只要读懂canvas如何实现效果的这部分逻辑就可以了 canvas动画的原理:利用定时器,给 ...

  3. 原生js实现canvas气泡冒泡效果

    说明: 本文章主要分为ES5和ES6两个版本 ES5版本是早期版本,后面用ES6重写优化的,建议使用ES6版本. 1, 原生js实现canvas气泡冒泡效果的插件,api丰富,使用简单2, 只需引入J ...

  4. canvas/CSS仪表盘效果

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. Canvas的下雪效果

    cfs.snow.js canvas 下雪场景 不会影响页面使用 使用方式非常简单 利用这个js文件,我们就能很快的让页面出现下雪的动画效果. 例如 <script type="tex ...

  6. canvas弹动效果

    弹动效果,用物体与目标的距离乘上系数再累加至速度上,让物体呈加速度运动,再让速度乘与摩擦力系数,让物体最终停止运动 代码如下所示 var canvas = document.getElementByI ...

  7. 用Canvas制作剪纸效果

    在做剪纸效果之前,先介绍剪纸效果运用到的一些知识: 1.阴影: 在Canvas之中进行绘制时,可以通过修改绘图环境中的如下4个属性值来指定阴影效果: shadowColor:CSS格式的颜色字串.默认 ...

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

    今天,带来的是使用HTML5中Canvas标签实现的动态时钟效果. 话不多说,先看效果:亲,请点击这里 众所周知,Canvas标签是HTML5中的灵魂,HTML5 Canvas是屏幕上的一个由Java ...

  9. 【HTML5】Canvas 实现放大镜效果

    图片放大镜 效果 在线演示    源码 原理 首先选择图片的一块区域,然后将这块区域放大,然后再绘制到原先的图片上,保证两块区域的中心点一致, 如下图所示: 初始化 <canvas id=&qu ...

随机推荐

  1. JS数组添加元素的三种方式

    1.push() 结尾添加 数组.push(元素) 参数 描述 newelement1 必需.要添加到数组的第一个元素. newelement2 可选.要添加到数组的第二个元素. newelement ...

  2. 【Eclipse+IntelliJ反编译】Eclipse/IntelliJ IDEA反编译查看源码及注释

    怎么用IDE查看第三方jar包的源码和注释,IntelliJ IDEA自带反编译器,Eclipse装个插件即可,不能看注释就麻烦了,总不能去找API文档吧,现在终于掌握了,下面给出解决方案,供大家参考 ...

  3. linux 常见名词及命令(三)

    tar 用于对文件打包压缩或解压. 示例: 打包并压缩文件:tar -czvf 压缩包名.tar.gz 文件名 解压并展开压缩包:tar -zxvf 压缩包名.tar.gz -c 创建压缩文件 -x ...

  4. 使用GSON解析JSON文件

    package com.pingyijinren.test; /** * Created by Administrator on 2016/5/19 0019. */ public class App ...

  5. 在windows下安装Django

    2013-07-24 21:23:30| 1.安装Python 我安装的是Python(x,y)-2.7.5.0,安装目录在C盘.安装成功后如下图所示.   2.安装Django 从https://w ...

  6. Uva 106 - Fermat vs. Pythagoras 解题报告

    数论题,考查了本原勾股数(PPT) 对一个三元组(a,b,c)两两互质 且满足 a2 + b2 = c2 首先有结论 a 和 b 奇偶性不同 c总是奇数(可用反证法证明,不赘述) 设 a为奇数 b为偶 ...

  7. JAVA调用动态链接库(dll)

        菜鸡爬坑 基础知识  因为某个东西的keygen我只会在win下生成!! 所以只能出此下策!!之前一直是android下用jni调用so文件,现在试下java在win平台下调用dll 首先还是 ...

  8. react 服务器端渲染 ssr 中 localstorage/history/window is not defined 解决方案

    1.原因 ssr 会在后端执行组件的 componentWillMount 以及在它这个生命周期之前的生命周期 也就是说 ssr 阶段是不会执行 componentDidMount 方法的 当你在 c ...

  9. NSA开发的工控ICS/SCADA态势感知开源工具Grassmarlin(附下载地址)

    工具简介 GRASSMARLIN是一款由美国国家安全局开发的,能够帮助运维工程师在IP网络上发现并编目监控和数据采集系统(SCADA)和工业控制系统(ICS)主机的开源软件工具,也被称为被动网络映射器 ...

  10. Android进程间通信之内部类作为事件监听器

    在Android中,使用内部类能够在当前类里面发用改监听器类,由于监听器类是外部类的内部类.所以能够自由訪问外部类的全部界面组件. 下面是一个调用系统内部类实现短信发送的一个样例: SMS类: pac ...