程式員每日一樂:html動態煙花設計 3D

来源:https://www.cnblogs.com/igqx/archive/2020/07/22/13361081.html
-Advertisement-
Play Games

經過一天的的工作或者學習是否感到枯燥乏味?現在的你是否想找些樂子?下麵我將教大家製作簡單易做的3D煙花動態網頁,告別無聊與乏味。。。。。 第一步:首先新建一個文本文檔。 第二步:將以下代碼複製到該文本文檔中,保存。 <!doctype html><html><head><meta charset=" ...


 

 

經過一天的的工作或者學習是否感到枯燥乏味?現在的你是否想找些樂子?下麵我將教大家製作簡單易做的3D煙花動態網頁,告別無聊與乏味。。。。。

 

第一步:首先新建一個文本文檔。

第二步:將以下代碼複製到該文本文檔中,保存。

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>3D煙花</title>

<style>
html,body{
margin:0px;
width:100%;
height:100%;
overflow:hidden;
background:#000;
}

#canvas{
width:100%;
height:100%;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas><script>
function initVars(){

pi=Math.PI;
ctx=canvas.getContext("2d");
canvas.width=canvas.clientWidth;
canvas.height=canvas.clientHeight;
cx=canvas.width/2;
cy=canvas.height/2;
playerZ=-25;
playerX=playerY=playerVX=playerVY=playerVZ=pitch=yaw=pitchV=yawV=0;
scale=600;
seedTimer=0;seedInterval=5,seedLife=100;gravity=.02;
seeds=new Array();
sparkPics=new Array();
s="https://cantelope.org/NYE/";
for(i=1;i<=10;++i){
sparkPic=new Image();
sparkPic.src=s+"spark"+i+".png";
sparkPics.push(sparkPic);
}
sparks=new Array();
pow1=new Audio(s+"pow1.ogg");
pow2=new Audio(s+"pow2.ogg");
pow3=new Audio(s+"pow3.ogg");
pow4=new Audio(s+"pow4.ogg");
frames = 0;
}

function rasterizePoint(x,y,z){

var p,d;
x-=playerX;
y-=playerY;
z-=playerZ;
p=Math.atan2(x,z);
d=Math.sqrt(x*x+z*z);
x=Math.sin(p-yaw)*d;
z=Math.cos(p-yaw)*d;
p=Math.atan2(y,z);
d=Math.sqrt(y*y+z*z);
y=Math.sin(p-pitch)*d;
z=Math.cos(p-pitch)*d;
var rx1=-1000,ry1=1,rx2=1000,ry2=1,rx3=0,ry3=0,rx4=x,ry4=z,uc=(ry4-ry3)*(rx2-rx1)-(rx4-rx3)*(ry2-ry1);
if(!uc) return {x:0,y:0,d:-1};
var ua=((rx4-rx3)*(ry1-ry3)-(ry4-ry3)*(rx1-rx3))/uc;
var ub=((rx2-rx1)*(ry1-ry3)-(ry2-ry1)*(rx1-rx3))/uc;
if(!z)z=.000000001;
if(ua>0&&ua<1&&ub>0&&ub<1){
return {
x:cx+(rx1+ua*(rx2-rx1))*scale,
y:cy+y/z*scale,
d:Math.sqrt(x*x+y*y+z*z)
};
}else{
return {
x:cx+(rx1+ua*(rx2-rx1))*scale,
y:cy+y/z*scale,
d:-1
};
}
}

function spawnSeed(){

seed=new Object();
seed.x=-50+Math.random()*100;
seed.y=25;
seed.z=-50+Math.random()*100;
seed.vx=.1-Math.random()*.2;
seed.vy=-1.5;//*(1+Math.random()/2);
seed.vz=.1-Math.random()*.2;
seed.born=frames;
seeds.push(seed);
}

