JavaScript實現(xiàn)帶粒子效果的進度條
更新時間:2022年06月19日 15:49:00 作者:福州-司馬懿
這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)帶粒子效果的進度條,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了JavaScript實現(xiàn)帶粒子效果進度條的具體代碼,供大家參考,具體內(nèi)容如下
<html> ? ? <head> ? ? ? ? <meta charset="utf8"/> ? ? ? ? <!-- ? ? ? ? <meta name="viewport" content="width=device-width,user-scalable=no, initial-scale=1, maximum-scale=1" /> ? ? ? ? --> ? ? ? ? <title>粒子效果實戰(zhàn)</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會自動使用最優(yōu)的幀率進行渲染 ? ? ? ? ? ? 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]中隨機取一個數(shù) ? ? ? ? ? ? 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); ? ? ? ? ? ? } ? ? ? ? ? ? //判斷點是否在指定區(qū)域內(nèi) ? ? ? ? ? ? function isInRect(x, y, rx, ry, rw, rh) { ? ? ? ? ? ? ? ? return !(x < rx || x > rx + rw || y < ry || y > ry + rh); ? ? ? ? ? ? } ? ? ? ? ? ? //將數(shù)限制在某個范圍之內(nèi) ? ? ? ? ? ? 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坐標(biāo) ? ? ? ? ? ? ? ? ? ? this.x = (canvas.width - this.width) / 2; ? ? ? ? ? ? ? ? ? ? //進度條Y坐標(biāo) ? ? ? ? ? ? ? ? ? ? this.y = (canvas.height - this.height) / 2; ? ? ? ? ? ? ? ? ? ? //進度條當(dāng)前值 ? ? ? ? ? ? ? ? ? ? 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; ? ? ? ? ? ? ? ? ? ? //獲取當(dāng)前值對應(yīng)的X坐標(biāo) ? ? ? ? ? ? ? ? ? ? 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坐標(biāo) ? ? ? ? ? ? ? ? ? ? this.x = x; ? ? ? ? ? ? ? ? ? ? //粒子的Y坐標(biāo) ? ? ? ? ? ? ? ? ? ? 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() { ? ? ? ? ? ? ? ? ? ? //默認(rèn)值,表示圖形將繪制在現(xiàn)有畫布之上 ? ? ? ? ? ? ? ? ? ? ctx.globalCompositeOperation = "source-over"; ? ? ? ? ? ? ? ? ? ? ctx.clearRect(0, 0, canvas.width, canvas.height); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? //初始化函數(shù) ? ? ? ? ? ? ? ? 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>
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
學(xué)習(xí)JavaScript圖片預(yù)加載模塊
這篇文章主要介紹了js實現(xiàn)圖片預(yù)加載的方法,內(nèi)容很詳細,帶領(lǐng)大家全面認(rèn)識js圖片預(yù)加載模塊,感興趣的小伙伴們可以參考一下2016-11-11如何讓div span等元素能響應(yīng)鍵盤事件操作指南
在我這幾天的工作中遇到了一個問題,我有一個可編輯的div,并且在DIV里面還有一個可編輯的span,我想要讓span能響應(yīng)鍵盤事,想實現(xiàn)這種效果,應(yīng)該如何實踐呢2012-11-11JavaScript內(nèi)置對象math,global功能與用法實例分析
這篇文章主要介紹了JavaScript內(nèi)置對象math,global功能與用法,結(jié)合實例形式分析了javascript中內(nèi)置對象math與global的基本概念、功能及使用方法,需要的朋友可以參考下2019-06-06跟我學(xué)Node.js(四)---Node.js的模塊載入方式與機制
Node.js中模塊可以通過文件路徑或名字獲取模塊的引用。模塊的引用會映射到一個js文件路徑,除非它是一個Node內(nèi)置模塊。Node的內(nèi)置模塊公開了一些常用的API給開發(fā)者,并且它們在Node進程開始的時候就預(yù)加載了。2014-06-06