站長資訊網
        最全最豐富的資訊網站

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

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

        ↑↑↑↑↑↑ 效果圖鎮樓 ↑↑↑↑↑↑

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

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

        大家都很興奮,很多小伙伴開始購買煙花。特別是今年特別火的 “加特林 ?”

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

        但是大家興奮勁還沒過呢,隨著官方 一紙禁令,讓咱們知道了:

        2023 過春年

        煙花依然了無緣

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

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

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

        不過身為程序猿的我們,能就這么認栽了?

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

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

        所以我辛苦閉關九九八十一秒(開玩笑~我寫了好幾天),終于把煙花放到了瀏覽器上,看著效果我是“內牛滿面(淚流滿面)”??!

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

        此時,我真想仰天長嘯,大聲唱道:

        2023 過春年,

        煙花依然了無緣;

        這能難倒程序猿?

        一鍵三連過大年!

        代碼

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

        咱們整個的代碼一共分為三個部分:

        • html:用來構建項目結構

        • css:處理文字樣式

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

        那么下面,咱們就針對這三個部分,分別進行處理:

        1. html

        整個 html 分為兩部分:

        1. 文字結構:用來處理右下角的文本

        2023過年,又限制放煙花?程序猿有辦法!2. canvas 畫板:作為煙花渲染區

        1. 文字結構

        文字結構整體的內容處理會比較簡單,通過div包裹“文本標簽”即可:

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

        2. canvas

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

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

        所以在html區域部分,我們必須提供一個canvas繪制區:

        <!-- 煙花渲染區 --> <canvas></canvas>
        登錄后復制

        html 區域總結

        當咱們完成基本的html繪制之后,運行代碼到瀏覽器,效果應該是這個樣子的:

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

        啥都沒有對吧,別著急,下面咱們去處理css部分。

        2. css

        css 處理的核心目的,是為了幫助咱們繪制文字區域的樣式(沒錯,與煙花無關)。

        所以,整個css區域繪制會比較簡單

        咱們直接來看代碼:

        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%; }
        登錄后復制

        繪制了css之后,頁面效果應該是這個樣子的:

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

        3. 核心區域:JavaScript

        接下來就讓咱們進入煙花繪制,最核心的部分JavaScript的處理,在這部分咱們要利用canvas的繪制能力,構建出煙花效果。

        整個js的內容,我們把它分為四大部分:

        1. 煙花類 Firework:這里咱們會通過function構建構造函數,創建出自底向上煙花升起效果。

        2023過年,又限制放煙花?程序猿有辦法!2. 火花類 Spark:煙花上升到一定位置,會“綻放“,綻放之后變為”火花“,火花類就是處理綻放之后的火花效果的。

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

        1. 渲染函數 render:想要完成整個綻放,需要對頁面進行不斷地重繪,否則”動畫“會卡在一個點不動。所以此時就需要借助到渲染函數,咱們把它叫做 render(vue 代碼對我影響頗深?。?/p>

        2. 工具函數:工具函數主要包含兩個,咱們分開去說:

          1. 持續繪制函數 drawCircle:該函數可以幫助我們,在每次重新渲染時,進行煙花和火花的繪制
          2. 隨機色值函數 randomColor:該函數可以幫助我們,得到一個隨機的煙花色值,用來生成新的煙花

        那么明確好大致分類之后,接下來咱們就一步一步的進行實現。

        但是大家要注意:為了保證邏輯的通暢性,咱們需要從工具函數開始進行繪制。

        1. 工具函數

        在剛才咱們說過,工具函數主要包含兩個,那么首先先來看第一個工具函數drawCircle,它的主要作用是:在每次重新渲染時,進行煙花和火花的繪制

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

        在上面的代碼中:

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

        那么此時,只要觸發 drawCircle 函數,就可以進行持續繪制。

        工具函數繪制完成之后,下面我們來看第二個函數:隨機色值 randomColor:

        /**  * 生成隨機色值  */ 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},$)` }
        登錄后復制

        randomColor 函數,主要利用Math.random 生成了一個 0-255 的隨機數,三個隨機數共同組成了rgb 色值。

        2. 煙花類 Firework

        有了工具函數之后,下面咱們就可以處理煙花類 Firework。

        煙花類本質上是:自底向上的,煙花升起效果。 其核心是:生成可以被 drawCircle 繪制的對象

        所以它內部必然包含:坐標、綻放點、色彩 等屬性:

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

        在上面的代碼中:

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

        僅有屬性還不夠,因為煙花還需要 ”動起來“,所以咱們還需要為它賦值三個方法,以幫助它進行移動、持續繪制、綻放

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

        在上面的代碼中,咱們一共構建了三個方法:

        1. move:用來處理煙花上升。在上升的過程中,可以通過this.x += WALK來進行橫向的”微調“,這樣會更加漂亮
        2. draw:用來進行持續繪制。主要借助了drawCircle完成
        3. burst:處理綻放。當煙花上升到指定位置時,就需要進行綻放處理。所有的綻放過程,將交由Spark類處理。

        3. 火花類 Spark

        當煙花逐漸上升到一定位置之后,則需要進行綻放。

        而所謂的綻放就是:煙花爆炸之后迸現出的火花。這一塊的過程,咱們將通過Spark進行處理。

        煙花綻放時,將迸現出大量的火花,其中每一個火花,都是一個Spark實例。

        所以針對于Spark而言,它代表的是:單個火花,從出現到消亡的過程。

        那么對于 Spark 它內部的代碼來說,總體也是分為:屬性、方法 兩部分。

        首先咱們先來看屬性

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

        對于以上代碼來說:

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

        有了屬性之后,下面咱們需要通過兩個方法,來保證Spark的移動和繪制:

        /**  * 火花構造  */ function Spark(x, y, color) { 	... 	/** 	 * 火花移動方法 	 */ 	this.move = function () { 		// 倒計時處理 		this.countdown-- 		if (this.countdown < 0) { 			this.over = true 		}  		// 速度遞減 		if (this.speed > 0) { 			this.speed -= 0.1 		}  		if (this.speed < 0) { 			return 		}  		// x、y 坐標位置 		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) 	} }
        登錄后復制

        其中:

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

        4. 渲染函數 render

        那么最后,咱們就可以來構建render函數。

        render 函數的核心作用是:保證煙花的不斷渲染。要達到這個目的,咱們就必須要保證render 函數不斷重復執行

        想要讓render重復執行其實有兩種方式:

        1.window.requestAnimationFrame:該方法可以保證高性能的持續重繪。但是高刷屏幕下會導致 ”速率過快“2.window.setTimeout:該方法可以通過delay控制速率,所以在當前場景中比較推薦。

        /**  * 渲染函數  */ function render() { 	// 夜幕背景色與區域 	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() 	}  	// 通過隨機數來控制煙花產生速度 	if (Math.random() < 0.05) { 		fireworks.push(new Firework()) 	}  	// 重復渲染 	setTimeout(render, TIME_STEP) }
        登錄后復制

        5. 完整代碼

        因為整套的js代碼比較多,所以咱們在最后,把整個的js代碼給大家貼出來(因為我不相信你們會一步一步跟著學 ??????),以方便大家隨取隨用(我是不是很周到??????)

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

        總結

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

        我甚至一度以為將來會變成”封控常態化“、”裁員常態化“、”降薪常態化“。

        但是在新的2023年到來之前,所有的一切都已經變成了過去式。

        讓我們用一場煙花告別過去,迎接未來!

        2023 年將會是一個好的年度,大家一起加油!

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

      1. 微信
      2. 分享
      3. 聲明:本文轉載于:juejin,如有侵犯,請聯系admin@php.cn刪除

      4. 相關標簽:前端 JavaScript 程序員
        • 上一篇:程序員在Boss上投簡歷要注意了!
        • 下一篇:沒有了
        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 国产高清精品在线| 国产高清在线精品二区一| 日韩精品久久久久久久电影蜜臀| 久久精品无码一区二区三区| 日韩在线精品一二三区| 久久精品国产影库免费看| 久久精品中文无码资源站| 久久精品中文字幕有码| 91精品国产成人网在线观看 | 国产精品免费一区二区三区四区| 日本精品自产拍在线观看中文| 91精品国产色综久久| 99国产欧美久久久精品蜜芽| 综合人妻久久一区二区精品| 精品一区二区三区色花堂| 99热这里只有精品国产66| 99精品久久久久中文字幕| 久久国产亚洲精品无码| 亚洲精品制服丝袜四区| 亚洲国产成人精品久久久国产成人一区二区三区综 | 成人精品视频一区二区三区| 亚洲爆乳精品无码一区二区| 久久99精品久久久久久不卡| 99久久国产综合精品网成人影院 | 久久精品国产精品亜洲毛片| 国产精品美女久久久久av爽| 欧美亚洲精品在线| 99re8这里有精品热视频免费| 孩交VIDEOS精品乱子| 无码人妻精品一区二区三区夜夜嗨| 日韩AV毛片精品久久久| 精品久久久久久无码人妻蜜桃| 欧美一区二区精品| 亚洲综合国产精品| 国产成人精品天堂| 国产精品无码a∨精品| 99精品影院| 国产91精品一区二区麻豆亚洲 | 久久精品一区二区影院| 黑人巨茎精品欧美一区二区| 四虎永久在线精品884aa下载|