canvas粒子线条效果
在正式开始之前,先上个效果图看看:

很酷炫有木有???
那么如何实现这个效果呢?
首先,我做这个特效的基本步骤是这样的:
1.将若干个粒子随机分布在画布(canvas)上,并且给他们一个初始速度
2.为了不让粒子离开画布的可视范围,当粒子移动到画布边缘时,会进行反弹
3.设定一个最大距离,若粒子间的距离超过最大距离,便不会产生连线,若小于等于最大距离,则粒子间距越小,粒子间连的线就越宽,或者说颜色越深
4.设定鼠标事件,当鼠标移动时,粒子与鼠标距离若小于等于最大距离,那么粒子将会朝着鼠标方向移动
那么我们就按照这四个步骤来进行:
<canvas width="1300" height="600" id="myCanvas"></canvas>
正常操作,我设置了一个宽1300,高600的画布
let c = document.getElementById('myCanvas');
let cxt = c.getContext('2d');
let num = 100;//粒子数量
let balls = [];
num是我设置的粒子数量,数量可以随意设置,但要注意的是,如果粒子数量太多,因为设备的原因,可能粒子不能够流畅运动,或移动的很慢。
用balls数组来存放随机数
for(let i = 0; i < num; i ++){
//设置随机数(粒子横坐标,纵坐标,半径,水平移动速度,垂直移动速度)
let startX = Math.random() * (c.width - 5) + 5;
let startY = Math.random() * (c.height - 5) + 5;
let radius = Math.random() * 2 + 1;
let speedX = Math.random() * 2 - 1;
let speedY = Math.random() * 2 - 1;//速度的方向(正负)大小都是随机的
// let colour = `rgba(${Math.random() * 255},${Math.random() * 255},${Math.random() * 255},.7)`;
balls.push({startX, startY, radius, speedX, speedY});//存入数组
}
接下来用for循环设置随机数
从上到下顺序是:粒子初始横坐标、纵坐标、半径、水平移动速度、和垂直移动速度
还可以设置粒子的颜色,这里我注释掉了
最后把随机出的数推入数组储存起来
function change(ball){
cxt.beginPath();//开始绘制粒子
cxt.fillStyle = '#000';
cxt.arc(ball.startX, ball.startY, ball.radius, 0, Math.PI * 2);
cxt.fill();
//粒子碰到画布边界会自动反弹
ball.speedX *= (ball.startX + ball.radius) >= c.width || (ball.startX - ball.radius) <= 0 ? -1 : 1;
ball.speedY *= (ball.startY + ball.radius) >= c.height || (ball.startY - ball.radius) <= 0 ? -1 : 1;
ball.startX += ball.speedX;
ball.startY += ball.speedY;
}
先绘制粒子,然后判断粒子是否运动到画布边界,如果是,就使速度乘以-1,这样粒子会朝着相反方向运动
注意:这里不能先执行 startX/Y + speedX/Y 再执行粒子是否运动到画布边界的判断
如果这样做,那么在设置初始横坐标、纵坐标的时候就不能直接设为 Math.random() * c.width/height 或 Math.random() * c.width/height + 1
因为Math.random()随机出的数是包含0的,如果粒子的初始横坐标或纵坐标就在画布边缘,那么粒子会在边缘快速的反弹,不会移动到画布中,当然如果你有别的方法,那么请无视我这句话
function move(){
cxt.clearRect(0, 0, c.width, c.height);//清除画布
for(let i = 0; i < num; i ++){
change(balls[i]);
}
}
创建一个move函数来调用change
每当执行一遍for循环时,都要清除一次画布,不然之前粒子运动的轨迹都会显示在上面
//点与点之间划线,距离较小的连线,距离大的则不连
function drawLines(){
move();
let long = 100;
let newBalls=[];//设置新数组以便与其他粒子比较距离 balls.forEach(function(ball){//遍历数组
for(let i = 0; i < num; i ++){
newBalls[i] = balls[i];//赋值给新数组
let disX = newBalls[i].startX - ball.startX;
let disY = newBalls[i].startY - ball.startY;
let dis = Math.sqrt(disX * disX + disY * disY);
if(dis <= long){
cxt.beginPath();
cxt.lineWidth = (long - dis) / long;
cxt.strokeStyle = `rgba(0, 0, 0, ${dis / long})`;
cxt.moveTo(newBalls[i].startX, newBalls[i].startY);
cxt.lineTo(ball.startX, ball.startY);
cxt.stroke();
}
}
//添加鼠标事件
c.onmousemove=function(ev){
ev = event || window.event;
for(let i = 0; i < num; i ++){
let newX = newBalls[i].startX - ev.clientX;
let newY = newBalls[i].startY - ev.clientY;
let newDis = Math.sqrt(newX * newX + newY * newY);
if(newDis <= long){//周围的点朝着鼠标方向移动
newBalls[i].startX -= newX * 0.04;
newBalls[i].startY -= newY * 0.04;
}
}
};
});
}
setInterval(drawLines,20);
创建一个drawline函数来执行连线效果和鼠标移动效果
首先设置一个最大距离long,我设的是100px的长度
定义一个新数组newBalls[]便于和balls[]中的粒子做距离比较
用foreach()方法遍历balls数组,这样就可以直接和balls的所有粒子进行比较,比较方便
计算出粒子之间的距离dis,如果dis小于等于long,那么就绘制线条连接两个粒子
if(dis <= long){
cxt.beginPath();
cxt.lineWidth = (long - dis) / long;
cxt.strokeStyle = `rgba(0, 0, 0, ${dis / long})`;
cxt.moveTo(newBalls[i].startX, newBalls[i].startY);
cxt.lineTo(ball.startX, ball.startY);
cxt.stroke();
}
线条的宽度和透明度是根据long和dis的关系来设置的
这样的效果更加自然
c.onmousemove=function(ev){
ev = event || window.event;
for(let i = 0; i < num; i ++){
let newX = newBalls[i].startX - ev.clientX;
let newY = newBalls[i].startY - ev.clientY;
let newDis = Math.sqrt(newX * newX + newY * newY);
if(newDis <= long){//周围的点朝着鼠标方向移动
newBalls[i].startX -= newX * 0.04;
newBalls[i].startY -= newY * 0.04;
}
}
};
设置鼠标事件,仍然是一样的操作
先算出鼠标和粒子之间的距离,如果粒子和鼠标距离小于等于最大距离,就朝着鼠标的方向移动
这个效果是我自己做的,和网上的很多效果感觉不太一样,如果发现了更酷炫的效果,那么之后我会更新
canvas粒子线条效果的更多相关文章
- 打造高大上的Canvas粒子(一)
HTML5 Canvas <canvas>标签定义图形,比如图表和其他图像,必须用脚本(javascript)绘制图形. 举例:绘制矩形 <script> var c = do ...
- CodePen 作品秀:Canvas 粒子效果文本动画
作品名称——Shape Shifter,基于 Canvas 的粒子图形变换实验.在页面下方的输入框输入文本,上面就会进行变换出对应的粒子效果文本动画. CodePen 作品秀系列向大家展示来自 Cod ...
- html5 canvas 粒子特效
不知不觉就已经好久没写过博客了,自从七月正式毕业后,离开了实习了将近九个月的老东家,进了鼠厂后,做的事都是比较传统的前端活,之前在tpy的时候只管做移动h5的特效以及小游戏,再加上实习所以时间比较充裕 ...
- canvas粒子时钟
前面的话 本文将使用canvas实现粒子时钟效果 效果展示 点阵数字 digit.js是一个三维数组,包含的是0到9以及冒号(digit[10])的二维点阵.每个数字的点阵表示是7*10大小的二维数组 ...
- 炒鸡简单的canvas粒子(山东数漫江湖)
位图的canvas一直不会被svg比下去的原因了. 俗话说,须弥芥子,是大小之说,也有以小见大之说,颗颗粒子,足以构建宏大效果. 这是一篇炒鸡简单的canvas粒子教程,主要是讲如何粒子特效的原理,一 ...
- wpf实现两头渐窄的线条效果
原文:wpf实现两头渐窄的线条效果 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/huangli321456/article/details/800 ...
- 使用Canvas实现动画效果 | DKlogs -- 设计 | 生活
使用Canvas实现动画效果 | DKlogs -- 设计 | 生活 使用Canvas实现动画效果
- HTML5 canvas绘制线条曲线
HTML5 canvas入门 线条例子 1.简单线条 2.三角形 3.填充三角形背景颜色 4.线条颜色以及线条大小 5.二次贝塞尔曲线 6.三次贝塞尔曲线 <!doctype html> ...
- canvas实现倒计时效果示例(vue组件内编写)
前言: 此事例是在vue组件中,使用canvas实现倒计时动画的效果.其实,实现效果的逻辑跟vue没有关系,只要读懂canvas如何实现效果的这部分逻辑就可以了 canvas动画的原理:利用定时器,给 ...
随机推荐
- 企业级架构 MVVM 模式指南 (WPF 和 Silverlight 实现) 译(1)
前言对于WPF和Silverlight来讲,MVVM是微软设计师和业内专家高度推荐的非常棒的一种设计模式.本书会探讨MVVM设计模式的一些自身缺陷以及为什么MVVM还不能成为行业内的标准设计模式.这会 ...
- 奇虎360选择IPO “壳概念”很受伤
黄一帆 “市场正呈现出为一幕经典影像:在绚丽的霞光笼罩下,蔚蓝色的大海边,在金色的海岸上,欢笑的孩子们踮起脚尖,刚好看见原来海平面露出的航船桅杆——那是缓缓驶来的注册制号:而转过头来,则是沙滩上大 ...
- 用友的BS专用浏览器方案
T+的这个BS中的B是自己的专用浏览器,这样有以下好处 1.避免了公用浏览器比如IE 里的其它插件的干扰2.避免了各个操作系统不同版本和不同种类浏览器的兼容问题,且只需要维护一个版本3.避免了共用浏览 ...
- sql关联查询—将一个表的查询结果作为新表进行查询操作
例题:# 各个部门中 最高工资中最低的那个部门的 最低工资是多少? 先考虑取得各个部门最高工资 SELECT MAX(salary) AS max_salary,e.`department_id` ...
- 使用wireshark抓包分析-抓包实用技巧
目录 使用wireshark抓包分析-抓包实用技巧 前言 自定义捕获条件 输入配置 输出配置 命令行抓包 抓取多个接口 抓包分析 批量分析 合并包 结论 参考文献 使用wireshark抓包分析-抓包 ...
- Hexo+NexT(三):Next主题配置详解
阅读本篇之前,假定读者已经有了Node.js的基础,如需要补充Node.js知识的,请自行百度. Hexo是在Node.js框架下的一个项目,利用Node.js提供的强大功能,完成从Markdown到 ...
- python文件及路径管理函数
glob模块 说明: 1.glob是python自己带的一个文件操作相关模块,用它可以查找符合自己目的的文件,就类似于Windows下的文件搜索, 支持通配符操作 *.?.[] 这三个通配符,*代表0 ...
- pybind11在Windows下的使用
Pybind11算是目前最方便的Python调用C++的工具了, 介绍一下在vs2019上写Python的扩展的HelloWorld 1. 去下载pybind11 https://github ...
- SSM(二)MyBatis多表联查
这篇文章写了以下几个简单的例子,用来说明MyBatis多标联查基本语法 1.sql片段的用法 2.一对多查询 3.多条sql的一对多查询 4.多对一查询 5.多条sql一对多查询 6.多对多查询 这里 ...
- 统一资源定位符URL
Uniform Resource Locate--URL 用途:通过URL访问web网页:通过URL使用其它的Internet应用程序,例如FTP,Telnet(远程登录服务):对应IE浏览器窗口中的 ...