废话不说先上图:

关于这个效果我第一次见是在
https://www.mengxiaozhu.cn/
后来知乎登录页也开始用了
https://www.zhihu.com/
网络上还有很多地方都在用,效果还是不错的。
我见了之后觉得挺有意思的就研究了一下原理
下面开始coding:
先写个canvas标签

<canvas height="620" width="1360" id="canvas"></canvas>

加上一些默认的样式:

*{margin:0;padding:0;
}
body{overflow: hidden;
}

这里的overflow:hidden是为了防止出现滚动条
下面开始写JS:
首先我们要得到那个 canvas 并得到绘制上下文:

var canvasEl = document.getElementById('canvas');
var ctx = canvasEl.getContext('2d');
var mousePos = [0, 0];

紧接着我们声明两个变量,分别用于存储“星星”和边:

var nodes = [];
var edges = [];

然后我们定义一些其他的变量:

var easingFactor = 5.0;  //缓动因子
var backgroundColor = '#000'; //背景颜色
var nodeColor = '#fff'; //点颜色
var edgeColor = '#fff'; //边颜色
var pageWidth = window.innerWidth, //窗口宽度 pageHeight = window.innerHeight; //窗口高度

设置画布的大小铺满整个屏幕:

window.onresize = function () {canvasEl.width = pageWidth;canvasEl.height = pageHeight;if (nodes.length == 0) {constructNodes();}render();
};window.onresize(); 

准备工作完成,我们要开始构建点了:

function constructNodes() {for (var i = 0; i < 100; i++) {var node = {drivenByMouse: i == 0,x: Math.random() * canvasEl.width,y: Math.random() * canvasEl.height,vx: Math.random() * 1 - 0.5,vy: Math.random() * 1 - 0.5,radius: Math.random() > 0.9 ? 3 + Math.random() * 3 : 1 + Math.random() * 3};nodes.push(node);}nodes.forEach(function (e) {nodes.forEach(function (e2) {if (e == e2) {return;}var edge = {from: e,to: e2}addEdge(edge);});});
}

先创建100个点,每个点设置6个属性,drivenByMouse属性只有第一个点为true,其他的点为false,第一个点作为鼠标跟随点,不显示出来,可以与其他点连线。x,y作为点的初始位置,取得是画布内的随机点,vx,vy表示点的初始速度,范围为-0.5到0.5之间的随机数,radius表示点的半径,大部分的点为小的,少数的点为大的。

点都构建完毕了,就要构建点与点之间的连线了,我们用到双重遍历,把两个点捆绑成一组,放到 edges 数组中。注意这里我用了另外一个函数来完成这件事,而没有直接用 edges.push() ,为什么?

假设我们之前连接了 A、B两点,也就是外侧循环是A,内侧循环是B,那么在下一次循环中,外侧为B,内侧为A,是不是也会创建一条边呢?而实际上,这两个边除了方向不一样以外是完全一样的,这完全没有必要而且占用资源。因此我们在 addEdge 函数中进行一个判断:

function addEdge(edge) {var ignore = false;edges.forEach(function (e) {if (e.from == edge.from & e.to == edge.to) {ignore = true;}if (e.to == edge.from & e.from == edge.to) {ignore = true;}});if (!ignore) {edges.push(edge);}
}

至此,我们的准备工作就完毕了,下面我们要让点动起来:

function step() {nodes.forEach(function (e) {if (e.drivenByMouse) {return;}e.x += e.vx;e.y += e.vy;function clamp(min, max, value) {if (value > max) {return max;} else if (value < min) {return min;} else {return value;}}if (e.x <= 0 || e.x >= canvasEl.width) {e.vx *= -1;e.x = clamp(0, canvasEl.width, e.x)}if (e.y <= 0 || e.y >= canvasEl.height) {e.vy *= -1;e.y = clamp(0, canvasEl.height, e.y)}});adjustNodeDrivenByMouse();render();window.requestAnimationFrame(step);
}function adjustNodeDrivenByMouse() {nodes[0].x += (mousePos[0] - nodes[0].x) / easingFactor;nodes[0].y += (mousePos[1] - nodes[0].y) / easingFactor;
}

这段代码就是遍历粒子,并且更新其状态。根据一个简单的物理公式 s = s + v,每次执行都会 更新到点的下一步的状态。
adjustNodeDrivenByMouse函将第一个点作为鼠标的跟随点,easingFactor为缓动因子可以让点的运动比鼠标运动的稍慢一点。
然后我们要让整个粒子系统连续地运转起来就需要一个timer了,但是十分不提倡大家使用 setInterval,而是尽可能使用 requestAnimationFrame,它能保证你的帧率锁定在当前浏览器的频率下,一般为60HZ。

剩下的就是绘制了

function render() {ctx.fillStyle = backgroundColor;ctx.fillRect(0, 0, canvasEl.width, canvasEl.height);edges.forEach(function (e) {var l = lengthOfEdge(e);var threshold = canvasEl.width / 8;if (l > threshold) {return;}ctx.strokeStyle = edgeColor;ctx.lineWidth = (1.0 - l / threshold) * 2.5;ctx.globalAlpha = 1.0 - l / threshold;ctx.beginPath();ctx.moveTo(e.from.x, e.from.y);ctx.lineTo(e.to.x, e.to.y);ctx.stroke();});ctx.globalAlpha = 1.0;nodes.forEach(function (e) {if (e.drivenByMouse) {return;}ctx.fillStyle = nodeColor;ctx.beginPath();ctx.arc(e.x, e.y, e.radius, 0, 2 * Math.PI);ctx.fill();});
}
function lengthOfEdge(edge) {return Math.sqrt(Math.pow((edge.from.x - edge.to.x), 2) + Math.pow((edge.from.y - edge.to.y), 2));
}

