兔年新春

今天是兔年大年初二,神州大地,在經(jīng)歷了疫情的三年后迎來(lái)開放的一個(gè)春節(jié)。大家都沉浸在歡樂幸福的春節(jié)氣氛中。玉兔迎新春,祝福齊送到:白兔祝你身體安康,黑兔祝你薪水高漲,灰兔送你夢(mèng)想如意,花兔愿你早日高升,公兔祈禱你名利雙收,母兔稱贊你家和萬(wàn)事興,只有兔崽崽最淘氣,鞭炮連連,讓你歡樂一整年。祝各位技術(shù)同仁在新的一年里,發(fā)量比Bug多,他/她比最帥/最靚的明星更亮,RMB把錢包撐破。
一、橘子洲頭
1、橘子洲與偉人

大家對(duì)《沁園春.長(zhǎng)沙》想必都非常熟悉。詞的內(nèi)容,上闕為描寫湘江、橘子洲、岳簏山生機(jī)盎然的秋景,下闕為懷念同學(xué)少年的生活,抒發(fā)救世濟(jì)民的遠(yuǎn)大理想,洋溢著激流奮進(jìn)的壯志和豪情?,F(xiàn)在,詩(shī)詞碑已成為橘洲景區(qū)的標(biāo)志性景點(diǎn)之一。詞中,橘子洲頭、看萬(wàn)山紅遍、層林盡染、萬(wàn)江碧透、百舸爭(zhēng)流,描述的就是橘子洲頭的景象。恰同學(xué)少年,風(fēng)華正茂,書生意氣,揮斥方遒。表達(dá)了偉人當(dāng)時(shí)的遠(yuǎn)大理想和壯志豪情,每次登臨岳麓山,到岳麓書院,于橘子洲頭,感受到流傳下來(lái)的氣魄,因此,這山和水也便被賦予了精神。

2、橘子洲與煙花
作為旅游城市,橘子洲的煙花表演一直是以前很多來(lái)星城必須要進(jìn)行的一項(xiàng)打卡活動(dòng),同時(shí)也是湖南煙花對(duì)外展示的一個(gè)窗口。當(dāng)然,煙花燃放的污染物排放一直是人們關(guān)注的首個(gè)重點(diǎn)目標(biāo),而現(xiàn)在瀏陽(yáng)煙花也是不斷的改進(jìn)煙花燃放工藝,爭(zhēng)取減少污染區(qū)的排放。而隨著疫情的爆發(fā),也加上對(duì)排污治理的整治,橘子洲煙花與人們的邂逅機(jī)會(huì)就越來(lái)越少,曾幾何時(shí),橘子洲煙花是一周一次,后面變成了逢重大活動(dòng)才燃放,一般在一年4次左右。下面來(lái)幾張?jiān)?jīng)的橘子洲煙花的燃放盛況,供大家觀賞吧,圖片來(lái)源于網(wǎng)絡(luò)供圖(百家號(hào)和影像湖南)。


3、綠色燃放
雖然現(xiàn)在難得遇到一次橘子洲頭的煙花燃放,但作為技術(shù)人,可以充分利用WebGL技術(shù),結(jié)合時(shí)空地理地圖,地形數(shù)據(jù)來(lái)一場(chǎng)實(shí)時(shí)可見的煙花燃放盛況。在這里遇見岳麓山、遇見橘子洲頭,山水洲城的盛宴。在本文中基于Cesium開源框架,采用開源WebGL技術(shù),疊加全國(guó)影像地圖(本地私有化),標(biāo)簽路網(wǎng)數(shù)據(jù)、地形數(shù)據(jù),采用粒子系統(tǒng),實(shí)現(xiàn)煙花燃放的效果。先來(lái)一張效果圖開胃吧。

二、Cesium煙花實(shí)現(xiàn)
1、相關(guān)依賴
由于采用Cesium開源實(shí)現(xiàn),因此基礎(chǔ)的依賴于Cesium.js,感興趣的朋友可以自行在github(cesium github)或者官方網(wǎng)站(cesium)上下載相關(guān)依賴。Cesium可以基于原生的html5和javascript來(lái)進(jìn)行運(yùn)行,也支持和現(xiàn)代流程框架React和Vue等前端框架進(jìn)行集成開發(fā)??梢愿鶕?jù)自己的技術(shù)棧來(lái)合理選型。


將下載之后的Cesium編譯后的js文件復(fù)制到工程的Build目錄下,如下所示:

在上一層的Documentation目錄中是同版本對(duì)應(yīng)的API文檔,您可以直接打開html頁(yè)面,這是最全的API介紹文檔。


