前言
七夕马上就要到了,为了帮助大家高效表白,下面再给大家带来了实用的HTML
浪漫表白代码(附源码)+背景音乐,可用于520,情人节,生日,表白等场景,可直接使用。
特效
内容修改
文字区
<div id="child"><h4>💗文文 and 翔翔💗</h4></div><!--这里写名字❤!!!-->
音乐区
<audio autoplay="autoplay" loop="loop" preload="auto" id="music" controls> <source src="img/訫%20-%20修炼爱情.mp3" type="audio/ogg"> <source src="img/訫%20-%20修炼爱情.mp3" type="audio/mpeg"> </audio>
完整代码
<!doctype html> <html> <head> <meta charset="utf-8"> <title>❤永远开心❤</title> <style> html, body { margin: 0px; width: 100%; height: 100%; overflow: hidden; background: #000; } #canvas { width: 100%; height: 100%; } html, body { height: 100%; padding: 0; margin: 0; background: #000; } canvas { position: absolute; width: 100%; height: 100%; } #child { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } h4 { font-family: "STKaiti"; font-size: 40px; color: #f584b7; position: relative; } </style> </head> <body> <div id="child"><h4>💗文文 and 翔翔💗</h4></div><!--这里写名字❤!!!--> <canvas id="pinkboard"></canvas> <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 }, }; /* * RequestAnimationFrame polyfill by Erik M?ller */ (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> <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> <audio autoplay="autoplay" loop="loop" preload="auto" id="music" controls> <source src="img/訫%20-%20修炼爱情.mp3" type="audio/ogg"> <source src="img/訫%20-%20修炼爱情.mp3" type="audio/mpeg"> </audio> </body> </html>
总结
大家可以用各种HTML编译器,也可直接用记事本开发,改后缀为html即可。
制作不易,希望各位大佬能够多多支持!!
祝大家在情场顺风顺水