JavaScript實現(xiàn)瀑布動畫
更新時間:2022年06月19日 09:59:22 作者:福州-司馬懿
這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)瀑布動畫,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了JavaScript實現(xiàn)瀑布動畫的具體代碼,供大家參考,具體內(nèi)容如下
<!DOCTYPE html> <html> ? ? <head> ? ? ? ? <meta charset="utf8"> ? ? ? ? <meta http-equiv=“X-UA-Compatible” content="IE-edge, chrome=1"> ? ? ? ? <meta name="viewport" content="width=device-width, initial-scale=1.0"> ? ? ? ? <title>瀑布(waterful)</title> ? ? ? ? <style> ? ? ? ? ? ? body { ? ? ? ? ? ? ? ? background: #222; ? ? ? ? ? ? } ? ? ? ? </style> ? ? </head> ? ? <body> ? ? ? ? <script> ? ? ? ? ? ? //判斷瀏覽器是否支持canvas ? ? ? ? ? ? function isSupportCanvas() { ? ? ? ? ? ? ? ? var canvas = document.createElement('canvas'); ? ? ? ? ? ? ? ? return !!(canvas.getContext && canvas.getContext("2d")); ? ? ? ? ? ? } ? ? ? ? ? ? //requestAnimationFrame會自動使用最優(yōu)的幀率進行渲染,在我的瀏覽器上是每秒60幀 ? ? ? ? ? ? function setupRAF() { ? ? ? ? ? ? ? ? var lastTime = 0; ? ? ? ? ? ? ? ? var vendors = ['webkit', 'ms', 'moz', 'o']; ? ? ? ? ? ? ? ? for(var i=0; i<vendors.length && !window.requestAnimationFrame; i++) { ? ? ? ? ? ? ? ? ? ? window.requestAnimationFrame = window[vendors[i] + "RequestAnimationFrame"]; ? ? ? ? ? ? ? ? ? ? window.cancelAnimationFrame = window[vendors[i] + "CancelAnimationFrame"] || window[vendors[i] + "CancelRequestAnimationFrame"] ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? if(!window.requestAnimationFrame) { ? ? ? ? ? ? ? ? ? ? window.requestAnimationFrame = function(callback, element) { ? ? ? ? ? ? ? ? ? ? ? ? var currentTime = new Date().getTime(); ? ? ? ? ? ? ? ? ? ? ? ? var timeToCall = Math.max(0, 16 - (currentTime - lastTime)); ? ? ? ? ? ? ? ? ? ? ? ? var futureTime = currentTime + timeToCall; ? ? ? ? ? ? ? ? ? ? ? ? var id = window.setTimeout(function() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? callback(futureTime); ? ? ? ? ? ? ? ? ? ? ? ? }, timeToCall); ? ? ? ? ? ? ? ? ? ? ? ? lastTime = futureTime; ? ? ? ? ? ? ? ? ? ? ? ? return id; ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? if(!window.cancelAnimationFrame) { ? ? ? ? ? ? ? ? ? ? window.cancelAnimationFrame = function(id) { ? ? ? ? ? ? ? ? ? ? ? ? clearTimeout(id); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? //在給定的范圍內(nèi)隨機選取一個整數(shù) ? ? ? ? ? ? function randomInt(min, max) { ? ? ? ? ? ? ? ? /* ? ? ? ? ? ? ? ? 由于位運算的操作數(shù)要求是整數(shù),其結(jié)果也是整數(shù),所以經(jīng)過位運算的都會自動變成整數(shù) ? ? ? ? ? ? ? ? 可用的取整方法: ? ? ? ? ? ? ? ? (1)~~n ? ? ? ? ? ? ? ? (2)n<<0 ? ? ? ? ? ? ? ? (3)n>>0 ? ? ? ? ? ? ? ? (4)n|0 ? ? ? ? ? ? ? ? (5)Math.floor() ? ? ? ? ? ? ? ? (6)Math.ceil() ? ? ? ? ? ? ? ? (7)Math.round() ? ? ? ? ? ? ? ? 值得注意的是,位運算只是去掉小數(shù)部分,并不會改變整數(shù)部分 ? ? ? ? ? ? ? ? */ ? ? ? ? ? ? ? ? return ~~(Math.random() * (max - min) + min); ? ? ? ? ? ? } ? ? ? ? ? ? //在對象所表示的范圍中隨機選取一個數(shù) ? ? ? ? ? ? function randomAtRange(obj) { ? ? ? ? ? ? ? ? return Math.random() * (obj.max - obj.min) + obj.min; ? ? ? ? ? ? } ? ? ? ? ? ? //在對象所表示的范圍中隨機選取一個整數(shù) ? ? ? ? ? ? function randomIntAtRange(obj) { ? ? ? ? ? ? ? ? return randomInt(obj.min, obj.max); ? ? ? ? ? ? } ? ? ? ? ? ? //瀑布 ? ? ? ? ? ? var Waterful = function(width, height) { ? ? ? ? ? ? ? ? var doublePI = Math.PI * 2; ? ? ? ? ? ? ? ? var canvas; ? ? ? ? ? ? ? ? var ctx; ? ? ? ? ? ? ? ? //存放水粒子的數(shù)組 ? ? ? ? ? ? ? ? var particles = []; ? ? ? ? ? ? ? ? //每幀生成或銷毀粒子的數(shù)量 ? ? ? ? ? ? ? ? var particleChangeRate = width / 25; ? ? ? ? ? ? ? ? //垂直方向上的加速度(即重力), 小數(shù)點前的0可以省略 ? ? ? ? ? ? ? ? var gravity = .15; ? ? ? ? ? ? ? ? //水流粒子 ? ? ? ? ? ? ? ? var WaterParticle = function() { ? ? ? ? ? ? ? ? ? ? //水流粒子寬度范圍 ? ? ? ? ? ? ? ? ? ? var waterWidthRange = {min: 1, max: 20}; ? ? ? ? ? ? ? ? ? ? //水流粒子高度范圍 ? ? ? ? ? ? ? ? ? ? var waterHeightRange = {min: 1, max: 45}; ? ? ? ? ? ? ? ? ? ? //水流粒子落到地上濺起的水花半徑范圍 ? ? ? ? ? ? ? ? ? ? var waterBubbleRadiusRange = {min: 1, max: 8}; ? ? ? ? ? ? ? ? ? ? //水花濺起的高度范圍 ? ? ? ? ? ? ? ? ? ? var waterBubbleSpringRange = {min: 20, max: 30}; ? ? ? ? ? ? ? ? ? ? //色相范圍 ? ? ? ? ? ? ? ? ? ? var hueRange = {min: 200, max: 220}; ? ? ? ? ? ? ? ? ? ? //飽和度范圍 ? ? ? ? ? ? ? ? ? ? var saturationRange = {min: 30, max: 60}; ? ? ? ? ? ? ? ? ? ? //亮度 ? ? ? ? ? ? ? ? ? ? var lightnessRange = {min: 30, max: 60}; ? ? ? ? ? ? ? ? ? ? //拼接成一個HSLA顏色值(注意:普通函數(shù)的this指代它自己) ? ? ? ? ? ? ? ? ? ? this.joinHSLA = function(alpha) { ? ? ? ? ? ? ? ? ? ? ? ? return "hsla(" + [this.hue, this.saturation + "%", this.lightness + "%", alpha].join(",") + ")"; ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? this.init = function() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //水流粒子的最大半徑 ? ? ? ? ? ? ? ? ? ? ? ? var waterMaxRadius = waterWidthRange.max / 2; ? ? ? ? ? ? ? ? ? ? ? ? //水流粒子初始X坐標的范圍 ? ? ? ? ? ? ? ? ? ? ? ? var xRange = {min: waterMaxRadius, max: canvas.width - waterMaxRadius}; ? ? ? ? ? ? ? ? ? ? ? ? //水流粒子寬度 ? ? ? ? ? ? ? ? ? ? ? ? this.width = randomAtRange(waterWidthRange); ? ? ? ? ? ? ? ? ? ? ? ? //水流粒子高度 ? ? ? ? ? ? ? ? ? ? ? ? this.height = randomAtRange(waterHeightRange); ? ? ? ? ? ? ? ? ? ? ? ? //水流粒子初始X坐標 ? ? ? ? ? ? ? ? ? ? ? ? this.x = randomAtRange(xRange); ? ? ? ? ? ? ? ? ? ? ? ? //水流粒子初始Y坐標 ? ? ? ? ? ? ? ? ? ? ? ? this.y = -this.height; ? ? ? ? ? ? ? ? ? ? ? ? //水流粒子垂直方向上的初始速度 ? ? ? ? ? ? ? ? ? ? ? ? this.velocity = 0; ? ? ? ? ? ? ? ? ? ? ? ? //水流半徑等于水流粒子寬度的一半 ? ? ? ? ? ? ? ? ? ? ? ? this.waterRadius = this.width / 2; ? ? ? ? ? ? ? ? ? ? ? ? //水花半徑 ? ? ? ? ? ? ? ? ? ? ? ? this.waterBubbleRadius = randomAtRange(waterBubbleRadiusRange); ? ? ? ? ? ? ? ? ? ? ? ? //水花濺起的高度 ? ? ? ? ? ? ? ? ? ? ? ? this.waterBubbleSpring = randomAtRange(waterBubbleSpringRange); ? ? ? ? ? ? ? ? ? ? ? ? //水流顏色 ? ? ? ? ? ? ? ? ? ? ? ? this.hue = randomIntAtRange(hueRange); ? ? ? ? ? ? ? ? ? ? ? ? this.saturation = randomIntAtRange(saturationRange); ? ? ? ? ? ? ? ? ? ? ? ? this.lightness = randomIntAtRange(lightnessRange); ? ? ? ? ? ? ? ? ? ? ? ? //地板高度 ? ? ? ? ? ? ? ? ? ? ? ? this.floorHeight = canvas.height - waterBubbleSpringRange.min - this.height;? ? ? ? ? ? ? ? ? ? ? ? ? //水流粒子是否已經(jīng)落地變成水花 ? ? ? ? ? ? ? ? ? ? ? ? this.isDead = false; ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? this.update = function() { ? ? ? ? ? ? ? ? ? ? ? ? this.velocity += gravity; ? ? ? ? ? ? ? ? ? ? ? ? this.y += this.velocity; ? ? ? ? ? ? ? ? ? ? ? ? if(this.y > this.floorHeight) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? this.isDead = true; ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? this.render = function() { ? ? ? ? ? ? ? ? ? ? ? ? if(this.isDead) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? //繪制水花 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ctx.fillStyle = "hsla(" + this.hue + ", 40%, 40%, 1)"; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ctx.fillStyle = this.joinHSLA(.3); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ctx.beginPath(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ctx.arc(this.x, canvas.height - this.waterBubbleSpring, this.waterBubbleRadius, 0, doublePI); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ctx.fill(); ? ? ? ? ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? ? ? ? ? //繪制水流 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ctx.strokeStyle = this.joinHSLA(.05); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ctx.lineCap = "round"; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ctx.lineWidth = this.waterRadius; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ctx.beginPath(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ctx.moveTo(this.x, this.y); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ctx.lineTo(this.x, this.y + this.height); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ctx.stroke(); ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? this.init(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? this.init = function() { ? ? ? ? ? ? ? ? ? ? canvas = document.createElement("canvas"); ? ? ? ? ? ? ? ? ? ? //如果html不支持canvas的話會顯示該文本,否則不顯示 ? ? ? ? ? ? ? ? ? ? var textNode = document.createTextNode("Your browser can not support canvas"); ? ? ? ? ? ? ? ? ? ? canvas.appendChild(textNode); ? ? ? ? ? ? ? ? ? ? document.body.appendChild(canvas); ? ? ? ? ? ? ? ? ? ? canvas.width = width; ? ? ? ? ? ? ? ? ? ? canvas.height = height; ? ? ? ? ? ? ? ? ? ? //如果不支持canvas就沒必要繼續(xù)下去了 ? ? ? ? ? ? ? ? ? ? if(!isSupportCanvas()) { ? ? ? ? ? ? ? ? ? ? ? ? return; ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ctx = canvas.getContext("2d"); ? ? ? ? ? ? ? ? ? ? setupRAF(); ? ? ? ? ? ? ? ? ? ? loop(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? function loop() { ? ? ? ? ? ? ? ? ? ? /* ? ? ? ? ? ? ? ? ? ? 先繪制一層朦朧的白非常重要,這樣可以省去很多用來填充顏色的粒子 ? ? ? ? ? ? ? ? ? ? 將下面3句換成clearRect就能發(fā)現(xiàn)其實繪制的粒子顏色本身是很淡的,如果直接換成深的顏色就會發(fā)現(xiàn)空隙銜接處很不均勻 ? ? ? ? ? ? ? ? ? ? 增大粒子數(shù)目可以發(fā)現(xiàn)顏色會變深,但是粒子數(shù)越多畫面越卡,所以先繪制上一層白色的蒙版是一種非常取巧的做法 ? ? ? ? ? ? ? ? ? ? */ ? ? ? ? ? ? ? ? ? ? ctx.globalCompositeOperation = 'destination-out'; ? ? ? ? ? ? ? ? ? ? ctx.fillStyle = 'rgba(255,255,255,.06)'; ? ? ? ? ? ? ? ? ? ? ctx.fillRect(0, 0, canvas.width, canvas.height); ? ? ? ? ? ? ? ? ? ? //ctx.clearRect(0, 0, canvas.width, canvas.height); ? ? ? ? ? ? ? ? ? ? ctx.globalCompositeOperation = "lighter"; ? ? ? ? ? ? ? ? ? ? //添加新粒子 ? ? ? ? ? ? ? ? ? ? for(var i=0; i<particleChangeRate; i++) { ? ? ? ? ? ? ? ? ? ? ? ? particles.push(new WaterParticle()); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? //更新渲染粒子 ? ? ? ? ? ? ? ? ? ? for(var i=0; i<particles.length; i++) { ? ? ? ? ? ? ? ? ? ? ? ? particles[i].update(); ? ? ? ? ? ? ? ? ? ? ? ? particles[i].render(); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? //繪制水花,并刪除消亡的粒子 ? ? ? ? ? ? ? ? ? ? for(var i=particles.length-1; i>=0; i--) { ? ? ? ? ? ? ? ? ? ? ? ? if(particles[i].isDead) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? particles.splice(i, 1); ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? requestAnimationFrame(loop); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? ? ? function init() { ? ? ? ? ? ? ? ? var waterful = new Waterful(300, 300); ? ? ? ? ? ? ? ? waterful.init(); ? ? ? ? ? ? } ? ? ? ? ? ? init(); ? ? ? ? </script> ? ? </body> </html>
效果:
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
- 在html文本框中顯示提示效果,以方便用戶的輸入,比如在輸入姓名時,會自動提示 姓名長度最多16個字符,是不是很酷哦??靵砜纯窗?/div> 2014-06-06
《JavaScript DOM 編程藝術(shù)》讀書筆記之JavaScript 語法
這篇文章主要介紹了《JavaScript DOM 編程藝術(shù)》讀書筆記之JavaScript 語法,需要的朋友可以參考下2015-01-01JS數(shù)組降維的實現(xiàn)Array.prototype.concat.apply([], arr)
這篇文章主要介紹了JS數(shù)組降維的實現(xiàn)Array.prototype.concat.apply([], arr),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04JS的鼠標監(jiān)聽mouseup鼠標抬起失效原因及解決
這篇文章主要為大家介紹了JS的鼠標監(jiān)聽mouseup鼠標抬起失效原因及解決示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-05-05最新評論