原生JS Canvas 粒子漂浮 效果 (详细注释)

 

其实用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();

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值