2、新建html頁(yè)面
在cesiumdemo或者任意目錄下新建fireworks2.html,關(guān)鍵代碼如下所示:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Use correct character set. -->
<meta charset="utf-8" />
<!-- Tell IE to use the latest, best version. -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- Make the application on mobile take up the full browser screen and disable user scaling. -->
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
/>
<title>大展宏兔,大吉大利</title>
<script src="Build/Cesium/Cesium.js"></script>
<style>
@import url(Build/Cesium/Widgets/widgets.css);
html,
body,
#cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="cesiumContainer"></div>
</body>
</html>
在上面的代碼中通過(guò)引入Cesium.js,并且在頁(yè)面中創(chuàng)建了一個(gè)div用于渲染展示cesium地球組件。但這是還未將cesium和頁(yè)面元素進(jìn)行綁定,也沒有加載加載相應(yīng)的底圖和地形數(shù)據(jù)。
3、底圖和地形數(shù)據(jù)加載
下面將通過(guò)UrlTemplateImageryProvider對(duì)象來(lái)進(jìn)行Cesium的底圖對(duì)象定義,示例代如下所示:
//加載影像底圖
var imageryProvider = new Cesium.UrlTemplateImageryProvider({
url: "http://localhost:8086/data/basemap_water/{z}/{x}/{y}.png",
tilingScheme: new Cesium.WebMercatorTilingScheme(),
fileExtension: 'png',
minimumLevel: 1,
maximumLevel: 16
});
var labelProvider = new Cesium.UrlTemplateImageryProvider({
url: "http://localhost:8086/data/basemap_nowater/1-10label/{z}/{x}/{y}.png",
tilingScheme: new Cesium.GeographicTilingScheme(),//投影方式為經(jīng)緯度直投,否則路網(wǎng)不對(duì)
fileExtension: 'png',
minimumLevel: 1,
maximumLevel: 10
});

//加載本地地形數(shù)據(jù)
var terrainLayer = new Cesium.CesiumTerrainProvider({
url: "http://localhost:8086/data/hunanterrain",
// 請(qǐng)求照明
requestVertexNormals: true,
// 請(qǐng)求水波紋效果
requestWaterMask: false
});
上面的代碼定義了地形數(shù)據(jù),同時(shí)使用如下的代碼將地形數(shù)據(jù)、底圖數(shù)據(jù)都添加到Cesium的視圖對(duì)象中,并且將標(biāo)簽圖層也添加到對(duì)象中。用于系統(tǒng),同時(shí)將cesium的展示視角初始調(diào)整為橘子洲的經(jīng)緯度坐標(biāo)。
var viewer = new Cesium.Viewer('cesiumContainer',{
imageryProvider:imageryProvider,
terrainProvider: terrainLayer,
baseLayerPicker:false,
homeButton: true,
baseLayerPicker: false,
animation: false,
timeline: false,
navigationHelpButton: false,
geocoder: false,
sceneModePicker: false,
shouldAnimate: true,
});
// 設(shè)置相機(jī)初始位置
var homeCameraView = {
destination: Cesium.Cartesian3.fromDegrees(112.955074,28.16843,507.0480578185452),
orientation: {
heading:5.656571359006588,
pitch: -0.28428181994862656,
roll: 0
},
};
viewer.camera.setView(homeCameraView);
viewer.imageryLayers.addImageryProvider(labelProvider);
// 隱藏版權(quán)信息
viewer._cesiumWidget._creditContainer.style.display = "none";
viewer.scene.globe.enableLighting = false;//關(guān)閉光照
4、粒子系統(tǒng)
粒子系統(tǒng)是WebGL中的一個(gè)非常重要的組成部分,通過(guò)粒子系統(tǒng)可以實(shí)現(xiàn)很多的特效。粒子系統(tǒng)是一種模擬復(fù)雜物理效應(yīng)的圖形技術(shù)。粒子系統(tǒng)是小圖片的集合,當(dāng)放到一起觀察它們時(shí),會(huì)形成一個(gè)更復(fù)雜的“模糊”對(duì)象,例如火、煙霧、氣候,或者煙火(fireworks)。通過(guò)使用例如初始位置、速度和壽命屬性來(lái)指定單個(gè)粒子的行為,可以控制這些復(fù)雜的效果。這里推薦一篇介紹粒子系統(tǒng)比較簡(jiǎn)單同時(shí)講解比較清楚的入門博客Cesium中文教程-粒子系統(tǒng)介紹(Introduction to Particle Systems)和cesium粒子系統(tǒng)介紹,更多的關(guān)于粒子系統(tǒng)的說(shuō)明,可以上WebGL知識(shí)去深入學(xué)習(xí),這里不做特別深入的講解(因?yàn)椴┲饕矊W(xué)得不深)。本文結(jié)合代碼來(lái)簡(jiǎn)要說(shuō)明粒子系統(tǒng)的一些知識(shí)。
模擬圖片源,粒子系統(tǒng)可以理解是多個(gè)小圖片的集合整體渲染。所以可以基于外部圖片的渲染,比如爆炸的效果,同時(shí)作為煙花的特效,這里采用模擬圖片實(shí)現(xiàn)。關(guān)鍵代碼如下:
let particleCanvas;
function getImage() {
if (!Cesium.defined(particleCanvas)) {
particleCanvas = document.createElement("canvas");
particleCanvas.width = 30;
particleCanvas.height = 30;
const context2D = particleCanvas.getContext("2d");
context2D.beginPath();
context2D.arc(10, 10, 10, 0, Cesium.Math.TWO_PI, true);
context2D.closePath();
context2D.fillStyle = "rgb(255, 255, 255)";
context2D.fill();
}
return particleCanvas;
}
粒子系統(tǒng)在Cesium被進(jìn)行了簡(jiǎn)單封裝,開發(fā)者通過(guò)API進(jìn)行簡(jiǎn)單調(diào)用即可。
new Cesium.ParticleSystem({
image: getImage(),
startColor: color,
endColor: color.withAlpha(0.0),
particleLife: life,
speed: 30.0,
imageSize: particlePixelSize,
emissionRate: 0,
emitter: new Cesium.SphereEmitter(1.8),
bursts: bursts,
lifetime: lifetime,
updateCallback: force,
modelMatrix: modelMatrix,
emitterModelMatrix: emitterModelMatrix,
})
);

