canvas大雪纷飞

前言:正好业务触及到canvas,看完api顺手写个雪花效果,因为之前看到过很多次这个,主要看思路,想象力好的可以慢慢去创作属于自己的canvas效果

思路:

  • 利用画圆arc()和环形渐变色createRadialGradient()画一个雪花的模型(想要更好看的模型可以用图片代替)
    var grd = this.canvas.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.r);
grd.addColorStop(0, "rgba(255,255,255,1)");
grd.addColorStop(1, "rgba(255,255,255,0.2)");
this.canvas.fillStyle = grd;
this.canvas.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
this.canvas.fill();

效果图

  • 如何让canvas画布上的点移动

动画其实就是一帧一帧的画面的组合,在一定时间内把画面从第一帧切换到第二帧到第n帧这个过程就是动画
弄懂这个道理,让雪花动起来就很简单了,重绘。
改变雪花的x,y坐标,在短时间内重绘一次,然后不断重复此过程,为了照顾浏览器爸爸的感受,x,y超出画布边界的时候把雪花清除掉。

    setInterval(() => {
arr[0].canvas.clearRect(0, 0, maxW, maxH);
for(var i = 0; i < arr.length; i++) {
if(arr[i].y >= maxH){
//清除超出下边界的雪花
continue;
}
arr[i].play();
}
}, 30); play: function() {
this.x += this.speedX;
this.y += this.speedY;
if(this.x < this.r) {
this.speedX = Math.abs(this.speedX);
}
if(this.y < this.r) {
this.speedY = Math.abs(this.speedY);
}
this.canvas.beginPath();
var grd = this.canvas.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.r);
grd.addColorStop(0, "rgba(255,255,255,1)");
grd.addColorStop(1, "rgba(255,255,255,0.2)");
this.canvas.fillStyle = grd;
this.canvas.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
this.canvas.fill();
}
  • 最后一步就是创建一个个雪花实例去执行动画了
    var snow = function() {
this.x = this.rand(maxW);
this.y = 0;
this.r = this.rand(10);
this.speedX = this.getRanNum(-5, 5);
this.speedY = this.getRanNum(10, 20);
this.width = 0;
this.height = 0;
this.canvas = {};
this.init();
}
var arr = [];
setInterval(() => {
for(let i = 0; i < 10; i++) {
arr.push(new snow());
}
}, 30);

效果预览

完整代码

<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
body {
background-color: '#fff';
}
canvas {
background-color: rgba(0, 0, 0, 1);
}
</style>
</head> <body>
<canvas id="canvas" width="1000px" height="500px"></canvas> <script type="text/javascript">
var myCanvas = document.getElementById('canvas')
var ctx = myCanvas.getContext('2d');
var clientW = window.innerWidth;
var clientH = window.innerHeight;
myCanvas.width = clientW;
myCanvas.height = clientH;
var maxW = clientW;
var maxH = clientH; //雪花实例构造函数
var snow = function() {
this.r = this.rand(10);
this.x = this.rand(maxW);
this.y = 0;
this.speedX = this.getRanNum(-5, 5);
this.speedY = this.getRanNum(10, 20);
this.width = 0;
this.height = 0;
this.canvas = {};
this.init();
}
snow.prototype = {
//初始化
init: function() {
var snow = document.getElementById('canvas');
this.canvas = snow.getContext('2d');
this.width = snow.width;
this.height = snow.height;
},
//获取0-num之间的随机数
rand: function(num) {
return Math.floor(Math.random() * num + 1);
},
//获取n-m之间的随机数
getRanNum: function (n, m) {
return Math.floor(Math.random() * (m - n) + n);
},
//雪花移动
play: function() {
//改变坐标位置 连续重绘形成动画效果
this.x += this.speedX;
this.y += this.speedY;
this.canvas.beginPath();
//定义雪花UI 渐变色+圆
var snowColor = this.canvas.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.r);
snowColor.addColorStop(0, "rgba(255,255,255,1)");
snowColor.addColorStop(1, "rgba(255,255,255,0.2)");
this.canvas.fillStyle = snowColor;
this.canvas.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
this.canvas.fill();
}
}; var arr = [];
//生成新雪花的速度 每30ms生成10个
setInterval(() => {
for(let i = 0; i < 10; i++) {
arr.push(new snow());
}
}, 30); //雪花重绘(即帧,多帧即移动动画) 30ms重绘一次
setInterval(() => {
arr[0].canvas.clearRect(0, 0, maxW, maxH);
for(let i = 0; i < arr.length; i++) {
if(arr[i].y >= maxH){
//清除超出下边界的雪花
arr.splice(i,1);
continue;
}
arr[i].play();
}
}, 30);
</script>
</body>
</html>

最后,每几个canvas的方法组合一下做个小效果,慢慢的就可以做大型炫酷效果了,当然,炫酷效果离不开一些常用或生僻的数学知识,各类算法,方法,相关插件(我说的插件是用来计算一些东西或者图形之类的,不是用插件画canvas)作为铺垫
敲黑板,希望路过的大神能介绍一些canvas进阶需要学习的一些知识点,小弟不胜感激~

