JavaScript实现带粒子效果的进度条

本文实例为大家分享了JavaScript实现带粒子效果进度条的具体代码,供大家参考,具体内容如下

<html>
    <head>
        <meta charset="utf8"/>
        <!--
        <meta name="viewport" content="width=device-width,user-scalable=no, initial-scale=1, maximum-scale=1" />
        -->
        <title>粒子效果实战</title>
        <style type="text/css">
            body {
                background:#111;
            }
            #canvas {
                background:transparent;
                border:1px dashed #171717;
                margin:-151px 0 0 -401px;
                position:absolute;
                left:50%;
                top:50%;
            }
        </style>
    </head>
    <body onload="init()">
        <canvas id="canvas" width="800px" height="300px">浏览器不支持canvas</canvas>
        <script type="text/javascript">

            //判断是否支持canvaas
            function isSupportCanvas(canvas) {
                return !!(canvas.getContext && canvas.getContext("2d"));
            }

            //requestAnimationFrame会自动使用最优的帧率进行渲染
            function setupRAF() {
                window.lastTime = 0;

                //兼容各个浏览器,Internet Explorer11、Google Chrome(Microsoft Edge)、Mozilla Firefox、Opera
                var vendors = ["ms", "moz", "webkit", "o"];
                for(var i=0; i<vendors.length; i++) {
                    window.requestAnimationFrame = window[vendors[i] + "RequestAnimationFrame"];
                    window.cancelAnimationFrame = window[vendors[i] + "CancelAnimationFrame"] || window[vendors[i] + "CancelRequestAnimationFrame"];

                    //测试浏览器支持哪一张
                    if(window.requestAnimationFrame) {
                        console.log(vendors[i] + "requestAnimationFrame");
                    }
                    if(window[vendors[i] + "CancelAnimationFrame"]) {
                        console.log(vendors[i] + "CancelAnimationFrame");
                    }
                    if(window[vendors[i] + "CancelRequestAnimationFrame"]) {
                        console.log(vendors[i] + "CancelRequestAnimationFrame");
                    }
                }

                //回退机制
                if(!window.requestAnimationFrame) {
                    window.requestAnimationFrame = function(callback, element) {
                        var currentTime = new Date().getTime();
                        var timeToCall = Math.max(0, 16-(currentTime-window.lastTime));
                        var callTime = currentTime + timeToCall;
                        var id = window.setTimeout(function() {
                            callback(callTime);
                        }, timeToCall);
                        window.lastTime = callTime;
                        return id;
                    };
                }

                //回退机制
                if(!window.cancelAnimationFrame) {
                    window.cancelAnimationFrame = function(id) {
                        clearTimeout(id);
                    }
                }
            }

            //在[min, max]中随机取一个数
            function rand(min, max) {
                return Math.random() * (max - min + 1) + min;
            }

            //判断两碰撞盒是否相交
            function isHit(x1, y1, w1, h1, x2, y2, w2, h2) {
                return !( x1 + w1 < x2 || x2 + w2 < x1 || y1 + h1 < h2 || y2 + h2 < h1);
            }

            //判断点是否在指定区域内
            function isInRect(x, y, rx, ry, rw, rh) {
                return !(x < rx || x > rx + rw || y < ry || y > ry + rh);
            }

            //将数限制在某个范围之内
            function limit(value, min, max) {
                if(value < min) {
                    return min;
                } else if(value > max) {
                    return max;
                }
                return value;
            }

            var CanvasController = function(canvas) {
                var ctx = canvas.getContext("2d");

                //进度条对象
                var Loader = function() {
                    //进度条宽度
                    this.width = canvas.width - 80;
                    //进度条高度
                    this.height = 20;
                    //进度条X坐标
                    this.x = (canvas.width - this.width) / 2;
                    //进度条Y坐标
                    this.y = (canvas.height - this.height) / 2;
                    //进度条当前值
                    this.value = 0;
                    //进度条最大值
                    this.maxValue = 100;
                    //进度条更新速度
                    this.speed = .5;
                    //加深的颜色
                    this.lighterColor = "#222";

                    //HSL(Hue:色相,Saturation:饱和度,Lightness:饱和度)
                    this.hue = 0;
                    this.hueStart = 0;
                    this.hueEnd = 360;

                    //获取当前值对应的X坐标
                    this.currentPosX = function() {
                        return this.x + this.width * this.value / 100; 
                    }

                    //更新进度条
                    this.update = function() {
                        this.value += this.speed;
                        if(this.value > this.maxValue) {
                            this.value = 0;
                        }
                    }

                    //渲染进度条
                    this.render = function() {
                        ctx.globalCompositeOperation = "source-over";
                        var currentWidth = this.width * this.value / 100;
                        this.hue = this.hueStart + (this.hueEnd - this.hueStart) * this.value / 100;
                        //ctx.fillStyle = "hsl(" + this.hue + ", 100%, 40%)";
                        var linearGradient = ctx.createLinearGradient(this.x, this.y, this.x + currentWidth, this.y);
                        linearGradient.addColorStop(0, "hsl(" + this.hueStart + ", 100%, 40%)");
                        linearGradient.addColorStop(1, "hsl(" + this.hue + ", 100%, 40%)");
                        ctx.fillStyle = linearGradient;
                        ctx.fillRect(this.x, this.y, currentWidth, this.height);
                        ctx.fillStyle = this.lighterColor;
                        ctx.globalCompositeOperation = "lighter";                   
                        ctx.fillRect(this.x, this.y, currentWidth, this.height/2);
                    }
                }

                //单个粒子对象
                var Particle = function(x, y, hue, minX, maxX) {
                    //粒子的X坐标
                    this.x = x;
                    //粒子的Y坐标
                    this.y = y;
                    //粒子的宽度
                    this.width = rand(1,3);
                    //粒子的高度
                    this.height = rand(1,2);
                    //粒子的HSL颜色的hue分量
                    this.hue = limit(hue + rand(-15,15), 0, 360);
                    //粒子在X方向上的速度
                    this.velocityX = rand(-1,1);
                    //粒子在Y方向上的速度
                    this.velocityY = rand(-30,-20);
                    //粒子在X方向上的加速度
                    this.accelerationX = -.5;
                    //粒子在Y方向上的加速度
                    this.accelerationY = 4;
                    //单位时间
                    this.unitTime = .2;

                    //更新粒子位置
                    this.update = function() {
                        this.x += (this.velocityX * this.unitTime);
                        this.y += (this.velocityY * this.unitTime);
                        this.velocityX += (this.accelerationX * this.unitTime * rand(-1,1));
                        this.velocityY += (this.accelerationY * this.unitTime);
                    }

                    //渲染粒子
                    this.render = function() {
                        ctx.fillStyle = "hsl(" + this.hue + ", 100%, 40%)"
                        ctx.globalCompositeOperation = "source-over";
                        ctx.fillRect(this.x, this.y, this.width, this.height);
                    }
                }

                //所有粒子效果的对象
                var Particles = function(minX, maxX) {
                    //存放生成的所有粒子对象
                    this.values = [];
                    //粒子生成速率
                    this.rate = 3;

                    //生成粒子
                    this.generate = function(x, y, hue) {
                        for(var i=0; i<this.rate; i++) {
                            this.values.push(new Particle(x, y, hue, minX, maxX));
                        }
                    }

                    //更新进度值
                    this.update = function() {
                        for(var i = this.values.length-1; i >= 0; i--) {
                            this.values[i].update();
                            if(!isInRect(this.values[i].x, this.values[i].y, 0, 0, canvas.width, canvas.height)) {
                                this.values.splice(i, 1);
                            }
                        }
                    }

                    //渲染进度条
                    this.render = function() {
                        for(var i =0; i<this.values.length; i++) {
                            this.values[i].render();
                        }
                    }
                }

                //清空画布
                function clearCanvas() {
                    //默认值,表示图形将绘制在现有画布之上
                    ctx.globalCompositeOperation = "source-over";
                    ctx.clearRect(0, 0, canvas.width, canvas.height);
                }

                //初始化函数
                this.init = function() {
                    var loader = new Loader();
                    var particles = new Particles(loader.x, loader.x + loader.width);
                    var loop = function() {
                        requestAnimationFrame(loop, canvas);

                        clearCanvas();

                        loader.update();
                        loader.render();

                        particles.generate(loader.currentPosX()-3, loader.y + loader.height/2, loader.hue);
                        particles.update();
                        particles.render();
                    }
                    loop();
                }
            }

            function init() {
                var canvas = document.getElementById("canvas");
                if(!isSupportCanvas(canvas)) {
                    return;
                }
                setupRAF();
                var canvasController = new CanvasController(canvas);
                canvasController.init();
            }
        </script>
    </body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • js实现进度条的方法

    本文实例讲述了js实现进度条的方法.分享给大家供大家参考.具体实现方法如下: 1.setTimeout和clearTimeout <html> <head> <title>进度条</title> <style type="text/css"> .container{ width:450px; border:1px solid #6C9C2C; height:25px; } #bar{ background:#95CA0D; f

  • JS实现环形进度条(从0到100%)效果

    最近公司项目中要用到这种类似环形进度条的效果,初始就从0开始动画到100%结束.动画结果始终会停留在100%上,并不会到因为数据的关系停留在一半. 如图 代码如下 demo.html <!doctype html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content=

  • JS 进度条效果实现代码整理

    第一种方法:Loading.js 复制代码 代码如下: //频率 var frequency = 50; //步长 var step = 3; //背景颜色 var loadingBgcolor = "#ffffff"; //宽度 var loadingWidth = 354; /* *参数说明: *content:显示内容,可以为空: *imageURL:将引用JS文件的路径设置即可: *left:进度条显示位置left *top:进度条显示位置top */ function Loa

  • JavaScript实现网页加载进度条代码超简单

    网页进度条能够更好的反应当前网页的加载进度情况,loading进度条可用动画的形式从开始0%到100%完成网页加载这一过程.但是目前的浏览器并没有提供页面加载进度方面的接口,也就是说页面还无法准确返回页面实际加载的进度,本文中我们使用jQuery来实现页面加载进度条效果. HTML 首先我们要知道的是,目前没有任何浏览器可以直接获取正在加载对象的大小.所以我们无法通过数据大小来实现0-100%的加载显示过程. 因此我们需要通过html代码逐行加载的特性,在整页代码的若干个跳跃行数中设置节点,进行

  • js 进度条实现代码

    进度条 body{ text-align:center; } .graph{ width:450px; border:1px solid #F8B3D0; height:25px; } #bar{ display:block; background:#FFE7F4; float:left; height:100%; text-align:center; } #barNum{ position:absolute; } function $(obj){ return document.getElem

  • JavaScript实现水平进度条拖拽效果

    本文实例为大家分享水平进度条拖拽效果的js具体代码,供大家参考,具体内容如下 <html> <head> <meta charset="UTF-8"> <title>Document</title> <style> *{ margin: 0; padding: 0; } .scroll{ margin:100px; width: 500px; height: 5px; background: #ccc; posit

  • Javascript jquery css 写的简单进度条控件

    通过我们伟大的 CSS,可以实现非常漂亮的进度条样式.加上 Javascript 的效果,就可以完全"欺骗"我们的用户,让他们有耐心等待浏览器处理完成.上述的原理已经知道了,那么就可以直接看代码了.本人使用的还是 jQuery 框架,因为这样简短的代码可能会更容易理解. 当然这个控件还有很多需要完成的地方,我仅仅是提供了一种遵循 Web 标准的实现思路.废话不多说. Javascript Progress Bar Demo - jb51.net #progress {backgroun

  • 用CSS+JS实现的进度条效果效果

    进度条,就是在用户进入你的网站的时候,能让用户看到网页下载了多少,这个的作用非常明显---就是让用户的等待时间变长,可以有效的弥补空间慢的缺点(当然,你空间太慢,还是建议你换下空间,呵呵) 好了,现在我先来举两个例子 一个是用FLASH实现的 (这个网上很多网站都是,不说了) 一个是用动态的GIF实现的 (这个你可以看微软官方的下载页面,也不说了) 这里,我们的重点是用 CSS+JS 实现这个效果 好了,废话不多说,我们开始 首先,写一段HTML代码 <div id="loading&qu

  • javascript 进度条的几种方法

    我们先看看最终效果: 第一步,基本 构建基本的代码,看效果演示: 制作进度条的两种方法 *{ margin:0; padding:0; } body{font-size:12px;}h1{font-size:15px;} .wrap{ font-size: 12px; margin:40px auto; width:400px; } /*进度条样式*/ .progressbar_1{ background-color:#eee; height:16px; width:150px; border:

  • js实现音频控制进度条功能

    效果图: 代码如下: <!doctype html> <html> <head> <meta name="author" content="dony"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="pragma" content="no

随机推荐