前言:之前做过一个 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. 使用IDEA部署Myeclipse项目----亲测有效

    使用IDEA部署Myeclipse项目-----https://blog.csdn.net/u010570551/article/details/51510447

  2. PHP 关键词

    PHP 关键词 TCP 传输层通信协议 面向连接的.可靠的.基于字节流的 建立链接需要三次握手 Socket(套接字) 一个工具,一个接口 封装了TCP/IP协议 建立长链接的基础 HTTP 一个应用 ...

  3. Count Color POJ - 2777 线段树

    Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds ...

  4. [bzoj3436]小K的农场_差分约束

    小K的农场 bzoj-3436 题目大意:给定n个点,每个节点有一个未知权值.现在有m个限制条件,形如:点i比点j至少大c,点i比点j至多大c或点i和点j相等.问是否可以通过给所有点赋值满足所有限制条 ...

  5. 解析excel文件并将数据导入到数据库中

    今天领导给安排了一个临时工作,让我将一个excel里面的数据解析后放入数据库中,经过一个下午的努力成功完成,现在将代码献上,希望对大家有所帮助 一.需要导入的jar 1.commons-collect ...

  6. HttpClientUtil 工具类 实现跨域请求数据

    package com.xxx.common.util; import java.io.IOException; import java.net.URI; import java.util.Array ...

  7. Django学习系列之模板系统

    一.模板标签 if/else {%  if  %}标签检查一个变量的值是否为真或者等于另外一个值,如果为真,系统会执行{%  if  %}和{%  endif  %}之间的代码块,例如: {% if ...

  8. Linux学习系列之MySQL备份

    MySQL排除表备份 #!/bin/bash #created by 90root #date: 20160809 date_y=$(date +%Y) date_m=$(date +%m) time ...

  9. 自己动手写Android数据库框架

    前言 相信不少开发人员跟我一样,每次都非常烦恼自己写数据库,并且那些数据库语句也经常记不住.当然网上也有非常多非常好的数据库框架,你能够直接拿来用,可是 非常多时候我们的项目.特别是一个小型的Andr ...

  10. Windows网络编程:winsock文件传输范例

    基于TCP流协议的winsock网络文件传输Demo: 实现:C语言 功能:文件传输(可以传任何格式的文件) /******************************************** ...