很多个点,很多条线,相互链接与断开的效果怎么做?
其实没有想象中的那么难,要实现就一个canvas画布 + js 的事件以及数学逻辑,就可以实现,废话不多说先上效果图
html部分
<body>
<canvas id="tutorial"></canvas>
<script src="./index.js"></script>
</body>
样式部分
<style>
canvas {
position: fixed;
top: 0;
left: 0;
background-color: black;
}
</style>
JS 主体部分
// 获取实例 ,设置画布
let canvas = document.querySelector("canvas");
let ctx = canvas.getContext("2d");
// 画布窗口大小设置 , devicePixelRatio是为了等比缩放保持清晰度
function init() {
canvas.width = window.innerWidth * devicePixelRatio;
canvas.height = window.innerHeight * devicePixelRatio;
}
init(); //打开画布
// 设置一个随机数产生方法
function getRandom(min, max) {
// console.log(min, max, 'min, max')
return Math.floor(Math.random() * (max + 1 - min) + min);
}
class Point {
/**
* devicePixelRatio 解决缩放图片清晰度 放大倍率缩放
*/
constructor () {
this.r = 4 * devicePixelRatio;
this.x = getRandom(0, canvas.width - this.r / 2);
this.y = getRandom(0, canvas.height - this.r / 2);
this.xSpeed = getRandom(-50, 50); //坐标移动速度
this.ySpeed = getRandom(-50, 50);
this.lastDrawTime = null; // 上一次作画时间
}
draw() {
// 更新坐标
if (this.lastDrawTime) {
// 计算新坐标
const duration = (Date.now() - this.lastDrawTime) / 1000; // 时间差 秒
// console.log(duration, 'duration==')
// 距离
const xDis = this.xSpeed * duration, yDis = this.ySpeed * duration;
let x = this.x + xDis, y = this.y + yDis;
// 超出 边界回弹
if (x > canvas.width - this.r / 2) {
x = canvas.width - this.r / 2;
this.xSpeed = - this.xSpeed;
} else if (x < 0) {
x = 0;
this.xSpeed = - this.xSpeed;
};
if (y > canvas.height - this.r / 2) {
y = canvas.height - this.r / 2;
this.ySpeed = - this.ySpeed;
} else if (y < 0) {
y = 0;
this.ySpeed = - this.ySpeed;
}
this.x = x;
this.y = y;
}
ctx.beginPath();
// console.log(this.x, this.y, 'this.x, this.y')
// 参数 x,y轴 ,圆弧半径,初始弧度,结束弧度, 顺时针/逆时针
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, true);
ctx.fillStyle = '#fff'; // 填充颜色
ctx.fill(); // 执行填充
this.lastDrawTime = Date.now();
}
};
class Graph {
constructor (pointNumber = 50, maxDis = 200) {
this.points = new Array(pointNumber).fill(0).map(() => new Point())
this.maxDis = maxDis;
}
draw() {
// 请求执行动画函数
requestAnimationFrame(() => {
this.draw()
});
ctx.clearRect(0, 0, canvas.width, canvas.height); // 清空 画布
for (let i = 0; i < this.points.length; i++) {
const p1 = this.points[i];
p1.draw();
for (let j = i + 1; j < this.points.length; j++) {
const p2 = this.points[j];
const d = Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);
if (d > this.maxDis) {
continue;
}
ctx.beginPath()
// 开始画一条路径 x,y 轴
ctx.moveTo(p1.x, p1.y);
// 连线
ctx.lineTo(p2.x, p2.y);
ctx.strokeStyle = `rgba(200,200,200,${1 - d / this.maxDis})`; // 设置颜色
ctx.stroke();
}
}
}
}
const g = new Graph().draw();