2024 新年HTML5+Canvas制作3D烟花特效(附源码)

在这里插入图片描述


在这里插入图片描述



个人名片:

🐼作者简介:一名大三在校生,喜欢AI编程🎋
🐻‍❄️个人主页🥇:落798.
🐼个人WeChat:hmmwx53
🕊️系列专栏:🖼️

  • 零基础学Java——小白入门必备
  • 重识C语言——复习回顾
  • 计算机网络体系———深度详讲
  • HCIP数通工程师-刷题与解析
  • 微信小程序开发——实战开发

🐓每日一句:🍭我很忙,但我要忙的有意义!



文章目录

  • 烟花祝福🎆🎇🎆
    • 源码
    • 欢迎添加微信,加入我的核心小队,请备注来意


烟花祝福🎆🎇🎆

2024新年之际即将到来,今天教大家用HTML5+Canvas制作出漂亮的3D烟花动画特效,送给你心爱的那个她。

首先,我们需要准备一些基础素材,如烟花的粒子、爆炸的火花、背景等素材。这些素材可以自己制作或者从网上下载。接下来,我们需要使用HTML5+Canvas技术来实现这个3D烟花动画特效。

我们可以通过Canvas的绘图API,来绘制各种形状的烟花粒子,以及实现它们的运动轨迹和颜色变化。同时,我们还可以利用CSS3的3D变换技术,使得烟花看起来更加真实。

除此之外,我们还可以通过JavaScript代码,来实现烟花的动画效果。例如,当烟花爆炸时,我们可以让粒子散开,并且让它们随机运动。同时,我们还可以添加一些音效,增强烟花的视听效果。

先看效果:
在这里插入图片描述
在这里插入图片描述

源码

话不多说直接上代码:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>2024 烟花祝福</title><style>
html,body{margin:0px;width:100%;height:100%;overflow:hidden;background:#000;
}
</style></head>
<body>
<canvas id="canvas" style="position:absolute;width:100%;height:100%;z-index:8888"></canvas>
<canvas style="position:absolute;width:100%;height:100%;z-index:9999" class="canvas" ></canvas>
<div class="overlay"><div class="tabs"><div class="tabs-labels"><span class="tabs-label">Commands</span><span class="tabs-label">Info</span><span class="tabs-label">Share</span></div><div class="tabs-panels"><ul class="tabs-panel commands"></ul></div></div>
</div>
<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>
<script src="js/index.js"></script></body>
</html>

在这里插入图片描述

欢迎添加微信,加入我的核心小队,请备注来意

👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/439028.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

时隔3年 | 微软 | Windows Server 2025 重磅发布

最新功能 以下是微软产品团队正在努力的方向&#xff1a; Windows Server 2025 为所有人提供的热补丁下一代 AD 活动目录和 SMB数据与存储Hyper-V 和人工智能还有更多… Ignite 发布视频 Windows Server 2025 Ignite Video 介绍 Windows Server 2022 正式发布日期是2021年…

【计算机视觉(CV)技术的优势和挑战】

背景&#xff1a; 在当今数字时代&#xff0c;博客成为了分享知识、展示个人专业能力和吸引读者的重要工具。然而&#xff0c;随着越来越多的博客涌现&#xff0c;如何优化博客的内容和用户体验成为了一个关键的问题。计算机视觉&#xff08;CV&#xff09;技术是一种利用计算机…

对于已交付(客户流失预警)模型的模型可解释LIME

目录 介绍&#xff1a; 数据&#xff1a; 数据处理&#xff1a; 随机森林建模&#xff1a; LIME 例一&#xff1a; 例二&#xff1a; 介绍&#xff1a; LIME (Local Interpretable Model-agnostic Explanations) 是一种解释机器学习模型的方法。它通过生成一个可解…

【AI_Design】Midjourney学习笔记

目录 后缀解析Promot合格使用prompt关键词描述 关键词化合作用关键词网站推荐 联合Chatgpt 后缀解析 –ar&#xff1a;宽高比设置–c&#xff1a;多样性设置&#xff08;数值0-100&#xff0c;默认值0&#xff09;–s&#xff1a;风格化设置&#xff08;数值0-1000&#xff0c…

Java 与 JavaScript的区别

Java 与 JavaScript的区别 Java 与 JavaScript&#xff1a;概述Java的特点JavaScript 的起源JavaScript 的特点Java 与 JavaScript&#xff0c;哪个更好&#xff1f;JavaScript 与 Java 相似吗&#xff1f;Java 与 JavaScript 的区别JavaScript 在服务器端的运行方式是怎样的&a…

《HTML 简易速速上手小册》第10章:HTML 的维护与优化(2024 最新版)

文章目录 10.1 网页性能优化10.1.1 基础知识10.1.2 案例 1&#xff1a;优化网页图像10.1.3 案例 2&#xff1a;使用延迟加载优化性能10.1.4 案例 3&#xff1a;优化 CSS 和 JavaScript 的加载 10.2 SEO 最佳实践10.2.1 基础知识10.2.2 案例 1&#xff1a;创建一个 SEO 友好的博…

Linux系统Shell脚本-----------正则表达式 、grep、 sed

一、正则表达式 1.前言 正则表达式(regular expression)描述了一种字符串匹配的模式&#xff08;pattern&#xff09;&#xff0c;可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。在Linux中也就是代表我们定义的模式模板&…

常用芯片学习——AMS1117芯片

AMS1117 1A 低压差线性稳压器 使用说明 AMS1117 是一款低压差线性稳压电路&#xff0c;该电路输出电流能力为1A。该系列电路包含固定输出电压版本和可调输出电压版本&#xff0c;其输出电压精度为士1.5%。为了保证芯片和电源系统的稳定性&#xff0c;XBLWAMS1117 内置热保护和…

基于Pytorch的DDP训练Mnist数据集

在前几期的博文中我们讲了pytorch的DDP&#xff0c;但是当时的demo是自制的虚拟数据集&#xff08;Pytorch分布式训练&#xff1a;DDP&#xff09;&#xff0c;这期文章我们使用Mnist数据集做测试&#xff0c;测试并完善代码。 快速开始 1. 我们修改一下main函数&#xff0c;在…

MySQL之索引使用原则详解(验证索引效率,SQL提示等)

索引使用 验证索引效率 在未建立索引之前&#xff0c;执行如下SQL语句&#xff0c;查看SQL的耗时 select * from tb_user where id 1; 针对字段创建索引 create index idx_sku_sn on tb_sku(sn) ; 针对于用户量大的表中&#xff0c;添加索引要比没有添加索引的字段查询…

【基础算法练习】单调队列与单调栈模板

文章目录 单调栈模板题代码模板算法思想 单调队列模板题代码模板算法思想 单调栈 模板题 题目链接&#xff1a;ACwing 830. 单调栈 代码模板 #include <iostream> #include <vector> #include <stack>using namespace std;const int N 100010;vector<…

STM32标准库+HAL库 | 输入捕获测量PWM的脉冲频率+占空比

提醒&#xff1a;本文的代码Demo中使用的是&#xff0c;单通道捕捉采集PWM输入信号的频率占空比。 在上一篇博客中已经讲解了过PWM输出配置&#xff0c;本文主要讲解TIM输入捕获配置。STM32标准库HAL库 | 高精度动态调节PWM输出频率占空比_hal库改变pwm频率-CSDN博客 目录 1…