function splode(x,y,z){

t=5+parseInt(Math.random()*150);
sparkV=1+Math.random()*2.5;
type=parseInt(Math.random()*3);
switch(type){
case 0:
pic1=parseInt(Math.random()*10);
break;
case 1:
pic1=parseInt(Math.random()*10);
do{ pic2=parseInt(Math.random()*10); }while(pic2==pic1);
break;
case 2:
pic1=parseInt(Math.random()*10);
do{ pic2=parseInt(Math.random()*10); }while(pic2==pic1);
do{ pic3=parseInt(Math.random()*10); }while(pic3==pic1 || pic3==pic2);
break;
}
for(m=1;m<t;++m){
spark=new Object();
spark.x=x; spark.y=y; spark.z=z;
p1=pi*2*Math.random();
p2=pi*Math.random();
v=sparkV*(1+Math.random()/6)
spark.vx=Math.sin(p1)*Math.sin(p2)*v;
spark.vz=Math.cos(p1)*Math.sin(p2)*v;
spark.vy=Math.cos(p2)*v;
switch(type){
case 0: spark.img=sparkPics[pic1]; break;
case 1:
spark.img=sparkPics[parseInt(Math.random()*2)?pic1:pic2];
break;
case 2:
switch(parseInt(Math.random()*3)){
case 0: spark.img=sparkPics[pic1]; break;
case 1: spark.img=sparkPics[pic2]; break;
case 2: spark.img=sparkPics[pic3]; break;
}
break;
}
spark.radius=25+Math.random()*50;
spark.alpha=1;
spark.trail=new Array();
sparks.push(spark);
}
switch(parseInt(Math.random()*4)){
case 0: pow=new Audio(s+"pow1.ogg"); break;
case 1: pow=new Audio(s+"pow2.ogg"); break;
case 2: pow=new Audio(s+"pow3.ogg"); break;
case 3: pow=new Audio(s+"pow4.ogg"); break;
}
d=Math.sqrt((x-playerX)*(x-playerX)+(y-playerY)*(y-playerY)+(z-playerZ)*(z-playerZ));
pow.volume=1.5/(1+d/10);
pow.play();
}

function doLogic(){

if(seedTimer<frames){
seedTimer=frames+seedInterval*Math.random()*10;
spawnSeed();
}
for(i=0;i<seeds.length;++i){
seeds[i].vy+=gravity;
seeds[i].x+=seeds[i].vx;
seeds[i].y+=seeds[i].vy;
seeds[i].z+=seeds[i].vz;
if(frames-seeds[i].born>seedLife){
splode(seeds[i].x,seeds[i].y,seeds[i].z);
seeds.splice(i,1);
}
}
for(i=0;i<sparks.length;++i){
if(sparks[i].alpha>0 && sparks[i].radius>5){
sparks[i].alpha-=.01;
sparks[i].radius/=1.02;
sparks[i].vy+=gravity;
point=new Object();
point.x=sparks[i].x;
point.y=sparks[i].y;
point.z=sparks[i].z;
if(sparks[i].trail.length){
x=sparks[i].trail[sparks[i].trail.length-1].x;
y=sparks[i].trail[sparks[i].trail.length-1].y;
z=sparks[i].trail[sparks[i].trail.length-1].z;
d=((point.x-x)*(point.x-x)+(point.y-y)*(point.y-y)+(point.z-z)*(point.z-z));
if(d>9){
sparks[i].trail.push(point);
}
}else{
sparks[i].trail.push(point);
}
if(sparks[i].trail.length>5)sparks[i].trail.splice(0,1);
sparks[i].x+=sparks[i].vx;
sparks[i].y+=sparks[i].vy;
sparks[i].z+=sparks[i].vz;
sparks[i].vx/=1.075;
sparks[i].vy/=1.075;
sparks[i].vz/=1.075;
}else{
sparks.splice(i,1);
}
}
p=Math.atan2(playerX,playerZ);
d=Math.sqrt(playerX*playerX+playerZ*playerZ);
d+=Math.sin(frames/80)/1.25;
t=Math.sin(frames/200)/40;
playerX=Math.sin(p+t)*d;
playerZ=Math.cos(p+t)*d;
yaw=pi+p+t;
}

function rgb(col){

var r = parseInt((.5+Math.sin(col)*.5)*16);
var g = parseInt((.5+Math.cos(col)*.5)*16);
var b = parseInt((.5-Math.sin(col)*.5)*16);
return "#"+r.toString(16)+g.toString(16)+b.toString(16);
}

