日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

JavaScript實現煙花綻放動畫效果

瀏覽:235日期:2023-10-18 18:52:41

先編寫一個煙花綻放的動畫效果。

放煙花時,一個煙花可分為兩個階段:(1)煙花上升到空中;(2)煙花炸開成碎片,炸開的碎片慢慢消散。

為此抽象出兩個對象類:Firework和Particle。其中,Firework用于表示一個煙花對象,Particle用于表示一個煙花炸開后的各碎片。

Firework對象類定義6個屬性:表示煙花上升軌跡中各點的坐標(x,y)、煙花弧狀軌跡的偏轉角度angle、上升階段水平和垂直方向的位移改變量xSpeed和ySpeed、煙花的色彩色相hue。

坐標屬性值y的初始值取畫布的高度,表示煙花從地面上升到空中,其余各屬性的初始值采用隨機數確定。具體定義如下:

function Firework() { this.x = canvas.width/4*(1+3*Math.random()); this.y = canvas.height - 15; this.angle = Math.random() * Math.PI / 4 - Math.PI / 6; this.xSpeed = Math.sin(this.angle) *(6+Math.random()*7); this.ySpeed = -Math.cos(this.angle) *(6+Math.random()*7); this.hue = Math.floor(Math.random() * 360); }

Firework對象類定義3個方法:繪制煙花上升軌跡的方法draw()、煙花上升時坐標改變方法update()和煙花炸開方法explode()。繪制煙花軌跡時,在各點(x,y)處繪制一個寬度為5、高度為15的填充小矩形表示一個軌跡點。煙花上升時,垂直方向速度ySpeed初始值為負的,每次上升時,ySpeed加上一個正值,表示上升在減速,當ySpeed的值大于0時,煙花上升到頂了(不能再上升),就炸開為70個碎片。具體方法的實現見后面的HTML文件內容。

Particle對象類定義8個屬性:表示碎片散開軌跡中各點的坐標(x,y)、碎片弧狀軌跡的偏轉角度angle、散開時水平和垂直方向的位移改變量xSpeed和ySpeed、碎片的色彩色相hue、表示碎片小圓的半徑size、碎片的亮度lightness。

function Particle(x,y,hue) { this.x = x; this.y = y; this.hue = hue; this.lightness = 50; this.size = 15 + Math.random() * 10; this.angle = Math.random() * 2 * Math.PI; this.xSpeed = Math.cos(this.angle) *(1+Math.random() * 6); this.ySpeed = Math.sin(this.angle) *(1+Math.random() * 6); }

Particle對象類定義2個方法:繪制碎片散開軌跡的方法draw()、碎片散開時坐標改變方法update()。碎片散開時逐漸變?。▽傩詓ize值減量),當size值小于1時,從碎片數組中刪除該碎片,表示碎片已消亡。

定義兩個數組var fireworks=[];和var particles=[];分別存儲煙花對象和炸開的碎片對象。

模擬動畫的函數loop中,每隔一段時間(用count計數來實現)向fireworks數組中添加一個煙花對象,煙花對象上升到頂炸開后,從fireworks數組中刪除該對象元素,然后向particles數組中添加70個碎片對象。

遍歷兩個數組的各對象,分別調用它們的draw()和update()方法。

編寫的完整HTML文件內容如下。

<html> <head> <title>煙花綻放</title> </head><body><canvas style='border:3px double #996633;background:black;'></canvas><script type='text/javascript'> var canvas=document.getElementById(’myCanvas’); ctx= canvas.getContext(’2d’); var fireworks=[]; var particles=[]; var counter = 0; function Firework() { this.x = canvas.width/4*(1+3*Math.random()); this.y = canvas.height - 15; this.angle = Math.random() * Math.PI / 4 - Math.PI / 6; this.xSpeed = Math.sin(this.angle) *(6+Math.random()*7); this.ySpeed = -Math.cos(this.angle) *(6+Math.random()*7); this.hue = Math.floor(Math.random() * 360); } Firework.prototype.draw= function() { ctx.save(); ctx.translate(this.x, this.y); ctx.rotate(Math.atan2(this.ySpeed, this.xSpeed) + Math.PI / 2); ctx.fillStyle =`hsl(${this.hue}, 100%, 50%)`; ctx.fillRect(0, 0, 5, 15); ctx.restore(); } Firework.prototype.update= function() { this.x = this.x + this.xSpeed; this.y = this.y + this.ySpeed; this.ySpeed += 0.1; } Firework.prototype.explode= function() { for (var i = 0; i < 70; i++) { particles.push(new Particle(this.x, this.y, this.hue)); } } function Particle(x,y,hue) { this.x = x; this.y = y; this.hue = hue; this.lightness = 50; this.size = 15 + Math.random() * 10; this.angle = Math.random() * 2 * Math.PI; this.xSpeed = Math.cos(this.angle) *(1+Math.random() * 6); this.ySpeed = Math.sin(this.angle) *(1+Math.random() * 6); } Particle.prototype.draw= function() { ctx.fillStyle = `hsl(${this.hue}, 100%, ${this.lightness}%)`; ctx.beginPath(); ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI); ctx.closePath(); ctx.fill(); } Particle.prototype.update= function(index) { this.ySpeed += 0.05; this.size = this.size*0.95; this.x = this.x + this.xSpeed; this.y = this.y + this.ySpeed; if (this.size<1) { particles.splice(index,1); } } function loop() { ctx.fillStyle = 'rgba(0, 0, 0, 0.1)'; ctx.fillRect(0,0,canvas.width,canvas.height); counter++; if (counter==15) { fireworks.push(new Firework()); counter=0; } var i=fireworks.length; while (i--) { fireworks[i].draw(); fireworks[i].update(); if (fireworks[i].ySpeed > 0) { fireworks[i].explode(); fireworks.splice(i, 1); } } var i=particles.length; while (i--) {particles[i].draw(); particles[i].update(i); } requestAnimationFrame(loop); } loop();</script></body> </html>

