一、浪漫烟花
多说无益,直接上代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <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" width="825" height="631"></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> </body> </html>
复制
将这段代码复制粘贴到记事本中,将记事本后缀名.txt改为.html,再次打开就可以看到下面这样的效果啦,动手试试吧!
二、浪漫爱心
跟前文操作一样,代码如下:
<!DOCTYPE html> <html> <head> <title></title> <script src="js/jquery.min.js"></script> </head> <style> * { padding: 0; margin: 0; } html, body { height: 100%; padding: 0; margin: 0; background: #000; } .aa { position: fixed; left: 50%; bottom: 10px; color: #ccc; } .container { width: 100%; height: 100%; } canvas { z-index: 99; position: absolute; width: 100%; height: 100%; } </style> <body> <!-- 樱花 --> <div id="jsi-cherry-container" class="container"> <audio autoplay="autopaly"> <source src="renxi.mp3" type="audio/mp3" /> </audio> <img class="img" src="./123.png" alt="" /> <!-- 爱心 --> <canvas id="pinkboard" class="container"> </canvas> </div> </body> </html> <script> /* * Settings */ var settings = { particles: { length: 500, // maximum amount of particles duration: 2, // particle duration in sec velocity: 100, // particle velocity in pixels/sec effect: -0.75, // play with this for a nice effect size: 30, // particle size in pixels }, }; (function () { var b = 0; var c = ["ms", "moz", "webkit", "o"]; for (var a = 0; a < c.length && !window.requestAnimationFrame; ++a) { window.requestAnimationFrame = window[c[a] + "RequestAnimationFrame"]; window.cancelAnimationFrame = window[c[a] + "CancelAnimationFrame"] || window[c[a] + "CancelRequestAnimationFrame"]; } if (!window.requestAnimationFrame) { window.requestAnimationFrame = function (h, e) { var d = new Date().getTime(); var f = Math.max(0, 16 - (d - b)); var g = window.setTimeout(function () { h(d + f); }, f); b = d + f; return g; }; } if (!window.cancelAnimationFrame) { window.cancelAnimationFrame = function (d) { clearTimeout(d); }; } })(); /* *Point class */ var Point = (function () { function Point(x, y) { this.x = typeof x !== "undefined" ? x : 0; this.y = typeof y !== "undefined" ? y : 0; } Point.prototype.clone = function () { return new Point(this.x, this.y); }; Point.prototype.length = function (length) { if (typeof length == "undefined") return Math.sqrt(this.x * this.x + this.y * this.y); this.normalize(); this.x *= length; this.y *= length; return this; }; Point.prototype.normalize = function () { var length = this.length(); this.x /= length; this.y /= length; return this; }; return Point; })(); /* * Particle class */ var Particle = (function () { function Particle() { this.position = new Point(); this.velocity = new Point(); this.acceleration = new Point(); this.age = 0; } Particle.prototype.initialize = function (x, y, dx, dy) { this.position.x = x; this.position.y = y; this.velocity.x = dx; this.velocity.y = dy; this.acceleration.x = dx * settings.particles.effect; this.acceleration.y = dy * settings.particles.effect; this.age = 0; }; Particle.prototype.update = function (deltaTime) { this.position.x += this.velocity.x * deltaTime; this.position.y += this.velocity.y * deltaTime; this.velocity.x += this.acceleration.x * deltaTime; this.velocity.y += this.acceleration.y * deltaTime; this.age += deltaTime; }; Particle.prototype.draw = function (context, image) { function ease(t) { return --t * t * t + 1; } var size = image.width * ease(this.age / settings.particles.duration); context.globalAlpha = 1 - this.age / settings.particles.duration; context.drawImage( image, this.position.x - size / 2, this.position.y - size / 2, size, size ); }; return Particle; })(); /* * ParticlePool class */ var ParticlePool = (function () { var particles, firstActive = 0, firstFree = 0, duration = settings.particles.duration; function ParticlePool(length) { // create and populate particle pool particles = new Array(length); for (var i = 0; i < particles.length; i++) particles[i] = new Particle(); } ParticlePool.prototype.add = function (x, y, dx, dy) { particles[firstFree].initialize(x, y, dx, dy); // handle circular queue firstFree++; if (firstFree == particles.length) firstFree = 0; if (firstActive == firstFree) firstActive++; if (firstActive == particles.length) firstActive = 0; }; ParticlePool.prototype.update = function (deltaTime) { var i; // update active particles if (firstActive < firstFree) { for (i = firstActive; i < firstFree; i++) particles[i].update(deltaTime); } if (firstFree < firstActive) { for (i = firstActive; i < particles.length; i++) particles[i].update(deltaTime); for (i = 0; i < firstFree; i++) particles[i].update(deltaTime); } // remove inactive particles while ( particles[firstActive].age >= duration && firstActive != firstFree ) { firstActive++; if (firstActive == particles.length) firstActive = 0; } }; ParticlePool.prototype.draw = function (context, image) { // draw active particles if (firstActive < firstFree) { for (i = firstActive; i < firstFree; i++) particles[i].draw(context, image); } if (firstFree < firstActive) { for (i = firstActive; i < particles.length; i++) particles[i].draw(context, image); for (i = 0; i < firstFree; i++) particles[i].draw(context, image); } }; return ParticlePool; })(); /* * Putting it all together */ (function (canvas) { var context = canvas.getContext("2d"), particles = new ParticlePool(settings.particles.length), particleRate = settings.particles.length / settings.particles.duration, // particles/sec time; // get point on heart with -PI <= t <= PI function pointOnHeart(t) { return new Point( 160 * Math.pow(Math.sin(t), 3), 130 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25 ); } // creating the particle image using a dummy canvas var image = (function () { var canvas = document.createElement("canvas"), context = canvas.getContext("2d"); canvas.width = settings.particles.size; canvas.height = settings.particles.size; // helper function to create the path function to(t) { var point = pointOnHeart(t); point.x = settings.particles.size / 2 + (point.x * settings.particles.size) / 350; point.y = settings.particles.size / 2 - (point.y * settings.particles.size) / 350; return point; } // create the path context.beginPath(); var t = -Math.PI; var point = to(t); context.moveTo(point.x, point.y); while (t < Math.PI) { t += 0.01; // baby steps! point = to(t); context.lineTo(point.x, point.y); } context.closePath(); // create the fill context.fillStyle = "#ea80b0"; context.fill(); // create the image var image = new Image(); image.src = canvas.toDataURL(); return image; })(); // render that thing! function render() { // next animation frame requestAnimationFrame(render); // update time var newTime = new Date().getTime() / 1000, deltaTime = newTime - (time || newTime); time = newTime; // clear canvas context.clearRect(0, 0, canvas.width, canvas.height); // create new particles var amount = particleRate * deltaTime; for (var i = 0; i < amount; i++) { var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random()); var dir = pos.clone().length(settings.particles.velocity); particles.add( canvas.width / 2 + pos.x, canvas.height / 2 - pos.y, dir.x, -dir.y ); } // update and draw particles particles.update(deltaTime); particles.draw(context, image); } // handle (re-)sizing of the canvas function onResize() { canvas.width = canvas.clientWidth; canvas.height = canvas.clientHeight; } window.onresize = onResize; // delay rendering bootstrap setTimeout(function () { onResize(); render(); }, 10); })(document.getElementById("pinkboard")); </script> <script> var RENDERER = { INIT_CHERRY_BLOSSOM_COUNT: 30, MAX_ADDING_INTERVAL: 10, init: function () { this.setParameters(); this.reconstructMethods(); this.createCherries(); this.render(); if ( navigator.userAgent.match( /(phone|pod|iPhone|iPod|ios|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i ) ) { // var box = document.querySelectorAll(".box")[0]; // console.log(box, "移动端"); // box.style.marginTop = "65%"; } }, setParameters: function () { this.$container = $("#jsi-cherry-container"); this.width = this.$container.width(); this.height = this.$container.height(); this.context = $("<canvas />") .attr({ width: this.width, height: this.height }) .appendTo(this.$container) .get(0) var rate = this.FOCUS_POSITION / (this.z + this.FOCUS_POSITION), x = this.renderer.width / 2 + this.x * rate, y = this.renderer.height / 2 - this.y * rate; return { rate: rate, x: x, y: y }; }, re } } else { this.phi += Math.PI / (axis.y == this.thresholdY ? 200 : 500); this.phi %= Math.PI; } if (this.y <= -this.renderer.height * this.SURFACE_RATE) { this.x += 2; this.y = -this.renderer.height * this.SURFACE_RATE; } else { this.x += this.vx; this.y += this.vy; } return ( this.z > -this.FOCUS_POSITION && this.z < this.FAR_LIMIT && this.x < this.renderer.width * 1.5 ); }, }; $(function () { RENDERER.init(); }); </script>
复制
三、浪漫流星雨
代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>流星雨</title> <script> var context; var arr = new Array(); var starCount = 800; var rains = new Array(); var rainCount = 20; function init() { var stars = document.getElementById("stars"); windowWidth = window.innerWidth; //当前的窗口的高度 stars.width = windowWidth; stars.height = window.innerHeight; context = stars.getContext("2d"); } //创建一个星星对象 var Star = function () { this.x = windowWidth * Math.random();//横坐标 this.y = 5000 * Math.random();//纵坐标 this.text = ".";//文本 this.color = "white";//颜色 this.getColor = function () { var _r = Math.random(); if (_r < 0.5) { this.color = "#333"; } else { this.color = "white"; } } //初始化 this.init = function () { this.getColor(); } //绘制 this.draw = function () { context.fillStyle = this.color; context.fillText(this.text, this.x, this.y); } } //画月亮 function drawMoon() { var moon = new Image(); moon.src = "./images/moon.jpg" context.drawImage(moon, -5, -10); } //页面加载的时候 window.onload = function () { init(); //画星星 for (var i = 0; i < starCount; i++) { var star = new Star(); star.init(); star.draw(); arr.push(star); } //画流星 for (var i = 0; i < rainCount; i++) { var rain = new MeteorRain(); rain.init(); rain.draw(); rains.push(rain); } drawMoon();//绘制月亮 playStars();//绘制闪动的星星 playRains();//绘制流星 } //星星闪起来 function playStars() { for (var n = 0; n < starCount; n++) { arr[n].getColor(); arr[n].draw(); } setTimeout("playStars()", 100); } /*流星雨开始*/ var MeteorRain = function () { this.x = -1; this.y = -1; this.length = -1;//长度 this.angle = 30; //倾斜角度 this.width = -1;//宽度 this.height = -1;//高度 this.speed = 1;//速度 this.offset_x = -1;//横轴移动偏移量 this.offset_y = -1;//纵轴移动偏移量 this.alpha = 1; //透明度 this.color1 = "";//流星的色彩 this.color2 = ""; //流星的色彩 /****************初始化函数********************/ this.init = function () //初始化 { this.getPos(); this.alpha = 1;//透明度 this.getRandomColor(); //最小长度,最大长度 var x = Math.random() * 80 + 150; this.length = Math.ceil(x); // x = Math.random()*10+30; this.angle = 30; //流星倾斜角 x = Math.random() + 0.5; this.speed = Math.ceil(x); //流星的速度 var cos = Math.cos(this.angle * 3.14 / 180); var sin = Math.sin(this.angle * 3.14 / 180); this.width = this.length * cos; //流星所占宽度 this.height = this.length * sin;//流星所占高度 this.offset_x = this.speed * cos; this.offset_y = this.speed * sin; } /**************获取随机颜色函数*****************/ this.getRandomColor = function () { var a = Math.ceil(255 - 240 * Math.random()); //中段颜色 this.color1 = "rgba(" + a + "," + a + "," + a + ",1)"; //结束颜色 this.color2 = "black"; } /***************重新计算流星坐标的函数******************/ this.countPos = function ()// { //往左下移动,x减少,y增加 this.x = this.x - this.offset_x; this.y = this.y + this.offset_y; } /*****************获取随机坐标的函数*****************/ this.getPos = function () // { //横坐标200--1200 this.x = Math.random() * window.innerWidth; //窗口高度 //纵坐标小于600 this.y = Math.random() * window.innerHeight; //窗口宽度 } /****绘制流星***************************/ this.draw = function () //绘制一个流星的函数 { context.save(); context.beginPath(); context.lineWidth = 1; //宽度 context.globalAlpha = this.alpha; //设置透明度 //创建横向渐变颜色,起点坐标至终点坐标 var line = context.createLinearGradient(this.x, this.y, this.x + this.width, this.y - this.height); //分段设置颜色 line.addColorStop(0, "white"); line.addColorStop(0.3, this.color1); line.addColorStop(0.6, this.color2); context.strokeStyle = line; //起点 context.moveTo(this.x, this.y); //终点 context.lineTo(this.x + this.width, this.y - this.height); context.closePath(); context.stroke(); context.restore(); } this.move = function () { //清空流星像素 var x = this.x + this.width - this.offset_x; var y = this.y - this.height; context.clearRect(x - 3, y - 3, this.offset_x + 5, this.offset_y + 5); // context.strokeStyle="red"; // context.strokeRect(x,y-1,this.offset_x+1,this.offset_y+1); //重新计算位置,往左下移动 this.countPos(); //透明度增加 this.alpha -= 0.002; //重绘 this.draw(); } } //绘制流星 function playRains() { for (var n = 0; n < rainCount; n++) { var rain = rains[n]; rain.move();//移动 if (rain.y > window.innerHeight) {//超出界限后重来 context.clearRect(rain.x, rain.y - rain.height, rain.width, rain.height); rains[n] = new MeteorRain(); rains[n].init(); } } setTimeout("playRains()", 2); } /*流星雨结束*/ </script> <style type="text/css"> body { background-color: black; } body, html { width: 100%; height: 100%; overflow: hidden; } </style> </head> <body> <canvas id="stars"></canvas> </body> </html>
复制
效果:
说到这里,本文也结束啦,大家都去试一试吧!
参考文档:3个烟花代码,我已上传,也可复制代码_论恒的博客-CSDN博客_yanhua代码
HTML实现流星雨_呆萌的代Ma的博客-CSDN博客_html流星雨代码
html爱心表白代码(最全)_皮小孩ls的博客-CSDN博客_爱心代码html