function draw(){

ctx.clearRect(0,0,cx*2,cy*2);

ctx.fillStyle="#ff8";
for(i=-100;i<100;i+=3){
for(j=-100;j<100;j+=4){
x=i;z=j;y=25;
point=rasterizePoint(x,y,z);
if(point.d!=-1){
size=250/(1+point.d);
d = Math.sqrt(x * x + z * z);
a = 0.75 - Math.pow(d / 100, 6) * 0.75;
if(a>0){
ctx.globalAlpha = a;
ctx.fillRect(point.x-size/2,point.y-size/2,size,size);
}
}
}
}
ctx.globalAlpha=1;
for(i=0;i<seeds.length;++i){
point=rasterizePoint(seeds[i].x,seeds[i].y,seeds[i].z);
if(point.d!=-1){
size=200/(1+point.d);
ctx.fillRect(point.x-size/2,point.y-size/2,size,size);
}
}
point1=new Object();
for(i=0;i<sparks.length;++i){
point=rasterizePoint(sparks[i].x,sparks[i].y,sparks[i].z);
if(point.d!=-1){
size=sparks[i].radius*200/(1+point.d);
if(sparks[i].alpha<0)sparks[i].alpha=0;
if(sparks[i].trail.length){
point1.x=point.x;
point1.y=point.y;
switch(sparks[i].img){
case sparkPics[0]:ctx.strokeStyle="#f84";break;
case sparkPics[1]:ctx.strokeStyle="#84f";break;
case sparkPics[2]:ctx.strokeStyle="#8ff";break;
case sparkPics[3]:ctx.strokeStyle="#fff";break;
case sparkPics[4]:ctx.strokeStyle="#4f8";break;
case sparkPics[5]:ctx.strokeStyle="#f44";break;
case sparkPics[6]:ctx.strokeStyle="#f84";break;
case sparkPics[7]:ctx.strokeStyle="#84f";break;
case sparkPics[8]:ctx.strokeStyle="#fff";break;
case sparkPics[9]:ctx.strokeStyle="#44f";break;
}
for(j=sparks[i].trail.length-1;j>=0;--j){
point2=rasterizePoint(sparks[i].trail[j].x,sparks[i].trail[j].y,sparks[i].trail[j].z);
if(point2.d!=-1){
ctx.globalAlpha=j/sparks[i].trail.length*sparks[i].alpha/2;
ctx.beginPath();
ctx.moveTo(point1.x,point1.y);
ctx.lineWidth=1+sparks[i].radius*10/(sparks[i].trail.length-j)/(1+point2.d);
ctx.lineTo(point2.x,point2.y);
ctx.stroke();
point1.x=point2.x;
point1.y=point2.y;
}
}
}
ctx.globalAlpha=sparks[i].alpha;
ctx.drawImage(sparks[i].img,point.x-size/2,point.y-size/2,size,size);
}
}
}

function frame(){

if(frames>100000){
seedTimer=0;
frames=0;
}
frames++;
draw();
doLogic();
requestAnimationFrame(frame);
}

window.addEventListener("resize",()=>{
canvas.width=canvas.clientWidth;
canvas.height=canvas.clientHeight;
cx=canvas.width/2;
cy=canvas.height/2;
});

initVars();
frame();</script>
<div style="text-align:center;">
</div>
</body>
</html>

 

第三步:將文本擴展名txt改為html,打開網頁即可展示煙花效果。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • #資料庫對應EFCore操作 #1,查某個id在某個集合被包含的數據 例如: 查 Id 在ids里的結合 //實現的sql是實體Id in ids,也就是ids跟Id 兩個集合的交集 var _ainfcfgs = await _ainfcfgServices.GetListAsync(x => i ...
  • 對於sql優化,除了索引之外,執行計劃和統計信息是無法繞開的一個話題,如果sql優化(所有的RDBMS)脫離了統計信息的話就少了一個為什麼的過程,味道就感覺少了一大半。剛接觸Postgresql,粗淺地學習總結一下Postgresql相關的統計信息。 postgresql 進程模型 開始之前,有必要 ...
  • 一、驗證表單 封裝一個函數用於驗證手機號 /** * @param {String}eleId * @param {Object}reg */ function checkInput(eleId,reg) { var ele = document.getElementById(eleId); ele ...
  • 1.屬性選擇器 通過HTML的屬性及屬性值來選擇元素,如<p att= "val" >文本內容</p>,class 即是<p>元素的屬性,val 則是 att 的屬性值 屬性選擇器的書寫格式:元素[屬性名稱 = "屬性值"] {color: red; },等號只是其中一種關係符號 屬性選擇器類型: ...
  • “常說,要認識一個人①,大概瞭解一下背景,然後見面時打招呼講什麼語言規矩範禮②,她回應了,聲音很好聽,你會繼續選擇③用選擇什麼語氣對待?而且又怎麼漂亮,相信自己不會拒絕④的,來預先處理⑤好情緒,好讓彼此能有一個新的開始⑥,給生活一個甜美的謎底吧⑦”--晚安,EmilyChen! (一)CSS簡介 C ...
  • 介紹了 javascript 偽協議, 並說明瞭它的特點及其用途 ...
  • 假設有這麼一條數據 const data = [ { "15日": 0, "27日": 0, "13日": 0, "25日": 0, "11日": 0, "23日": 0, "31日": 0, "21日": 2, "9日": 0, "7日": 0, "5日&q ...
  • 隨著我國經濟的飛速發展,室內地圖定位必將是GIS發展的一大趨勢,應運而生。縱觀當前GIS領域的發展狀況,室外地圖相關的產品比較成熟,像百度、google、arcgis等都是在GIS領域很具有代表性的,但是個性化室內地圖卻微乎其微,深圳市易景空間地圖專業致力於室內地圖平臺的研究,如何製作個性化效果好看... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...