浏览其它浏览器页面的时候看到一个小球动态效果,就自己写了一个,如下图
过程也很简单
封装个随机数
声明一个绘制小球的类
更新小球位置
监听鼠标移动更新小球位置
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>阁下</title>
<style>
html,
body {
margin: 0;
padding: 0;
height: 100%;
box-sizing: border-box;
}
#canvas {
background-color: rgb(0, 0, 0);
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var xZou=0,yZou=0;
function resizeFn(){
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
resizeFn();
// 随机数
function getRandom(min,max){
return Math.floor(Math.random() * (max + 1 -min) + min);
}
class Point {
constructor(){
this.r = 10;//小球半径
this.x = getRandom(0,canvas.width - this.r);//小球x坐标
this.y = getRandom(0,canvas.height - this.r);//小球y坐标
this.xSpeed = getRandom(-3,3);//x轴速度
this.ySpeed = getRandom(-3,3);//y轴速度
this.speed = 50;//小球跟随鼠标移动速度
this.temp = 0;//小球是否跟随鼠标移动 0 不移动 1 移动
this.flag = null;
}
// 绘制单个小球
draw(){
if(this.flag){
if(this.temp == 1){
//缓慢移动
this.x = this.x + (xZou - this.x) / this.speed;
this.y = this.y + (yZou - this.y) / this.speed;
}else{
//超出屏幕返回
if(this.x <= this.r || this.x >= canvas.width - this.r) this.xSpeed *= -1;
if(this.y <= this.r || this.y >= canvas.height - this.r) this.ySpeed *= -1;
this.x = this.x + this.xSpeed;
this.y = this.y + this.ySpeed;
}
}
// 绘制小球
ctx.beginPath();
ctx.arc(this.x,this.y,this.r,0,2 * Math.PI,false);
ctx.fillStyle = "rgba(200,200,200,.6)";
ctx.fill();
this.flag = true;
}
}
// 更新
class Update {
//list 小球数量 distance 小球之间连线最大距离
constructor(list = 50,distance = 200){
this.arr = new Array(list).fill(0).map(() => new Point());
this.distance = distance;
}
draw(){
window.requestAnimationFrame(() => this.draw());
ctx.clearRect(0,0,canvas.width,canvas.height);
for(let i = 0;i<this.arr.length;i++){
//根据小球和鼠标的距离判断是否大于distance
let l = Math.sqrt((this.arr[i].x - xZou) ** 2 + (this.arr[i].y - yZou) ** 2);
if(l > this.distance){
this.arr[i].temp = 0;
}else{
this.arr[i].temp = 1;
}
// 绘制小球
this.arr[i].draw();
for(let j = i + 1;j<this.arr.length;j++){
let d = Math.sqrt((this.arr[i].x - this.arr[j].x) ** 2 + (this.arr[i].y - this.arr[j].y) ** 2);
if(d > this.distance) continue;
// 绘制线
ctx.beginPath();
ctx.moveTo(this.arr[i].x,this.arr[i].y);
ctx.lineTo(this.arr[j].x,this.arr[j].y);
ctx.strokeStyle = `rgba(255,255,255,0.3)`;
ctx.stroke();
}
}
}
}
canvas.addEventListener('mousemove',function(e){
xZou = e.clientX;
yZou = e.clientY;
})
const update = new Update();
update.draw();
</script>
</body>
</html>