绘制的时候我们要判断线的长度如果大于某一个值,则不绘制该线了,如果在范围之内粗细,与颜色的透明度都与线的长度相关,点除了第一个鼠标跟随点,其他的画入即可。
最后加入鼠标移动事件,启动定时器:

window.onmousemove = function (e) {mousePos[0] = e.clientX;mousePos[1] = e.clientY;
}window.requestAnimationFrame(step);

大功告成!!

canvas绘制经典星空连线效果相关推荐

  1. 【Canvas】js用canvas绘制一个钟表时钟动画效果

    学习JavaScript的看过来,有没有兴趣用Canvas画图呢,可以画很多有趣的事物,自由发挥想象,收获多多哦,旋转角度绘图这个重点掌握到了吗,这里有一个例子,如何用canvas画钟表时钟动图效果, ...

  2. H5 Canvas绘制圆形进度条动画效果

    效果如图 效果比较简单 html结构部分 <canvas id="canvas" width="110" height="110"&g ...

  3. canvas绘制经典折线图(一)

    最终效果图如下: 实现步骤如下:注-引用了jQuery HTML代码 <!doctype html> <html lang="en"> <head&g ...

  4. 【Canvas】js用Canvas绘制漩涡螺旋图动画效果

    学习JavaScript编程,会用Canvas画图吗,学会它,能画很多有趣的事物,可自由发挥想象,会发现图形学的美,收获很多,这里有一个例子,如何用canvas画漩涡螺旋图动图效果,接下来开始讲,边学 ...

  5. HTML粒子漩涡特效,使用HTML5 Canvas绘制经典漩涡粒子特效

    JavaScript 语言: JaveScriptBabelCoffeeScript 确定 // create a canvas element var canvas = document.creat ...

  6. canvas绘制飞线效果

    在我们做的可视化大屏项目中,经常会遇到飞线的效果. 在我们的大屏编辑器中,可以通过拖拽+配置参数的方式很快就能够实现.下面是我们使用大屏编辑器实现的一个项目效果: 中间地图就有飞线的效果. 抛开编辑器 ...

  7. Canvas学习:封装Canvas绘制基本图形API

    Canvas学习:封装Canvas绘制基本图形API Canvas Canvas学习 从前面的文章中我们了解到,通过Canvas中的CanvasRenderingContext2D对象中的属性和方法, ...

  8. svg绘制蝌蚪状飞线

    svg绘制蝌蚪状飞线 效果如图: 飞线效果在可视化中很常见,有了它整个屏幕好像添加了一个小精灵一样充满活力.

  9. 用html5做一条线,使用HTML5 canvas绘制线条的方法

    使用HTML5 canvas绘制线条的方法 发布时间:2020-08-29 11:24:23 来源:亿速云 阅读:96 作者:小新 这篇文章主要介绍了使用HTML5 canvas绘制线条的方法,具有一 ...

  10. 使用 HTML5 Canvas 绘制出惊艳的水滴效果

    HTML5 在不久前正式成为推荐标准,标志着全新的 Web 时代已经来临.在众多 HTML5 特性中,Canvas 元素用于在网页上绘制图形,该元素标签强大之处在于可以直接在 HTML 上进行图形操作 ...

最新文章

  1. 机器学习中的梯度下降( Gradient Descent)算法
  2. Linux Kernel TCP/IP Stack — L1 Layer — Physical NIC
  3. 用Perl发送邮件小例子
  4. connect函数介绍
  5. Java 将 Word 文档转换为 PDF 的完美工具
  6. How can ifm help the SME WELL?
  7. 以ThreadStart方式实现多线程
  8. 库卡机器人CELL程序解析
  9. java与算法_Java与算法之(1) - 冒泡排序
  10. torch.stack作用分析
  11. java实现人字拼,人字拼地板拼法大全
  12. 恐龙机器人钢索恐龙形态_?四川自贡发现距今1.6亿年恐龙化石 已运抵自贡恐龙博物馆...
  13. python数据分析推荐课程_coursera上有哪些值得学习的Python,数据分析的课程
  14. Linux内核编程《一》
  15. Java中常见的异常举例
  16. AVR 上的汇编圈圈操作系统
  17. 计算机主板电源线接法,主板电源线怎么接
  18. 谷歌浏览器配置微信浏览器_微信网页版 - Chrome社交与通讯插件 - 画夹插件网
  19. Jaspergold形式验证-vhdl语言
  20. linux下WMB通过ODBC连接数据库

热门文章

  1. python入门11 元组tuple
  2. Python学习:3.Python学习基础
  3. SQL server 数据库调用远程数据库存储过程的实现方法
  4. Ansible@一个高效的配置管理工具--Ansible configure management--翻译(十一)
  5. Delphi之TStrings和TStringLists类【转】
  6. 修改Linux默认启动级别或模式的方法
  7. 游戏服务器mysql封装_游戏服务端之C++封装Mysql
  8. storm1.x支持主节点nimbus高可用 多master集群部署
  9. 【第40题】2019年OCP认证12C题库062考试最新考试原题
  10. 洛谷——P1744 采购特价商品