玩别人玩剩下的: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. 开始再次了解.
随机推荐
- MongoDB聚合查询及Python连接MongoDB操作
今日内容概要 聚合查询 Python操作MongoDB 第三方可视化视图工具 今日内容详细 聚合查询 Python操作MongoDB 数据准备 from pymongo import MongoCli ...
- 矩池云 | 搭建浅层神经网络"Hello world"
作为图像识别与机器视觉界的 "hello world!" ,MNIST ("Modified National Institute of Standards and Te ...
- Mysql引擎、隔离机制、存储结构、索引
目录 数据库常用的两种引擎 两种引擎差异对比 如何选择引擎 两个引擎索引结构 查找mysql数据存储位置方式 MyISAM InnoDB 1. 非独立表空间 2. 独立表空间 3. idb文件存的哪些 ...
- Docker - 安装&测试
一.什么是Docker Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中 ...
- 编写第一个GET、POST接口[renren-fast框架系列(1)]
配置好 renren-fast 脚手架,学习完 Spring MVC 架构后,我需要具体调试 renren-fast 的接口,比如要新增某个接口. 什么是前后端分离 运行 renren-fast 项目 ...
- Linux-本地日志服务管理(rsyslog基础)
目录 系统环境 1.常见的两种日志管理服务 1.1 RSYSLOG系统日志服务 1.2 ELK 2.RSYSLOG日志服务的相关知识 2.1 RSYSLOG日志消息级别 2.2 RSYSLOG日志服务 ...
- Vue-表单验证-全选-反选-删除-批量删除
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- MySQL-DB-封装-简易版
<?php class DB{ private $link; public function __construct($host,$user,$password,$dbname,$port) { ...
- BBS项目分布搭建三(个人站点时间归档补充,实现侧边栏跳转、无线级分类、实现文章详情页展示功能)
BBS项目分布搭建三(个人站点时间归档补充,) 1. 个人站点时间归档 """ settings.py设置最好更改以下: LANGUAGE_CODE = 'zh-hans ...
- MATLAB探索初步问题汇总
MATLAB命令窗口如果显示:尝试将SCRIPT normrnd作为函数执行:C:\User-- 出错sort 这类问题,一般是你的*.m文件的名与内置函数名重名,改一下文件名即可. 2.MATLAB ...