JavaScript实现带粒子效果的进度条
作者:福州-司马懿
这篇文章主要为大家详细介绍了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>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。