玩别人玩剩下的:canvas大雪纷飞
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大雪纷飞的更多相关文章
- 为什么说程序员都应该玩一玩GitHub
既熟悉又陌生的GitHub 关于GitHub,相信每一个程序员都再熟悉不过了.它为开发者提供Git仓库的托管服务,是全世界最大的代码集中地,被戏称为“全球最大同性交友网站”. 但是对于很大一部分程序员 ...
- 玩一玩nodejs--一个简单的在线实时填表应用
学习nodejs三天,入了个门,感觉他和jsp.php还是存在较大的差别.本文首先复习这些天学的一些知识点,然后谈一下如何一步一步到做一个在线实时填表的小应用,进一步巩固一下这些个知识点.这里先简单介 ...
- 一起玩转玩转LiteOS组件:TinyFrame
摘要:TinyFrame是一个简单的用于解析串口(如 UART.telnet.套接字等)通信数据帧的库. 本文分享自华为云社区<LiteOS组件尝鲜-玩转TinyFrame>,作者:Lio ...
- 玩一玩基于Token的 自定义身份认证+权限管理
使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录.大概的流程是这样的: 客户端使用用户名跟密码请求登录 服务端收到请求,去验证用户名与密码 验证成功后,服务端会签发一个 Toke ...
- 无语啊,sublime给我弄乱玩,玩坏了,而且安装插件也安装不了
国内的什么插件地址都TMMD失效了,没办法,只能翻"强"到外面找了,而且找了很多也用不了,所以收藏一个为了预防以后不行有补救的方法: 百度的99%都不行,不是报这个错就是那个错,可 ...
- 想挑战AlphaGO吗?先和PostgreSQL玩一玩?? PostgreSQL与人工智能(AI)
1月4日晚,随着古力认输,Master对人类顶尖高手的战绩停留在60胜0负1和,而令人尴尬的是这唯一一场和棋还是因为棋手掉线系统自动判和,并不是棋盘上的局势真的势均力敌了.包括聂卫平.柯洁.朴廷桓.井 ...
- js 玩一玩
闲着没事学了学js,做了一个下页面玩玩. 下面是html代码: <!DOCTYPE html><html> <head> <meta charset=&quo ...
- .NET Core 玩一玩 Ocelot API网关
.net 这几年国内确实不好过. 很多都选择转行.不过.net Core跨平台 开源之后 .社区的生态在慢慢建立.往好的趋势发展. 对于坚守在.NET战线的开发者来说 是个挺不错的消息. 特别是微软 ...
- 玩一玩MEAN
参考的书如下: Manning.Getting.MEAN.with.Mongo.Express.Angular.and.Node. 开始再次了解.
随机推荐
- pandas模块补充
数据分析模块pandas和matplotlib补充 面向百度式编程 面向百度式工作 遇到没有见过的知识点或者是相关知识点一定不要慌,结合百度和已知的知识点去学习 pandas模块补充 基于numpy构 ...
- JZ-029-最小的 K 个数
标题 最小的 K 个数 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 题目链接: 最小的 K 个数 代码 import ja ...
- css蒙层
{ -webkit-filter: grayscale(100%); -moz-filter: grayscale(100%); -ms-filter: grayscale(100%); ...
- 极速体验|使用 Erda 微服务观测接入 Jaeger Trace
在大型网站系统设计中,随着分布式架构,特别是微服务架构的流行,我们将系统解耦成更小的单元,通过不断的添加新的.小的模块或者重用已经有的模块来构建复杂的系统.随着模块的不断增多,一次请求可能会涉及到十几 ...
- 安卓手机APP兼容性测试如何有效进行?
Android App兼容性测试是一个比较重要的App评价内容,实际上兼容性测试不仅仅和测试人员相关,在开发阶段就应当着重考虑,因为兼容性问题是除了实现App本身要求的功能后,必须要关注.而且至关重要 ...
- feign服务中调用,传递token
默认spring-boot 微服务中 用feign来做服务间调用,是不会携带token传递的.为了能让服务间调用的时候带上token,需要进行配置,增强resTemplate 1.先实现请求拦截器 ...
- swoole 聊天室
1:宝塔终端安装php 2:宝塔终端检测是否安装好 php-v 3:宝塔面板安装swoole扩展,终端检测 php -m 查看扩展 扩展已经安装完毕
- mysql 获取当前时间和时间戳
mysql 获取当前时间为select now()运行结果: 2012-09-05 17:24:15 mysql 获取当前时间戳为select unix_timestamp(now()) 运行结果:u ...
- tensorflow源码解析之framework-node
目录 什么是node node_def 关系图 涉及的文件 迭代记录 1. 什么是node TF中的计算图由节点组成,每个节点包含了一个操作,表示这个节点的作用,比如,如果一个节点的作用是做矩阵乘法, ...
- call、apply 和 bind
call().apply().bind() 都是用来重定义 this 这个对象的! var obj1 = { username: "HuiTaiLang", fn: functio ...