在瀏覽器中打開包含這段HTML代碼的html文件,可以看到在瀏覽器窗口中呈現出如圖所示的煙花綻放動畫效果。

JavaScript實現煙花綻放動畫效果

實現了煙花綻放的效果,我們還可以繼續讓一定區域內的綻放的煙花碎片拼成“Happy New Year”粒子文本。

編寫如下的HTML代碼。

<html> <head> <title>迎新年煙花綻放</title> <style> body { margin: 0; background: black; } canvas { position: absolute; }</style></head><body><canvas id='myCanvas1'></canvas><canvas id='myCanvas2'></canvas><canvas id='myCanvas3'></canvas><script type='text/javascript'> function Particle(x, y, hue) { this.x = x; this.y = y; this.hue = hue; this.lightness = 50; this.size = 15 + Math.random() * 10; this.angle = Math.random() * 2 * Math.PI; this.xSpeed = Math.cos(this.angle) * (1 + Math.random() * 6); this.ySpeed = Math.sin(this.angle) * (1 + Math.random() * 6); this.target = getTarget(); this.timer = 0; } Particle.prototype.draw= function() { ctx2.fillStyle =`hsl(${this.hue}, 100%, ${this.lightness}%)`; ctx2.beginPath(); ctx2.arc(this.x, this.y, this.size, 0, 2 * Math.PI); ctx2.closePath(); ctx2.fill(); } Particle.prototype.update= function(idx) { if (this.target) { var dx = this.target.x - this.x; var dy = this.target.y - this.y; var dist = Math.sqrt(dx * dx + dy * dy); var a = Math.atan2(dy, dx); var tx = Math.cos(a) * 5; var ty = Math.sin(a) * 5; this.size = lerp(this.size, 1.5, 0.05); if (dist < 5) { this.lightness = lerp(this.lightness, 100, 0.01); this.xSpeed = this.ySpeed = 0; this.x = lerp(this.x, this.target.x + fidelity / 2, 0.05); this.y = lerp(this.y, this.target.y + fidelity / 2, 0.05); this.timer += 1; } else if (dist < 10) { this.lightness = lerp(this.lightness, 100, 0.01); this.xSpeed = lerp(this.xSpeed, tx, 0.1); this.ySpeed = lerp(this.ySpeed, ty, 0.1); this.timer += 1; } else { this.xSpeed = lerp(this.xSpeed, tx, 0.02); this.ySpeed = lerp(this.ySpeed, ty, 0.02); } } else { this.ySpeed += 0.05; this.size = this.size*0.95; if (this.size<1) { particles.splice(idx,1); } } this.x = this.x + this.xSpeed; this.y = this.y + this.ySpeed; } function Firework() { this.x = canvas2.width*(1+ 3*Math.random())/4; this.y = canvas2.height - 15; this.angle = Math.random() * Math.PI / 4 - Math.PI / 6; this.xSpeed = Math.sin(this.angle) * (6 + Math.random() * 7); this.ySpeed = -Math.cos(this.angle) * (6 + Math.random() * 7); this.hue = Math.floor(Math.random() * 360); } Firework.prototype.draw= function() { ctx2.save(); ctx2.translate(this.x, this.y); ctx2.rotate(Math.atan2(this.ySpeed, this.xSpeed) + Math.PI / 2); ctx2.fillStyle = `hsl(${this.hue}, 100%, 50%)`; ctx2.fillRect(0, 0, 5, 15); ctx2.restore(); } Firework.prototype.update= function() { this.x = this.x + this.xSpeed; this.y = this.y + this.ySpeed; this.ySpeed += 0.1; } Firework.prototype.explode= function() { for (var i = 0; i < 70; i++) { particles.push(new Particle(this.x, this.y, this.hue)); } } function lerp(a, b, t) { return Math.abs(b - a)> 0.1 ? a + t * (b - a) : b; } function getTarget() { if (targets.length > 0) { var idx = Math.floor(Math.random() * targets.length); var { x, y } = targets[idx]; targets.splice(idx, 1); x += canvas2.width / 2 - textWidth / 2; y += canvas2.height / 2 - fontSize / 2; return { x, y }; } } var canvas1=document.getElementById(’myCanvas1’); ctx1= canvas1.getContext(’2d’); var canvas2=document.getElementById(’myCanvas2’); ctx2= canvas2.getContext(’2d’); var canvas3=document.getElementById(’myCanvas3’); ctx3= canvas3.getContext(’2d’); var fontSize = 200; var fireworks = []; var particles = []; var targets = []; var fidelity = 3; var counter = 0; canvas2.width = canvas3.width = window.innerWidth; canvas2.height = canvas3.height = window.innerHeight; ctx1.fillStyle = ’#000’; var text = ’Happy New Year’; var textWidth = 999999; while (textWidth > window.innerWidth) { ctx1.font = `900 ${fontSize--}px Arial`; textWidth = ctx1.measureText(text).width; } canvas1.width = textWidth; canvas1.height = fontSize * 1.5; ctx1.font = `900 ${fontSize}px Arial`; ctx1.fillText(text, 0, fontSize); var imgData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height); for (var i = 0, max = imgData.data.length; i < max; i += 4) { var alpha = imgData.data[i + 3]; var x = Math.floor(i / 4) % imgData.width; var y = Math.floor(i / 4 / imgData.width); if (alpha && x % fidelity === 0 && y % fidelity === 0) { targets.push({ x, y }); } } ctx3.fillStyle = ’#FFF’; ctx3.shadowColor = ’#FFF’; ctx3.shadowBlur = 25; function loop() { ctx2.fillStyle = 'rgba(0, 0, 0, .1)'; ctx2.fillRect(0, 0, canvas2.width, canvas2.height); counter += 1; if (counter==15) { fireworks.push(new Firework()); counter=0; } var i=fireworks.length; while (i--) { fireworks[i].draw(); fireworks[i].update(); if (fireworks[i].ySpeed > 0) { fireworks[i].explode(); fireworks.splice(i, 1); } } var i=particles.length; while (i--) {particles[i].draw(); particles[i].update(i); if (particles[i].timer >= 100 || particles[i].lightness >= 99) { ctx3.fillRect(particles[i].target.x, particles[i].target.y, fidelity + 1, fidelity + 1); particles.splice(i, 1); } } requestAnimationFrame(loop); } loop();</script></body> </html>