最后通過(guò)循環(huán)和一些隨機(jī)坐標(biāo)偏移來(lái)實(shí)現(xiàn)煙花的位置隨機(jī)展示,在粒子播放的時(shí)候,會(huì)進(jìn)行回歸調(diào)用。
const xMin = -100.0;
const xMax = 150.0;
const yMin = -80.0;
const yMax = 150.0;
const zMin = -50.0;
const zMax = 50.0;
const colorOptions = [
{
minimumRed: 0.75,
green: 0.0,
minimumBlue: 0.8,
alpha: 1.0,
},
{
red: 0.0,
minimumGreen: 0.75,
minimumBlue: 0.8,
alpha: 1.0,
},
{
red: 0.0,
green: 0.0,
minimumBlue: 0.8,
alpha: 1.0,
},
{
minimumRed: 0.75,
minimumGreen: 0.75,
blue: 0.0,
alpha: 1.0,
},
];
for (let i = 0; i < numberOfFireworks; ++i) {
const x = Cesium.Math.randomBetween(xMin, xMax);
const y = Cesium.Math.randomBetween(yMin, yMax);
const z = Cesium.Math.randomBetween(zMin, zMax);
const offset = new Cesium.Cartesian3(x, y, z);
const color = Cesium.Color.fromRandom(
colorOptions[i % colorOptions.length]
);
const bursts = [];
for (let j = 0; j < 5; ++j) {
bursts.push(
new Cesium.ParticleBurst({
time: Cesium.Math.nextRandomNumber() * lifetime,
minimum: burstSize,
maximum: burstSize,
})
);
}
createFirework(offset, color, bursts);
}
下面給一個(gè)最終的效果圖,一個(gè)在橘子洲頭的動(dòng)態(tài)煙花效果,真誠(chéng)的祝福大家新年快樂,兔年大吉。

5、粒子系統(tǒng)加載
這里給的Cesium.js是編譯之后的,所以對(duì)于debug不太友好,如果需要源碼調(diào)試可以使用開發(fā)版本,可以觀察到更深入的調(diào)用過(guò)程。對(duì)于理解粒子系統(tǒng)更加有幫助,調(diào)試起來(lái)吧。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-791670.html


總結(jié)
以上就是本文的所有內(nèi)容,本文首先介紹了橘子洲頭的一些相關(guān)知識(shí),它與偉人的淵源,與煙花的關(guān)系。最主要的是介紹了基于Cesium的電子煙花的展示播放技術(shù),重點(diǎn)介紹了在Cesium中如何進(jìn)行集成,粒子系統(tǒng)的創(chuàng)建過(guò)程以及加載技術(shù)。最后祝所有的技術(shù)人都能一飛沖天,炫彩奪目。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-791670.html
到了這里,關(guān)于兔年首文迎新春-Cesium橘子洲煙花禮贊的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!