欧美亚洲中文,在线国自产视频,欧洲一区在线观看视频,亚洲综合中文字幕在线观看

      1. <dfn id="rfwes"></dfn>
          <object id="rfwes"></object>
        1. 站長(zhǎng)資訊網(wǎng)
          最全最豐富的資訊網(wǎng)站

          2023過(guò)年,又限制放煙花?程序猿有辦法!

          本篇文章給大家介紹如何用前端代碼實(shí)現(xiàn)一個(gè)煙花綻放的絢爛效果,其實(shí)主要就是用前端三劍客來(lái)實(shí)現(xiàn),也就是HTML+CSS+JS,下面一起來(lái)看一下,作者會(huì)解說(shuō)相應(yīng)的代碼,希望對(duì)需要的朋友有所幫助。(ps:之所以有這篇文章是由于作者所在地區(qū)禁止放煙花…哈哈)2023過(guò)年,又限制放煙花?程序猿有辦法!

          ↑↑↑↑↑↑ 效果圖鎮(zhèn)樓 ↑↑↑↑↑↑

          不知道是在什么時(shí)候,濟(jì)南就開(kāi)始都在傳:“今年不再限制放煙花啦!”。一些集市上也開(kāi)始有了售賣(mài)煙花的攤子

          2023過(guò)年,又限制放煙花?程序猿有辦法!

          大家都很興奮,很多小伙伴開(kāi)始購(gòu)買(mǎi)煙花。特別是今年特別火的 “加特林 ?”

          2023過(guò)年,又限制放煙花?程序猿有辦法!

          但是大家興奮勁還沒(méi)過(guò)呢,隨著官方 一紙禁令,讓咱們知道了:

          2023 過(guò)春年

          煙花依然了無(wú)緣

          2023過(guò)年,又限制放煙花?程序猿有辦法!

          讓我們這些屯了煙花的可咋辦啊 ??????

          2023過(guò)年,又限制放煙花?程序猿有辦法!

          不過(guò)身為程序猿的我們,能就這么認(rèn)栽了?

          我們可是要用代碼改變世界的人啊~~~~

          2023過(guò)年,又限制放煙花?程序猿有辦法!

          所以我辛苦閉關(guān)九九八十一秒(開(kāi)玩笑~我寫(xiě)了好幾天),終于把煙花放到了瀏覽器上,看著效果我是“內(nèi)牛滿(mǎn)面(淚流滿(mǎn)面)”?。?/p>

          2023過(guò)年,又限制放煙花?程序猿有辦法!

          此時(shí),我真想仰天長(zhǎng)嘯,大聲唱道:

          2023 過(guò)春年,

          煙花依然了無(wú)緣;

          這能難倒程序猿?

          一鍵三連過(guò)大年!

          代碼

          下面開(kāi)始上菜(代碼)咯~~~

          咱們整個(gè)的代碼一共分為三個(gè)部分:

          • html:用來(lái)構(gòu)建項(xiàng)目結(jié)構(gòu)

          • css:處理文字樣式

          • js(核心):處理煙花邏輯

          那么下面,咱們就針對(duì)這三個(gè)部分,分別進(jìn)行處理:

          1. html

          整個(gè) html 分為兩部分:

          1. 文字結(jié)構(gòu):用來(lái)處理右下角的文本

          2023過(guò)年,又限制放煙花?程序猿有辦法!2. canvas 畫(huà)板:作為煙花渲染區(qū)

          1. 文字結(jié)構(gòu)

          文字結(jié)構(gòu)整體的內(nèi)容處理會(huì)比較簡(jiǎn)單,通過(guò)div包裹“文本標(biāo)簽”即可:

          <!-- 文字修改區(qū) --> <div class="title">     <h2>LGD_Sunday 祝大家:</h2>     <h1>2023 新年快樂(lè)?</h1> </div>
          登錄后復(fù)制

          2. canvas

          canvas 作為 web 為我們提供的畫(huà)板工具,可以幫助咱們繪制各種各樣的圖形。

          那么對(duì)于咱們本次的煙花繪制而言,同樣需要借助canvas的能力。

          所以在html區(qū)域部分,我們必須提供一個(gè)canvas繪制區(qū):

          <!-- 煙花渲染區(qū) --> <canvas></canvas>
          登錄后復(fù)制

          html 區(qū)域總結(jié)

          當(dāng)咱們完成基本的html繪制之后,運(yùn)行代碼到瀏覽器,效果應(yīng)該是這個(gè)樣子的:

          2023過(guò)年,又限制放煙花?程序猿有辦法!

          啥都沒(méi)有對(duì)吧,別著急,下面咱們?nèi)ヌ幚?code>css部分。

          2. css

          css 處理的核心目的,是為了幫助咱們繪制文字區(qū)域的樣式(沒(méi)錯(cuò),與煙花無(wú)關(guān))。

          所以,整個(gè)css區(qū)域繪制會(huì)比較簡(jiǎn)單

          咱們直接來(lái)看代碼:

          html, body {     padding: 0px;     margin: 0px;     background: #222;     font-family: 'Karla', sans-serif;     color: #fff;     height: 100vh;     overflow: hidden; }  .title {     z-index: 1000;     position: fixed;     bottom: 12px;     right: 12px;     // 此處修改了字體     font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;     border: 2px solid #fff;     padding: 7.5px 15px;     background: rgba(0, 0, 0, 0.5);     border-radius: 3px;     overflow: hidden; }  h1 {     text-align: right;     font-size: 46px; }  h2 {     font-size: 36px; }  canvas {     width: 100%;     height: 100%; }
          登錄后復(fù)制

          繪制了css之后,頁(yè)面效果應(yīng)該是這個(gè)樣子的:

          2023過(guò)年,又限制放煙花?程序猿有辦法!

          3. 核心區(qū)域:JavaScript

          接下來(lái)就讓咱們進(jìn)入煙花繪制,最核心的部分JavaScript的處理,在這部分咱們要利用canvas的繪制能力,構(gòu)建出煙花效果。

          整個(gè)js的內(nèi)容,我們把它分為四大部分:

          1. 煙花類(lèi) Firework:這里咱們會(huì)通過(guò)function構(gòu)建構(gòu)造函數(shù),創(chuàng)建出自底向上煙花升起效果。

          2023過(guò)年,又限制放煙花?程序猿有辦法!2. 火花類(lèi) Spark:煙花上升到一定位置,會(huì)“綻放“,綻放之后變?yōu)椤被鸹ā埃鸹?lèi)就是處理綻放之后的火花效果的。

          2023過(guò)年,又限制放煙花?程序猿有辦法!

          1. 渲染函數(shù) render:想要完成整個(gè)綻放,需要對(duì)頁(yè)面進(jìn)行不斷地重繪,否則”動(dòng)畫(huà)“會(huì)卡在一個(gè)點(diǎn)不動(dòng)。所以此時(shí)就需要借助到渲染函數(shù),咱們把它叫做 render(vue 代碼對(duì)我影響頗深?。?/p>

          2. 工具函數(shù):工具函數(shù)主要包含兩個(gè),咱們分開(kāi)去說(shuō):

            1. 持續(xù)繪制函數(shù) drawCircle:該函數(shù)可以幫助我們,在每次重新渲染時(shí),進(jìn)行煙花和火花的繪制
            2. 隨機(jī)色值函數(shù) randomColor:該函數(shù)可以幫助我們,得到一個(gè)隨機(jī)的煙花色值,用來(lái)生成新的煙花

          那么明確好大致分類(lèi)之后,接下來(lái)咱們就一步一步的進(jìn)行實(shí)現(xiàn)。

          但是大家要注意:為了保證邏輯的通暢性,咱們需要從工具函數(shù)開(kāi)始進(jìn)行繪制。

          1. 工具函數(shù)

          在剛才咱們說(shuō)過(guò),工具函數(shù)主要包含兩個(gè),那么首先先來(lái)看第一個(gè)工具函數(shù)drawCircle,它的主要作用是:在每次重新渲染時(shí),進(jìn)行煙花和火花的繪制

          // 獲取 canvas 上下文,并指定寬高 let ctx = document.querySelector('canvas').getContext('2d') ctx.canvas.width = window.innerWidth ctx.canvas.height = window.innerHeight  /**  * 持續(xù)繪制  */ function drawCircle(x, y, radius, color) { 	color = color 	ctx.fillStyle = color 	ctx.fillRect(x - radius / 2, y - radius / 2, radius, radius) }
          登錄后復(fù)制

          在上面的代碼中:

          1. 首先:我們拿到了ctx,也就是 CanvasRenderingContext2D 二維渲染上下文 ,利用它可以進(jìn)行繪制渲染
          2. 然后:把canvas的寬高指定為頁(yè)面寬高
          3. 最后:構(gòu)建了drawCircle函數(shù),進(jìn)行持續(xù)繪制。它接收四個(gè)參數(shù):
            1. x:繪制的 x 坐標(biāo)
            2. y:繪制的 y 坐標(biāo)
            3. radius:點(diǎn)的直徑(寬高)
            4. color:色值

          那么此時(shí),只要觸發(fā) drawCircle 函數(shù),就可以進(jìn)行持續(xù)繪制。

          工具函數(shù)繪制完成之后,下面我們來(lái)看第二個(gè)函數(shù):隨機(jī)色值 randomColor:

          /**  * 生成隨機(jī)色值  */ function randomColor() { 	const r = Math.floor(Math.random() * 255) 	const g = Math.floor(Math.random() * 255) 	const b = Math.floor(Math.random() * 255) 	return `rgb(${r},${g},$)` }
          登錄后復(fù)制

          randomColor 函數(shù),主要利用Math.random 生成了一個(gè) 0-255 的隨機(jī)數(shù),三個(gè)隨機(jī)數(shù)共同組成了rgb 色值。

          2. 煙花類(lèi) Firework

          有了工具函數(shù)之后,下面咱們就可以處理煙花類(lèi) Firework。

          煙花類(lèi)本質(zhì)上是:自底向上的,煙花升起效果。 其核心是:生成可以被 drawCircle 繪制的對(duì)象

          所以它內(nèi)部必然包含:坐標(biāo)、綻放點(diǎn)、色彩 等屬性:

          /**  * 煙花構(gòu)造  */ function Firework(x, y) { 	// 初始點(diǎn) 	this.x = x || Math.random() * ctx.canvas.width 	this.y = y || ctx.canvas.height 	// 綻放點(diǎn) 	this.burstLocation = (Math.random() * ctx.canvas.height) / 2 	// 綻放是否已完畢 	this.over = false 	// 煙花色 	this.color = randomColor() }
          登錄后復(fù)制

          在上面的代碼中:

          1. x、y:表示煙花升起的坐標(biāo)。其中y中默認(rèn)為瀏覽器底部,x則可以隨機(jī)
          2. burstLocation:表示定義的綻放點(diǎn)。通常小于屏幕高度的一半,即:在屏幕上半部分”綻放“
          3. over:表示當(dāng)前實(shí)例對(duì)象是否已經(jīng)綻放完畢了。完畢的實(shí)例將不再處理
          4. color:隨機(jī)得到的煙花色

          僅有屬性還不夠,因?yàn)闊熁ㄟ€需要 ”動(dòng)起來(lái)“,所以咱們還需要為它賦值三個(gè)方法,以幫助它進(jìn)行移動(dòng)、持續(xù)繪制、綻放

          // 初始綻放數(shù) const OVERLAP_NUM = 66 // 刷新速度 ms const TIME_STEP = 16 // 煙花移動(dòng)的速度與方向控制 const WALK = 0.2  // 火花數(shù)組 let sparks = [] // 煙花數(shù)組 let fireworks = []  /**  * 煙花構(gòu)造  */ function Firework(x, y) { 	...  	/** 	 * 移動(dòng)的方法 	 */ 	this.move = function () { 		// 橫向偏移 		this.x += WALK 		// 上升與綻放 		if (this.y > this.burstLocation) { 			this.y -= 1 		} else { 			this.burst() 		} 	}  	/** 	 * 持續(xù)繪制 	 */ 	this.draw = function () { 		drawCircle(this.x, this.y, 1.5, this.color) 	} 	/** 	 * 綻放方法 	 */ 	this.burst = function () { 		// 標(biāo)記綻放完畢 		this.over = true 		// 碎裂煙花數(shù) 		let i = Math.floor(Math.random() * 150) + 10 		// 構(gòu)建碎裂對(duì)象 		while (i--) { 			sparks.push(new Spark(this.x, this.y, this.color)) 		} 	} }
          登錄后復(fù)制

          在上面的代碼中,咱們一共構(gòu)建了三個(gè)方法:

          1. move:用來(lái)處理煙花上升。在上升的過(guò)程中,可以通過(guò)this.x += WALK來(lái)進(jìn)行橫向的”微調(diào)“,這樣會(huì)更加漂亮
          2. draw:用來(lái)進(jìn)行持續(xù)繪制。主要借助了drawCircle完成
          3. burst:處理綻放。當(dāng)煙花上升到指定位置時(shí),就需要進(jìn)行綻放處理。所有的綻放過(guò)程,將交由Spark類(lèi)處理。

          3. 火花類(lèi) Spark

          當(dāng)煙花逐漸上升到一定位置之后,則需要進(jìn)行綻放。

          而所謂的綻放就是:煙花爆炸之后迸現(xiàn)出的火花。這一塊的過(guò)程,咱們將通過(guò)Spark進(jìn)行處理。

          煙花綻放時(shí),將迸現(xiàn)出大量的火花,其中每一個(gè)火花,都是一個(gè)Spark實(shí)例。

          所以針對(duì)于Spark而言,它代表的是:單個(gè)火花,從出現(xiàn)到消亡的過(guò)程。

          那么對(duì)于 Spark 它內(nèi)部的代碼來(lái)說(shuō),總體也是分為:屬性、方法 兩部分。

          首先咱們先來(lái)看屬性

          /**  * 火花構(gòu)造  */ function Spark(x, y, color) { 	// 標(biāo)記綻放點(diǎn)位置與色值 	this.x = x 	this.y = y 	this.color = color 	// 位置 	this.dir = Math.random() * (Math.PI * 2) 	// 執(zhí)行完畢 	this.over = false 	// 火花崩裂速度 	this.speed = Math.random() * 3 + 3 	// 火花下墜的速度 	this.gravity = Math.random() + 0.1 	// 火花消失的速度 	this.countdown = this.speed * 10 }
          登錄后復(fù)制

          對(duì)于以上代碼來(lái)說(shuō):

          1. x、y、color:表示綻放的位置與色值
          2. dir:表示綻放后的位置
          3. over:表示綻放完成
          4. speed:火花崩裂之后的運(yùn)行速度
          5. gravity:火花開(kāi)始下墜時(shí)的速度,它在計(jì)算時(shí)會(huì)進(jìn)行遞增(加速)
          6. countdown:消失的倒計(jì)時(shí)

          有了屬性之后,下面咱們需要通過(guò)兩個(gè)方法,來(lái)保證Spark的移動(dòng)和繪制:

          /**  * 火花構(gòu)造  */ function Spark(x, y, color) { 	... 	/** 	 * 火花移動(dòng)方法 	 */ 	this.move = function () { 		// 倒計(jì)時(shí)處理 		this.countdown-- 		if (this.countdown < 0) { 			this.over = true 		}  		// 速度遞減 		if (this.speed > 0) { 			this.speed -= 0.1 		}  		if (this.speed < 0) { 			return 		}  		// x、y 坐標(biāo)位置 		this.x += Math.cos(this.dir + WALK) * this.speed 		this.y += Math.sin(this.dir + WALK) * this.speed 		this.y += this.gravity 		// 下墜速度加快 		this.gravity += 0.05 	} 	/** 	 * 繪制 	 */ 	this.draw = function () { 		drawCircle(this.x, this.y, 3, this.color) 	} }
          登錄后復(fù)制

          其中:

          1. move:代表移動(dòng)的過(guò)程。在這里咱們利用Math.cos 和 Math.sin 計(jì)算了坐標(biāo)位置,并且通過(guò)this.gravity += 0.05 增加了煙花下墜的速度。
          2. draw:代表持續(xù)繪制。同樣需要利用drawCircle方法。

          4. 渲染函數(shù) render

          那么最后,咱們就可以來(lái)構(gòu)建render函數(shù)。

          render 函數(shù)的核心作用是:保證煙花的不斷渲染。要達(dá)到這個(gè)目的,咱們就必須要保證render 函數(shù)不斷重復(fù)執(zhí)行

          想要讓render重復(fù)執(zhí)行其實(shí)有兩種方式:

          1.window.requestAnimationFrame:該方法可以保證高性能的持續(xù)重繪。但是高刷屏幕下會(huì)導(dǎo)致 ”速率過(guò)快“2.window.setTimeout:該方法可以通過(guò)delay控制速率,所以在當(dāng)前場(chǎng)景中比較推薦。

          /**  * 渲染函數(shù)  */ function render() { 	// 夜幕背景色與區(qū)域 	ctx.fillStyle = 'rgba(0, 0, 0, 0.1)' 	ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)  	// 煙花上升 	for (let firework of fireworks) { 		if (firework.over) { 			continue 		} 		firework.move() 		firework.draw() 	}  	// 火花下墜 	for (let spark of sparks) { 		if (spark.over) { 			continue 		} 		spark.move() 		spark.draw() 	}  	// 通過(guò)隨機(jī)數(shù)來(lái)控制煙花產(chǎn)生速度 	if (Math.random() < 0.05) { 		fireworks.push(new Firework()) 	}  	// 重復(fù)渲染 	setTimeout(render, TIME_STEP) }
          登錄后復(fù)制

          5. 完整代碼

          因?yàn)檎椎?code>js代碼比較多,所以咱們?cè)谧詈?,把整個(gè)的js代碼給大家貼出來(lái)(因?yàn)槲也幌嘈拍銈儠?huì)一步一步跟著學(xué) ??????),以方便大家隨取隨用(我是不是很周到??????)

          // 獲取 canvas 上下文,并指定寬高 let ctx = document.querySelector('canvas').getContext('2d') ctx.canvas.width = window.innerWidth ctx.canvas.height = window.innerHeight  // 初始綻放數(shù) const OVERLAP_NUM = 66 // 刷新速度 ms const TIME_STEP = 16 // 煙花移動(dòng)的速度與方向控制 const WALK = 0.2  // 火花數(shù)組 let sparks = [] // 煙花數(shù)組 let fireworks = []  // 初始爆炸的填充邏輯 for (let i = 0; i < OVERLAP_NUM; i++) { 	// 填充 	fireworks.push( 		// 構(gòu)建隨機(jī)位置 		new Firework( 			Math.random() * window.innerWidth, 			Math.random() * window.innerHeight 		) 	) }  /**  * 渲染函數(shù)  */ function render() { 	// 夜幕背景色與區(qū)域 	ctx.fillStyle = 'rgba(0, 0, 0, 0.1)' 	ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)  	// 煙花上升 	for (let firework of fireworks) { 		if (firework.over) { 			continue 		} 		firework.move() 		firework.draw() 	}  	// 火花下墜 	for (let spark of sparks) { 		if (spark.over) { 			continue 		} 		spark.move() 		spark.draw() 	}  	// 通過(guò)隨機(jī)數(shù)來(lái)控制煙花產(chǎn)生速度 	if (Math.random() < 0.05) { 		fireworks.push(new Firework()) 	}  	// 重復(fù)渲染 	setTimeout(render, TIME_STEP) }  /**  * 火花構(gòu)造  */ function Spark(x, y, color) { 	// 標(biāo)記綻放點(diǎn)位置與色值 	this.x = x 	this.y = y 	this.color = color 	// 位置 	this.dir = Math.random() * (Math.PI * 2) 	// 執(zhí)行完畢 	this.over = false 	// 火花崩裂速度 	this.speed = Math.random() * 3 + 3 	// 火花下墜的速度 	this.gravity = Math.random() + 0.1 	// 火花消失的速度 	this.countdown = this.speed * 10 	/** 	 * 火花移動(dòng)方法 	 */ 	this.move = function () { 		// 倒計(jì)時(shí)處理 		this.countdown-- 		if (this.countdown < 0) { 			this.over = true 		}  		// 速度遞減 		if (this.speed > 0) { 			this.speed -= 0.1 		}  		if (this.speed < 0) { 			return 		}  		// x、y 坐標(biāo)位置 		this.x += Math.cos(this.dir + WALK) * this.speed 		this.y += Math.sin(this.dir + WALK) * this.speed 		this.y += this.gravity 		// 下墜速度加快 		this.gravity += 0.05 	} 	/** 	 * 繪制 	 */ 	this.draw = function () { 		drawCircle(this.x, this.y, 3, this.color) 	} }  /**  * 煙花構(gòu)造  */ function Firework(x, y) { 	// 初始點(diǎn) 	this.x = x || Math.random() * ctx.canvas.width 	this.y = y || ctx.canvas.height 	// 綻放點(diǎn) 	this.burstLocation = (Math.random() * ctx.canvas.height) / 2 	// 綻放是否已完畢 	this.over = false 	// 煙花色 	this.color = randomColor()  	/** 	 * 移動(dòng)的方法 	 */ 	this.move = function () { 		// 橫向偏移 		this.x += WALK 		// 上升與綻放 		if (this.y > this.burstLocation) { 			this.y -= 1 		} else { 			this.burst() 		} 	}  	/** 	 * 持續(xù)繪制 	 */ 	this.draw = function () { 		drawCircle(this.x, this.y, 1.5, this.color) 	} 	/** 	 * 綻放方法 	 */ 	this.burst = function () { 		// 標(biāo)記綻放完畢 		this.over = true 		// 碎裂煙花數(shù) 		let i = Math.floor(Math.random() * 150) + 10 		// 構(gòu)建碎裂對(duì)象 		while (i--) { 			sparks.push(new Spark(this.x, this.y, this.color)) 		} 	} }  /**  * 持續(xù)繪制  */ function drawCircle(x, y, radius, color) { 	color = color 	ctx.fillStyle = color 	ctx.fillRect(x - radius / 2, y - radius / 2, radius, radius) }  /**  * 生成隨機(jī)色值  */ function randomColor() { 	const r = Math.floor(Math.random() * 255) 	const g = Math.floor(Math.random() * 255) 	const b = Math.floor(Math.random() * 255) 	return `rgb(${r},${g},$)` }  // 開(kāi)始 render()
          登錄后復(fù)制

          總結(jié)

          三年抗疫,咱們共同經(jīng)歷了封控、裁員、降薪等一系列讓人感到”始料未及“的事情。

          我甚至一度以為將來(lái)會(huì)變成”封控常態(tài)化“、”裁員常態(tài)化“、”降薪常態(tài)化“。

          但是在新的2023年到來(lái)之前,所有的一切都已經(jīng)變成了過(guò)去式。

          讓我們用一場(chǎng)煙花告別過(guò)去,迎接未來(lái)!

          2023 年將會(huì)是一個(gè)好的年度,大家一起加油!

          在這里:Sunday 祝大家:新年快樂(lè),兔年大吉!

        2. 微信
        3. 分享
        4. 聲明:本文轉(zhuǎn)載于:juejin,如有侵犯,請(qǐng)聯(lián)系admin@php.cn刪除

        5. 相關(guān)標(biāo)簽:前端 JavaScript 程序員
          • 上一篇:程序員在Boss上投簡(jiǎn)歷要注意了!
          • 下一篇:沒(méi)有了
          贊(0)
          分享到: 更多 (0)
          網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)