其实用Canvas 实现粒子效果 很简单。
知道 Canvas 怎么画出 圆形( arc 函数 ), 圆形的移动就是 arc 函数 定位参数变化的问题。
// x、y 变化 并且 每帧重绘 ,让我们看 圆形 像是 动起来了
context.arc(x,y,r,sAngle,eAngle,counterclockwise);
//获取 页面上 canvas 标签
var myCavans = document.getElementById('myCavans');
//设置 canvas画布的 width height (window的width、height ,全屏展示)
myCavans.width = window.innerWidth;
myCavans.height = window.innerHeight;
// 定义画布 2D 画布 ,获取 上下文 。
var ctx = myCavans.getContext('2d');
// 初始化 鼠标位置
let mouse = {
x: 0,
y: 0
}
// 绑定 鼠标移动事件,修改 mouse 对象中的 鼠标坐标 。
window.addEventListener('mousemove', function (event) {
mouse.x = event.clientX;
mouse.y = event.clientY;
})
// 绑定 浏览器大小变化 监听,动态调整canvas画布 width height
window.addEventListener('resize', function () {
myCavans.width = window.innerWidth;
myCavans.height = window.innerHeight;
})
// 节点 最大半径,防止鼠标靠近方法中的 节点无限制变大
let maxRadius = 40;
// 节点对象
/**
* x,y 代表 浏览器绘制 节点的坐标
* dx,dy 代表 节点移动的速度
* r 半径
* color 节点颜色
*/
function Ball(x, y, dx, dy, r, color) {
this.x = x;
this.y = y;
this.dx = dx;
this.dy = dy;
this.r = r;
this.color = color;
// 节点绘制方法
this.draw = function () {
// 新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。
ctx.beginPath();
// 定义画笔 颜色
ctx.fillStyle = this.color;
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
// 通过填充路径的内容区域生成实心的图形。
ctx.fill();
// 闭合路径之后图形绘制命令又重新指向到上下文中。
ctx.closePath();
}
// 更新 节点 每个属性(以达到 漂浮效果、鼠标靠近、鼠标远离等效果)
this.update = function () {
// 防止 X轴 节点生成到 边界外边 或者 边界上 。
if ((this.x + this.r) > myCavans.width || (this.x - this.r) < 0) {
this.dx = -this.dx;
}
// 防止 Y轴 节点生成到 边界外边 或者 边界上。
if ((this.y + this.r) > myCavans.height || (this.y - this.r) < 0) {
this.dy = -this.dy;
}
// 时刻变化的 x、y 就是 节点移动的奥秘。 dx、dy 就是节点移动速度调节参数。
this.x = this.x + this.dx;
this.y = this.y + this.dy;
// 每一帧刷新 画布 会 遍历所有节点 ,计算 所有节点 距离 鼠标的像素值, 靠近鼠标节点半径变大,远离则变小
if (mouse.x - this.x < 50 && mouse.x - this.x > -50
&& mouse.y - this.y < 50 && mouse.y - this.y > -50) {
if (this.r < maxRadius) {
this.r++;
}
} else {
if (this.r > r) {
this.r--;
}
}
this.draw();
}
}
let ballArr = [];
let colorArr = ['#248EA6', '#25C7D9', '#F2D338', '#F2762E', '#F23030'];
// 循环 随机属性生成 300个节点
for (let i = 0; i < 300; i++) {
let radius = Math.random() * 4 + 1;
let x = Math.random() * (myCavans.width - 2 * radius) + radius;
let y = Math.random() * (myCavans.height - 2 * radius) + radius;
let dx = (Math.random() - 0.5) * 2;
let dy = (Math.random() - 0.5) * 2;
let color = colorArr[Math.floor(Math.random() * 5)];
let ball = new Ball(x, y, dx, dy, radius, color);
ballArr.push(ball);
}
// 动画
function animate() {
//
// 浏览器 每一帧 调用一次 指定的函数
requestAnimationFrame(animate);
ctx.clearRect(0, 0, myCavans.width, myCavans.height);
// 遍历 节点数组 ,执行节点对象 update 函数
for (let ball of ballArr) {
ball.update();
}
}
animate();