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>

推荐阅读