HTML5 Canvas很酷炫的粉尘态粒子引力效应

原创 前端彭于晏 随笔 前端 76阅读 16 天前 举报

分享个Canvas粉尘态粒子引力效应
主要特点:
鼠标移动会被依附追随
鼠标点击会被弹开
鼠标拖动会以一定的范围弹开
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML5 Canvas粉尘态粒子引力效应</title>

<style type="text/css">
    * {
    margin: 0;
    padding: 0;
    }
    html {
    overflow: hidden;
    }
    canvas {
    cursor: none;
    }
</style>

</head>
<body>
<canvas id=canvas></canvas>

<!--move mouse or click -->

<script type="text/javascript">
window.onload = function() {

    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");

    var pi = Math.PI;

    var centerX, centerY;
    var part_num = 2000; //粒子数量

    var mousedown = false;
    var X, Y;  //鼠标坐标

    var P = [];
    var part = function(x, y, vx, vy, r, red, green, blue, alpha, col) {
  this.x = x;
  this.y = y;
  this.vx = vx; //初始向左移动
  this.vy = vy; //初始向右移动
  this.r = r;  //大小
  this.red = red;
  this.green = green;
  this.blue = blue;
  this.alpha = alpha;
  this.col = col;
};

window.onmousemove = function(e) {
    X = e.clientX;
    Y = e.clientY;
}

window.onmousedown = function() {
    mousedown = true;
}

window.onmouseup = function() {
    mousedown = false;
}

var mouseover = false;
window.onmouseover = function() {
    mouseover = true;
}

window.onmouseout = function() {
    mouseover = false;
}

function rand(min, max) {
    return Math.random() * (max - min) + min;
}

function dist(dx, dy) {
    return Math.sqrt(dx * dx + dy * dy);
}

function size() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    centerX = canvas.width / 2;
    centerY = canvas.height / 2;
}

size();
X = centerX;
Y = centerY;

function init() {
  var x, y, vx, vy, r, red, green, blue, alpha, col;
  for (var i = 0; i < part_num; i++) {
    x = rand(0, canvas.width);
    y = rand(0, canvas.height);
    vx = rand(-5, 5);
    vy = rand(-5, 5);
    r = rand(1, 10);
    red = Math.round(rand(150, 200));
    green = Math.round(rand(100, 255));
    blue = Math.round(rand(180, 255));
    alpha = 1;
    col = "rgba(" + red + "," + green + "," + blue + "," + alpha + ")";

    P.push(new part(x, y, vx, vy, r, red, green, blue, alpha, col));
  }
}
// 背景绘制
function bg() {
    // 使用 fillStyle 属性来设置用于填充绘图的颜色
    ctx.fillStyle = "raba(25,25,30,1)";
    // 使用fillRect() 方法绘制“已填色”的矩形
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    //clearRect() 方法清空给定矩形内的指定像素
    // ctx.clearRect(0, 0, canvas.width, canvas.height);
}

//鼠标吸引
function attract(p) {
    var dx = (p.x - X),
            dy = (p.y - Y),
            dist = Math.sqrt(dx * dx + dy * dy),  //返回距离(平方根)
            angle = Math.atan2(dy, dx);   //返回坐标(dx,dy)与 X轴之间的角度的弧度

    if(dist > 50 && dist < 500) {
        if(!mousedown) {
            p.vx -= (200 / (p.r * dist)) * Math.cos(angle);
            p.vy -= (200 / (p.r * dist)) * Math.sin(angle);
        } else if(mousedown) {
            p.vx += (300 / (p.r * dist)) * Math.cos(angle);
            p.vy += (300 / (p.r * dist)) * Math.sin(angle);
        }
    }
}

//粒子弹弹弹
function bounce(b) {
    if(b.x < b.r) {
        b.x = b.y;
        b.vx *= -3;
    }
    if(b.x > canvas.width - b.r) {
        b.x = canvas.width - b.r;
        b.vx *= -3;
    }

    if(b.y - b.r < 0) {
        b.y = b.r;
        b.vy *= -3;
    }
    if(b.y > canvas.height - b.r) {
        b.y = canvas.height - b.r;
        b.vy *= -3;
    }
}

// 鼠标拖动
function draw() {
    var p;
    for(var i = 0; i < P.length; i++) {
        p = P[i];

        if(mouseover) attract(p);
        bounce(p);

        p.x += p.vx;
        p.y += p.vy;

        p.vx *= .975;
        p.vy *= .975;

        ctx.fillStyle = p.col;
        ctx.fillRect(p.x, p.y, p.r, p.r);
    }
    ctx.strokeStyle = (!mousedown) ? "rgba(0,0,0,,1)" : "rgba(255,0,0,1)";

    ctx.beginPath();
    ctx.moveTo(X, Y - 10);
    ctx.lineTo(X, Y + 10);
    ctx.moveTo(X - 10, Y);
    ctx.lineTo(X + 10, Y);
    ctx.stroke();
}

function loop() {
    bg();
    draw();
    window.requestAnimationFrame(loop);
}
// 事件
window.onresize = size;

    // 初始化
    init();
loop();

}
</script>

</body>
</html>

“我自己是一名从事了5年前端的老程序员,辞职目前在做讲师,今年年初我花了一个月整理了一份最适合2019年学习的web前端干货,从最基础的HTML+CSS+JS到移动端HTML5到各种框架都有整理,送给每一位前端小伙伴,这里是小白聚集地,欢迎初学和进阶中的小伙伴。"

加QQ群:645199623(招募中)


加微❤:QD_666_QD


评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复