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

分享个Canvas粉尘态粒子引力效应

主要特点:

鼠标移动会被依附追随

鼠标点击会被弹开

鼠标拖动会以一定的范围弹开

HTML5 Canvas粉尘态粒子引力效应

<style type="text/css">

    * {

    margin: 0;

    padding: 0;

    }

    html {

    overflow: hidden;

    }

    canvas {

    cursor: none;

    }

</style>

<!--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>

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

加QQ群:645199623(招募中)

加微❤:QD_666_QD

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 225,208评论 6 524
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,502评论 3 405
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 172,496评论 0 370
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,176评论 1 302
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,185评论 6 401
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,630评论 1 316
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,992评论 3 431
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,973评论 0 280
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,510评论 1 325
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,546评论 3 347
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,659评论 1 355
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,250评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,990评论 3 340
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,421评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,569评论 1 277
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,238评论 3 382
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,732评论 2 366

推荐阅读更多精彩内容