烟花页面
<!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>
跨年倒计时页面
<!doctype html>
<html>
<head>
<meta charset=utf-8" >
<span style="font-size:18px;"> </span>
<span style="font-size:24px;">
<meta http-equiv="refresh" content="3;URL=res.html">
</span>
<title>新年快乐</title><!-- 这是网页标题 -->
<style>
body{
overflow: hidden;
margin: 0;
}
h1{
position: fixed;
top: 30%;
left: 0;
width: 100%;
text-align: center;
transform:translateY(-50%);
font-family: 'Love Ya Like A Sister', cursive;
font-size: 60px;
color: #c70012;
padding: 0 20px;
}
h1 span{
position: fixed;
left: 0;
width: 100%;
text-align: center;
margin-top:30px;
font-size:40px;
}
</style>
</head>
<body>
<h1 id="h1"></h1>
<canvas></canvas> <!--canvas 画布-->
<script>
var canvas = document.querySelector("canvas"),
ctx = canvas.getContext("2d");
var ww,wh;
function onResize(){
ww = canvas.width = window.innerWidth;
wh = canvas.height = window.innerHeight;
}
ctx.strokeStyle = "red";
ctx.shadowBlur = 25;
ctx.shadowColor = "hsla(0, 100%, 60%,0.5)";
var precision = 100;
var hearts = [];
var mouseMoved = false;
function onMove(e){
mouseMoved = true;
if(e.type === "touchmove"){
hearts.push(new Heart(e.touches[0].clientX, e.touches[0].clientY));
hearts.push(new Heart(e.touches[0].clientX, e.touches[0].clientY));
}
else{
hearts.push(new Heart(e.clientX, e.clientY));
hearts.push(new Heart(e.clientX, e.clientY));
}
}
var Heart = function(x,y){
this.x = x || Math.random()*ww;
this.y = y || Math.random()*wh;
this.size = Math.random()*2 + 1;
this.shadowBlur = Math.random() * 10;
this.speedX = (Math.random()+0.2-0.6) * 8;
this.speedY = (Math.random()+0.2-0.6) * 8;
this.speedSize = Math.random()*0.05 + 0.01;
this.opacity = 1;
this.vertices = [];
for (var i = 0; i < precision; i++) {
var step = (i / precision - 0.5) * (Math.PI * 2);
var vector = {
x : (15 * Math.pow(Math.sin(step), 3)),
y : -(13 * Math.cos(step) - 5 * Math.cos(2 * step) - 2 * Math.cos(3 * step) - Math.cos(4 * step))
}
this.vertices.push(vector);
}
}
Heart.prototype.draw = function(){
this.size -= this.speedSize;
this.x += this.speedX;
this.y += this.speedY;
ctx.save();
ctx.translate(-1000,this.y);
ctx.scale(this.size, this.size);
ctx.beginPath();
for (var i = 0; i < precision; i++) {
var vector = this.vertices[i];
ctx.lineTo(vector.x, vector.y);
}
ctx.globalAlpha = this.size;
ctx.shadowBlur = Math.round((3 - this.size) * 10);
ctx.shadowColor = "hsla(0, 100%, 60%,0.5)";
ctx.shadowOffsetX = this.x + 1000;
ctx.globalCompositeOperation = "screen"
ctx.closePath();
ctx.fill()
ctx.restore();
};
function render(a){
requestAnimationFrame(render);
hearts.push(new Heart())
ctx.clearRect(0,0,ww,wh);
for (var i = 0; i < hearts.length; i++) {
hearts[i].draw();
if(hearts[i].size <= 0){
hearts.splice(i,1);
i--;
}
}
}
onResize();
window.addEventListener("mousemove", onMove);
window.addEventListener("touchmove", onMove);
window.addEventListener("resize", onResize);
requestAnimationFrame(render);
window.onload=function starttime(){
time(h1,'2022,1,1'); // 需修改成后面年份春节时间
ptimer = setTimeout(starttime,1000); // 添加计时器
}
function time(obj,futimg){
var nowtime = new Date().getTime(); // 现在时间转换为时间戳
var futruetime = new Date(futimg).getTime(); // 未来时间转换为时间戳
var msec = futruetime-nowtime; // 毫秒 未来时间-现在时间
var time = (msec/1000); // 毫秒/1000
var day = parseInt(time/86400); // 天 24*60*60*1000
var hour = parseInt(time/3600)-24*day; // 小时 60*60 总小时数-过去的小时数=现在的小时数
var minute = parseInt(time%3600/60); // 分 -(day*24) 以60秒为一整份 取余 剩下秒数 秒数/60 就是分钟数
var second = parseInt(time%60); // 以60秒为一整份 取余 剩下秒数
obj.innerHTML="<br>距离2022年还有:<br>"+day+"天"+hour+"小时"+minute+"分"+second+"秒"+"<br><span>愿我所念的人平安喜乐,<br>愿我所想的事顺心如意。<br>May the people I think of be safe and happy, <br>and may the things I think of be all right.</span>" //页面显示的文本,可手动修改年份
return true;
}
</script>
</body>
</html>
在跨年倒计时页面的head标签里面写以下代码:
<meta http-equiv="refresh" content="3;URL=res.html">
可以做到当实现跨年倒计时页面3秒后,自动刷新转向到同一路径下的res.html(烟花)页面。