正在召唤神秘力量
导航

萌即是正义!时不时分享一些ACG活动记录与有趣代码的小站!

用canvas做 精灵 | 光点 | 粒子 | 光子 飘动的效果

作者:广树·时间:2018-03-08 17:01:04·分类:JavaScript/jQuery/Vue

前面做《四女神Online》模板的时候参照code pen上的一则飘雪效果改的。

首先引入HTML并想好canvas的ID:

<canvas id='canvasbg' class="star_effect"></canvas>

然后引入JS:

(function() {

    var Base, Particle, canvas, colors, context, drawables, i, mouseX, mouseY, mouseVX, mouseVY, rand, click, min, max, colors, particles, Cwidth, Cheight, GradientColors, CanvasEl;

    CanvasEl = "canvasbg"; //Canvas的ID
    min = 1; //最小光点直径
    max = 4; //最大光点直径
    particles = 200; //光点数量
    Cwidth = 800; //画布宽度
    Cheight = 600; //画布高度
    colors = ["255, 255, 255", "250, 150, 20", "255, 100, 255"]; //光点中间的颜色注意和晕开颜色顺序配对
    GradientColors = ["84,204,243", "250,150,20", "255, 100, 255"]; //光点晕开的颜色色注意和中间颜色顺序配对
    rand = function(a, b) {
        return Math.random() * (b - a) + a;
    };

    Particle = (function() {
        function Particle() {
            this.reset();
        }

        Particle.prototype.reset = function() {
            var colorSel = Math.random();
            this.color = colors[~~ (colorSel * colors.length)];
            this.GradientColors = GradientColors[~~ (colorSel * GradientColors.length)];
            this.radius = rand(min, max);
            this.x = rand(0, canvas.width);
            this.y = rand(60, canvas.height);
            this.vx = -5 + Math.random() * 10;
            this.vy = (Math.random() - 0.5) * this.radius;
            this.valpha = rand(0.02, 0.09);
            this.opacity = 0;
            this.life = 0;
            this.onupdate = undefined;
            this.type = "dust";
        };

        Particle.prototype.update = function() {
            this.x = (this.x + this.vx / 6);
            this.y = (this.y + this.vy / 6);

            if (this.opacity >= 1 && this.valpha > 0) this.valpha *= -1;
            this.opacity += this.valpha / 8;
            this.life += this.valpha / 8;

            if (this.type === "dust") this.opacity = Math.min(1, Math.max(0, this.opacity));
            else this.opacity = 1;

            if (this.onupdate) this.onupdate();
            if (this.life < 0 || this.radius <= 0 || this.y > canvas.height) {
                this.onupdate = undefined;
                this.reset();
            }
        };

        Particle.prototype.draw = function(c) {
            var grd = c.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.radius * 4);
            grd.addColorStop(0, "rgba(" + this.GradientColors + ", " + Math.min(this.opacity - 0.2, 0.65) + ")");
            grd.addColorStop(1, "rgba(" + this.GradientColors + ", " + '0' + ")");
            c.fillStyle = grd;

            c.beginPath();
            c.arc(this.x, this.y, this.radius * 4, 2 * Math.PI, false);
            c.fill();

            c.strokeStyle = "rgba(" + this.color + ", " + Math.min(this.opacity, 0.85) + ")";
            c.fillStyle = "rgba(" + this.color + ", " + Math.min(this.opacity, 0.65) + ")";
            c.beginPath();
            c.arc(this.x, this.y, this.radius, 2 * Math.PI, false);
            c.fill();
        };

        return Particle;

    })();

    mouseVX = mouseVY = mouseX = mouseY = 0;

    canvas = document.getElementById(CanvasEl);
    context = canvas.getContext("2d");
    canvas.width = Cwidth;
    canvas.height = Cheight;

    drawables = (function() {
        var _i, _results;
        _results = [];
        for (i = _i = 1; _i <= particles; i = ++_i) {
            _results.push(new Particle);
        }
        return _results;
    })();

    function draw() {
        window.requestAnimFrame(draw);
        var d, _i, _len;
        canvas.width = Cwidth;
        canvas.height = Cheight;
        context.clearRect(0, 0, canvas.width, canvas.height)

        for (_i = 0, _len = drawables.length; _i < _len; _i++) {
            d = drawables[_i];
            d.draw(context);
        }
    };

    function update() {
        window.requestAnimFrame(update);
        var d, _i, _len, _results;
        _results = [];
        for (_i = 0, _len = drawables.length; _i < _len; _i++) {
            d = drawables[_i];
            _results.push(d.update());
        }
        return _results;
    };

    document.onmousemove = function(e) {
        mouseVX = mouseX;
        mouseVY = mouseY;
        mouseX = ~~e.pageX;
        mouseY = ~~e.pageY;
        mouseVX = ~~ ((mouseVX - mouseX) / 2);
        mouseVY = ~~ ((mouseVY - mouseY) / 2);

    };

    window.addEventListener('resize', draw, false);
    window.requestAnimFrame = (function() {
        return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame ||
        function(callback) {
            window.setTimeout(callback, 1000 / 60);
        };
    })();
    window.requestAnimFrame(draw);
    window.requestAnimFrame(update);
}).call(this);


可设置的参数有:
CanvasEl = "canvasbg";//Canvas的ID
min = 1;//最小光点直径
max = 4;//最大光点直径
particles = 200;//光点数量
Cwidth = 800;//画布宽度
Cheight = 600;//画布高度
colors = ["255, 255, 255","250, 150, 20","255, 100, 255"];//光点中间的颜色注意和晕开颜色顺序配对
GradientColors = ["84,204,243","250,150,20","255, 100, 255"];//光点晕开的颜色色注意和中间颜色顺序配对
注意:光点和光晕的顺序是配对的,比如第一个光点会搭配第一个光晕。






侧边栏
最新评论
广树
2024-04-24
@粽叶加米:我的体验是不好用还贵,等产品过期了一个个转移
广树
2024-04-24
@test_user:bloghub不是我开发的呢,只不过是收录了我的博客。
test_user
2024-04-24
@广树:不是大佬。。。,相比之下我更敬佩你,我是通过 bloghub 的 rss 订阅收到这条 topic 的,你回复我之后我才看了下, bloghub 是你的作品,你还有一些其他落地的作品,我很喜欢你这这样的实干家。 我前些年才意识到记录的重要性,以前去哪里都不会拍照,现在无论是网上的,还是线下的,都尽可能的记录下来了。。,记忆太不可靠了。。
粽叶加米
2024-04-24
我用了一年他的邮箱服务,不好不坏,后来转到Icloud+自定义邮箱了。
广树
2024-04-24
@Chise Hachiroku:是大佬!膜拜! 百度这样的模式真的不是作茧自缚吗?信息越来越狭小。
正在攻略

圣兽之王.jpg

传颂之物

PSN奖杯卡

PSN奖杯卡

赞助商广告