版权所有,转载请注明出处~

玩别人玩剩下的:canvas大雪纷飞的更多相关文章

  1. 为什么说程序员都应该玩一玩GitHub

    既熟悉又陌生的GitHub 关于GitHub,相信每一个程序员都再熟悉不过了.它为开发者提供Git仓库的托管服务,是全世界最大的代码集中地,被戏称为“全球最大同性交友网站”. 但是对于很大一部分程序员 ...

  2. 玩一玩nodejs--一个简单的在线实时填表应用

    学习nodejs三天,入了个门,感觉他和jsp.php还是存在较大的差别.本文首先复习这些天学的一些知识点,然后谈一下如何一步一步到做一个在线实时填表的小应用,进一步巩固一下这些个知识点.这里先简单介 ...

  3. 一起玩转玩转LiteOS组件:TinyFrame

    摘要:TinyFrame是一个简单的用于解析串口(如 UART.telnet.套接字等)通信数据帧的库. 本文分享自华为云社区<LiteOS组件尝鲜-玩转TinyFrame>,作者:Lio ...

  4. 玩一玩基于Token的 自定义身份认证+权限管理

    使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录.大概的流程是这样的: 客户端使用用户名跟密码请求登录 服务端收到请求,去验证用户名与密码 验证成功后,服务端会签发一个 Toke ...

  5. 无语啊,sublime给我弄乱玩,玩坏了,而且安装插件也安装不了

    国内的什么插件地址都TMMD失效了,没办法,只能翻"强"到外面找了,而且找了很多也用不了,所以收藏一个为了预防以后不行有补救的方法: 百度的99%都不行,不是报这个错就是那个错,可 ...

  6. 想挑战AlphaGO吗?先和PostgreSQL玩一玩?? PostgreSQL与人工智能(AI)

    1月4日晚,随着古力认输,Master对人类顶尖高手的战绩停留在60胜0负1和,而令人尴尬的是这唯一一场和棋还是因为棋手掉线系统自动判和,并不是棋盘上的局势真的势均力敌了.包括聂卫平.柯洁.朴廷桓.井 ...

  7. js 玩一玩

    闲着没事学了学js,做了一个下页面玩玩. 下面是html代码: <!DOCTYPE html><html> <head> <meta charset=&quo ...

  8. .NET Core 玩一玩 Ocelot API网关

    .net 这几年国内确实不好过. 很多都选择转行.不过.net Core跨平台 开源之后 .社区的生态在慢慢建立.往好的趋势发展. 对于坚守在.NET战线的开发者来说 是个挺不错的消息.  特别是微软 ...

  9. 玩一玩MEAN

    参考的书如下: Manning.Getting.MEAN.with.Mongo.Express.Angular.and.Node. 开始再次了解.

随机推荐

  1. pandas模块补充

    数据分析模块pandas和matplotlib补充 面向百度式编程 面向百度式工作 遇到没有见过的知识点或者是相关知识点一定不要慌,结合百度和已知的知识点去学习 pandas模块补充 基于numpy构 ...

  2. JZ-029-最小的 K 个数

    标题 最小的 K 个数 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 题目链接: 最小的 K 个数 代码 import ja ...

  3. css蒙层

    {   -webkit-filter: grayscale(100%);   -moz-filter: grayscale(100%);   -ms-filter: grayscale(100%); ...

  4. 极速体验|使用 Erda 微服务观测接入 Jaeger Trace

    在大型网站系统设计中,随着分布式架构,特别是微服务架构的流行,我们将系统解耦成更小的单元,通过不断的添加新的.小的模块或者重用已经有的模块来构建复杂的系统.随着模块的不断增多,一次请求可能会涉及到十几 ...

  5. 安卓手机APP兼容性测试如何有效进行?

    Android App兼容性测试是一个比较重要的App评价内容,实际上兼容性测试不仅仅和测试人员相关,在开发阶段就应当着重考虑,因为兼容性问题是除了实现App本身要求的功能后,必须要关注.而且至关重要 ...

  6. feign服务中调用,传递token

    默认spring-boot 微服务中 用feign来做服务间调用,是不会携带token传递的.为了能让服务间调用的时候带上token,需要进行配置,增强resTemplate   1.先实现请求拦截器 ...

  7. swoole 聊天室

    1:宝塔终端安装php 2:宝塔终端检测是否安装好 php-v 3:宝塔面板安装swoole扩展,终端检测 php -m  查看扩展 扩展已经安装完毕

  8. mysql 获取当前时间和时间戳

    mysql 获取当前时间为select now()运行结果: 2012-09-05 17:24:15 mysql 获取当前时间戳为select unix_timestamp(now()) 运行结果:u ...

  9. tensorflow源码解析之framework-node

    目录 什么是node node_def 关系图 涉及的文件 迭代记录 1. 什么是node TF中的计算图由节点组成,每个节点包含了一个操作,表示这个节点的作用,比如,如果一个节点的作用是做矩阵乘法, ...

  10. call、apply 和 bind

    call().apply().bind() 都是用来重定义 this 这个对象的! var obj1 = { username: "HuiTaiLang", fn: functio ...