Canvas实现小星星闪烁效果

html结构:

<div>
    <img src="banner01.jpg" alt="">
    <canvas></canvas>
</div>
script:

$(function () {

    //进行浏览器环境检测
    //IE版本检测,非IE浏览器返回east.NOT_IE
    var NOT_IE = 1000;
    var ieVersion;
    if(navigator.appName === "Microsoft Internet Explorer"){
        ieVersion = +navigator.appVersion.match(/MSIE (\d\d?)/)[1];
    }else if(navigator.userAgent.indexOf('Trident/7.0') !== -1){
        ieVersion = 11;
    }else{
        ieVersion = NOT_IE;
    }
    //banner画布
    if(ieVersion <= 9){
        $('<style>.opacity-zero{opacity: 1}</style>').appendTo('head');
    }

    if(ieVersion <= 8){ return; }

    var $mask = $('<img />');
    $mask.on('load', ballInit)[0].src = "banner01-mask.png";

    function ballInit(){

        //背景画布
        var $canvas = $('canvas');
        var bgCanvas = $canvas[0];
        var ctx = bgCanvas.getContext('2d');
        var width = 1920;
        var height = 642;
        /*
         var minSize = 1;
         var maxSize = 1;//实际值为maxSize的平方
         */
        var minSpeed = 0.03;
        var maxSpeed = 0.06;
        var count = 120;
        var balls = [];

        bgCanvas.width = width;
        bgCanvas.height = height;

        var getPos = (function () {
            var rate = [0.60, 0.14, 0.1, 0.06, 0.05, 0.05];
            var level = [25, 75, 125, 175, 225, 255];
            var minSize = [1, 1, 1, 0.5, 0.5, 0.5];
            var maxSize = [1.5, 1.5, 1.5, 1, 1, 0.5];

            var canvas = $('<canvas></canvas>');
            canvas.prop({width: width, height: height});
            var ctx = canvas[0].getContext('2d');
            ctx.drawImage($mask[0],0,0);
            var imageData = ctx.getImageData(0, 0, width, height).data;

            return function(){
                var x, y, type, selectType;
                type = (function(){
                    var sum = 0, r = Math.random();
                    for(var i = 0; i < rate.length; i++){
                        if(sum < r && r < sum + rate[i]){
                            return i;
                        }
                        sum += rate[i];
                    }
                })();

                do{
                    x = getRandom(0, width);
                    y = getRandom(0, height);
                    selectType = (function () {
                        var deep = imageData[(Math.round(y) * width + Math.round(x)) * 4];
                        for(var i = 0; i < level.length; i++){
                            if(deep <= level[i]){
                                return i;
                            }
                        }
                    })()
                }while(type !== selectType);
                return {x: x, y:y, minSize: minSize[type], maxSize: maxSize[type]};
            }
        })();

        function Ball(init) {//init是否为球开始初始化
            var pos = getPos();
            this.centerX = pos.x;
            this.centerY = pos.y;
            this.radius = getRandom(pos.minSize, pos.maxSize);
            this.opacity = init ? getRandom(0, 1) : 0;
            this.speed = getRandomSpeed(init);
            this.color = getRandomColor();
        }

        Ball.prototype.move = function () {
            this.opacity += this.speed;
            if (this.opacity > 1) {
                this.opacity = 1;
                this.speed *= -1;
            } else if (this.opacity < 0) {
                Ball.call(this, false);
            }
        };

        Ball.prototype.draw = function () {
            // var c = 4, r = this.radius * 3 + 10;
            var c = 0.5, r = this.radius * 0.1 + 0.1;
            ctx.beginPath();
            ctx.arc(this.centerX, this.centerY, this.radius + c + r, 0, Math.PI * 2, false);
            ctx.closePath();
            var rg = ctx.createRadialGradient(this.centerX, this.centerY, 0,
                this.centerX, this.centerY, this.radius + c + r);
            rg.addColorStop(0, this.color(this.opacity));
            rg.addColorStop(this.radius / (this.radius + c + r), this.color(this.opacity));
            rg.addColorStop((this.radius + c) / (this.radius + c + r), this.color(this.opacity * 0.2));
            rg.addColorStop(1, this.color(0));
            ctx.fillStyle = rg;
            ctx.fill();
        };

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

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

        function getRandomSpeed(negative) {
            var speed = getRandom(minSpeed, maxSpeed);
            return negative ? -speed : speed;
        }

        function getRandomColor() {
            var rgb = HSB2RGB(
                getRandom(15, 45),
                getRandom(0, 0.5),
                getRandom(0.98, 0.99)
            );
            return function (opacity) {
                return "rgba(" + Math.floor(rgb[0]) + ","
                    + Math.floor(rgb[1]) + ","
                    + Math.floor(rgb[2]) + ","
                    + opacity.toFixed(3) + ")";
            }
        }

        for (var i = 0; i < count; i++) {
            var ball = new Ball(true);
            balls.push(ball);
        }

        var f = 0, frames = 2;//控制几帧刷新一次
        (function startAnimation() {
            f++;
            f %= frames;
            if (f == 0) {
                ctx.clearRect(0, 0, width, height);
                for (var i = 0; i < balls.length; i++) {
                    balls[i].move();
                    balls[i].draw();
                }
            }
            requestAnimationFrame(arguments.callee);
        })();

        function HSB2RGB(h, s, b) {//HSB =>> RGB
            var hsb = [h, s, b],
                r = 0, g = 0, b = 0,
                rgb = [255, 0, 0];//排序方式为主色、辅色、次辅色,非RGB
            if (hsb[0] <= 60) {
                r = 0;
                g = 1;
                b = 2;
            } else if (hsb[0] <= 120) {
                g = 0;
                r = 1;
                b = 2;
            } else if (hsb[0] <= 180) {
                g = 0;
                b = 1;
                r = 2;
            } else if (hsb[0] <= 240) {
                b = 0;
                g = 1;
                r = 2;
            } else if (hsb[0] <= 300) {
                b = 0;
                r = 1;
                g = 2;
            } else if (hsb[0] <= 360) {
                r = 0;
                b = 1;
                g = 2;
            }
            rgb[1] = Math.abs((hsb[0] + 60) % 120 - 60) * 255 / 60;
            rgb.forEach(
                function (val, idx, arr) {
                    arr[idx] = val + (255 - val) * (1 - hsb[1]);
                    arr[idx] *= hsb[2];
                }
            );
            return [rgb[r], rgb[g], rgb[b]];
        }
    }
});
css代码:

*{
    margin:0;
    padding: 0;
}
div{
    position: relative;
    width: 100%;
    height: 642px;
}
canvas{
    position: absolute;
    width: 1920px;
    height: 642px;
    top: 0;
    left: 50%;
    z-index: 50;
    margin-left: -969px;
}
img{
    width: 100%;
}
注意:需要引入jquery

效果截图:


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值