1.国际惯例,先上效果图
2.查看演示请看 这里 。
3 代码
html:
<canvas id="canvas" width="1920" height="1080"></canvas>
js: 这代码看起来可以说十分直白了,注释不放过任何一个角落。
var canvas = document.getElementById(‘canvas‘); var width = document.documentElement.clientWidth; var height = document.documentElement.clientHeight; canvas.width = width; canvas.height = height; var ctx = canvas.getContext(‘2d‘); var PI = Math.PI; // 点的数量 var point_count = 100; // 存放点的数组 var point_list = new Array(point_count); // 最大点间距 var max_space = 50; // 每次更新位置最大的行进距离 var max_speed = 1; // 点的半径 var point_r = 3; // 线宽 var lineWidth = 1; var strokeStyle = ‘#2779D7‘; var fillStyle = ‘#2779D7‘; for (var i = 0; i < point_count; i++) { point_list[i] = { // x 轴位置 x: Math.round(Math.random() * (width - point_r * 2)), // y 轴位置 y: Math.round(Math.random() * (height - point_r * 2)), // x 轴速度 speedX: Math.random() * max_speed * 2 - max_speed, // y 轴速度 speedY: Math.random() * max_speed * 2 - max_speed, } } function update() { point_list.forEach(function (value) { // 更新位置信息 value.x += value.speedX; value.y += value.speedY; // 超出屏幕后 在屏幕另一侧对应位置出现 // if (value.x > width + max_space) value.x = -max_space; // if (value.x < -max_space) value.x = width + max_space; // if (value.y > height + max_space) value.y = -max_space; // if (value.y < -max_space) value.y = height + max_space; // 碰壁反弹 if (value.x > width || value.x < 0) value.speedX = -value.speedX; if (value.y > height || value.y < 0) value.speedY = -value.speedY; }) } function draw() { var arr = point_list; ctx.clearRect(0, 0, width, height) ctx.strokeStyle = strokeStyle; ctx.fillStyle = fillStyle; ctx.lineWidth = lineWidth; for (var i = 0; i < arr.length; i++) { ctx.beginPath() ctx.globalAlpha = 1 ctx.arc(arr[i].x, arr[i].y, point_r, 0, PI * 2) ctx.fill() for (var j = i + 1; j < arr.length; j++) { // 计算每两个点的距离, 三角形的斜边 的平方 = 两直角边平方和 var s = max_space - Math.sqrt((arr[j].x - arr[i].x) * (arr[j].x - arr[i].x) + (arr[j].y - arr[i].y) * (arr[j].y - arr[i].y)); // 计算的两点之间线的透明度,如果距离小于最大距离 透明度为 1 , 如果大于 最大距离小于 1.5倍最大距离,透明度线性衰减,大于1.5倍时透明度为0 var opc = (s >= 0 ? 1 : (s < - max_space / 2) ? 0 : 1 - s / - max_space * 2); // 通过线透明度判断是否需要画线,如果透明度大于零,就划线。 if (opc > 0) { ctx.beginPath(); ctx.globalAlpha = opc; // 画直线 // ctx.moveTo(arr[i].x, arr[i].y); // ctx.lineTo(arr[j].x, arr[j].y); // 画贝塞尔曲线 ctx.moveTo(arr[i].x, arr[i].y); ctx.bezierCurveTo(arr[i].x, arr[i].y + (arr[j].y - arr[i].y) * 0.5, arr[i].x + arr[j].x - arr[i].x, arr[i].y + (arr[j].y - arr[i].y) * 0.5, arr[j].x, arr[j].y); ctx.stroke(); } } } // 更新位置 update(); } function loop() { // 循环程序 draw(); setTimeout(loop, 1000/60) } window.onload = loop;
()