在瀏覽器中打開包含這段HTML代碼的html文件,可以看到在瀏覽器窗口中呈現出如圖所示的煙花綻放迎新年動畫效果。圖2中為了控制圖片的大小,刪除了大量的中間幀,因此和實際運行的效果有所不同。

JavaScript實現煙花綻放動畫效果

以上就是JavaScript實現煙花綻放動畫效果的詳細內容,更多關于JavaScript動畫效果的資料請關注好吧啦網其它相關文章!

標簽: JavaScript
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
欧美日韩免费观看一区=区三区| 欧美羞羞视频| 激情久久久久久| 欧美日韩国产探花| 日韩在线电影| 天海翼精品一区二区三区| 美女久久久久久| 欧美午夜精彩| 久久亚洲欧美| 999久久久91| 日本亚洲最大的色成网站www | 久久精品高清| 三级欧美韩日大片在线看| 一本综合精品| 91精品国产调教在线观看| 欧美天堂一区| 国产一区日韩一区| 日韩精彩视频在线观看| av中文字幕在线观看第一页 | 综合日韩av| 欧美激情久久久久久久久久久| 国产精品日本| 欧美日韩尤物久久| 美女精品一区二区| 综合激情婷婷| 国产在线日韩| 久久aⅴ国产紧身牛仔裤| 久久中文字幕一区二区三区| 视频一区视频二区中文| 神马午夜在线视频| 麻豆91精品91久久久的内涵| 只有精品亚洲| 99热精品在线| 99国产精品免费视频观看| 91偷拍一区二区三区精品| 在线精品小视频| 97成人超碰| 蜜臀va亚洲va欧美va天堂| 欧美不卡视频| 韩国精品主播一区二区在线观看| 国产精品mv在线观看| 日韩有码av| 中文一区一区三区免费在线观 | 91精品国产自产观看在线| 欧美另类专区| 久久九九99| 亚洲免费成人av在线| 免费成人在线观看| 黄色日韩精品| 欧美专区在线| 久久亚洲图片| 在线视频亚洲| 日韩av免费| 日韩高清中文字幕一区| 亚洲深夜福利| 国产精品中文字幕制服诱惑| 日韩电影二区| 国产传媒在线| 日韩不卡一区二区| 久久亚洲成人| 最新日韩av| 一区三区视频| 久久伊人久久| 日韩免费高清| 亚洲欧美高清| 国内在线观看一区二区三区| 麻豆91小视频| 国产一区二区三区不卡视频网站 | 亚洲18在线| 日本中文字幕视频一区| 欧美精品资源| 欧美日韩国产一区二区三区不卡 | 欧美1区2区3| 欧美激情综合| 伊伊综合在线| 国产一区二区亚洲| www.com.cn成人| 亚洲免费黄色| 久久av导航| 蜜臀国产一区| 午夜电影亚洲| 国产精品jk白丝蜜臀av小说| 日韩av专区| 97精品视频在线看| 国产欧美88| 国产在线一区不卡| 精品一区二区三区的国产在线观看 | 精品一区不卡| 麻豆91小视频| 亚洲毛片在线免费| 国产一卡不卡| 国产一区二区亚洲| 国产精品久久久久久久久久10秀 | 蜜桃伊人久久| 亚洲国产成人精品女人| 国产精品一区二区精品| 蜜桃91丨九色丨蝌蚪91桃色| 99视频+国产日韩欧美| 亚洲精品日韩久久| 国产精品地址| 成人黄色av| 日韩在线二区| 亚洲国产欧美日本视频| 精品一区二区三区中文字幕| 免费高潮视频95在线观看网站| 精品一区三区| 在线精品亚洲| 日韩精品视频在线看| 国产精选在线| 九九久久国产| 欧美专区在线| 精品伊人久久| 六月婷婷综合| 色综合视频一区二区三区日韩 | 国产精品极品国产中出| 国产精品久久免费视频| 国产欧美日韩影院| 久久精品播放| 日本欧美韩国一区三区| 蜜桃91丨九色丨蝌蚪91桃色| 成人免费一区| 亚洲欧美日韩精品一区二区| 久久久噜噜噜| 色婷婷狠狠五月综合天色拍| 日韩精品久久理论片| 成人av三级| 亚洲www啪成人一区二区| 久久国产尿小便嘘嘘| 久久久久99| 国产免费av国片精品草莓男男| 国产亚洲精品自拍| 久久在线91| 在线精品视频一区| 99视频精品全国免费| 日本少妇一区二区| 在线综合亚洲| 亚洲视频二区| 欧美精品中文字幕亚洲专区| 美女视频网站久久| 国产精品入口久久| 悠悠资源网久久精品| 亚洲精品高潮| 国产亚洲高清一区| 久久精品国产大片免费观看| 天堂资源在线亚洲| 先锋亚洲精品| 国精品产品一区| 日韩黄色av| 正在播放日韩精品| 麻豆久久久久久久| 亚洲免费成人av在线| 国产高清日韩| 黄色欧美日韩| 一二三区精品| 国产欧美大片| 婷婷综合国产| 男女性色大片免费观看一区二区| 日韩av中文字幕一区| 激情综合网站| 欧美在线综合| 伊人久久亚洲热| 国产精品自在| 亚洲我射av| 欧美专区一区二区三区| 日韩精品永久网址| 国产不卡人人| 亚洲精品人人| 久久精品影视| 91综合久久爱com| 成人美女视频| 国产suv精品一区| 国产精品白丝久久av网站| 亚洲精品一二| 日本精品在线播放| 激情欧美丁香| 日韩伦理在线一区| 国产精成人品2018| 久久久久久久欧美精品| 亚洲v天堂v手机在线| 一本色道久久精品| 丝袜国产日韩另类美女| 久久大逼视频| 伊伊综合在线| 成人羞羞视频播放网站| 久久在线电影| 精品成av人一区二区三区| 久久久久伊人| 国产精品一区二区三区美女 | 欧美激情日韩| 久久免费国产| 欧美国产日本| 国产美女视频一区二区| 久久午夜精品一区二区| 亚洲制服欧美另类| 激情欧美一区| 蜜桃视频在线观看一区| 日韩午夜黄色| 91精品国产成人观看| 在线国产一区二区| 福利欧美精品在线|