第一种:

代码如下:
| <!DOCTYPE html> |
| <html> |
| <head> |
| <meta charset="utf-8" /> |
| <title>💗</title> |
| |
| <style> |
| html, |
| body { |
| height: 100%; |
| padding: 0; |
| margin: 0; |
| background: #000; |
| } |
| canvas { |
| position: absolute; |
| width: 100%; |
| height: 100%; |
| animation: anim 1.5s ease-in-out infinite; |
| -webkit-animation: anim 1.5s ease-in-out infinite; |
| -o-animation: anim 1.5s ease-in-out infinite; |
| -moz-animation: anim 1.5s ease-in-out infinite; |
| } |
| #name { |
| position: absolute; |
| top: 50%; |
| left: 50%; |
| transform: translate(-50%, -50%); |
| margin-top: -20px; |
| font-size: 30px; |
| color: #ea80b0; |
| } |
| @keyframes anim { |
| 0% { |
| transform: scale(0.8); |
| } |
| 25% { |
| transform: scale(0.7); |
| } |
| 50% { |
| transform: scale(1); |
| } |
| 75% { |
| transform: scale(0.7); |
| } |
| 100% { |
| transform: scale(0.8); |
| } |
| } |
| @-webkit-keyframes anim { |
| 0% { |
| -webkit-transform: scale(0.8); |
| } |
| 25% { |
| -webkit-transform: scale(0.7); |
| } |
| 50% { |
| -webkit-transform: scale(1); |
| } |
| 75% { |
| -webkit-transform: scale(0.7); |
| } |
| 100% { |
| -webkit-transform: scale(0.8); |
| } |
| } |
| @-o-keyframes anim { |
| 0% { |
| -o-transform: scale(0.8); |
| } |
| 25% { |
| -o-transform: scale(0.7); |
| } |
| 50% { |
| -o-transform: scale(1); |
| } |
| 75% { |
| -o-transform: scale(0.7); |
| } |
| 100% { |
| -o-transform: scale(0.8); |
| } |
| } |
| @-moz-keyframes anim { |
| 0% { |
| -moz-transform: scale(0.8); |
| } |
| 25% { |
| -moz-transform: scale(0.7); |
| } |
| 50% { |
| -moz-transform: scale(1); |
| } |
| 75% { |
| -moz-transform: scale(0.7); |
| } |
| 100% { |
| -moz-transform: scale(0.8); |
| } |
| } |
| </style> |
| </head> |
| <body> |
| <canvas id="pinkboard"></canvas> |
| <center> |
| <div id="name" style="color: blue;" > |
| xxx<br> |
| I Love You |
| </center> |
| </div> |
| |
| <script> |
| var settings = { |
| particles: { |
| length: 500, |
| duration: 2, |
| velocity: 100, |
| effect: -0.75, |
| size: 30, |
| }, |
| }; |
| (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); |
| }; |
| } |
| })(); |
| 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; |
| })(); |
| 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; |
| })(); |
| var ParticlePool = (function () { |
| var particles, |
| firstActive = 0, |
| firstFree = 0, |
| duration = settings.particles.duration; |
| |
| function ParticlePool(length) { |
| 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); |
| firstFree++; |
| if (firstFree == particles.length) firstFree = 0; |
| if (firstActive == firstFree) firstActive++; |
| if (firstActive == particles.length) firstActive = 0; |
| }; |
| ParticlePool.prototype.update = function (deltaTime) { |
| var i; |
| 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); |
| } |
| while ( |
| particles[firstActive].age >= duration && |
| firstActive != firstFree |
| ) { |
| firstActive++; |
| if (firstActive == particles.length) firstActive = 0; |
| } |
| }; |
| ParticlePool.prototype.draw = function (context, image) { |
| 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; |
| })(); |
| (function (canvas) { |
| var context = canvas.getContext("2d"), |
| particles = new ParticlePool(settings.particles.length), |
| particleRate = |
| settings.particles.length / settings.particles.duration, |
| time; |
| 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 |
| ); |
| } |
| var image = (function () { |
| var canvas = document.createElement("canvas"), |
| context = canvas.getContext("2d"); |
| canvas.width = settings.particles.size; |
| canvas.height = settings.particles.size; |
| 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; |
| } |
| context.beginPath(); |
| var t = -Math.PI; |
| var point = to(t); |
| context.moveTo(point.x, point.y); |
| while (t < Math.PI) { |
| t += 0.01; |
| point = to(t); |
| context.lineTo(point.x, point.y); |
| } |
| context.closePath(); |
| context.fillStyle = "#ea80b0"; |
| context.fill(); |
| var image = new Image(); |
| image.src = canvas.toDataURL(); |
| return image; |
| })(); |
| function render() { |
| requestAnimationFrame(render); |
| var newTime = new Date().getTime() / 1000, |
| deltaTime = newTime - (time || newTime); |
| time = newTime; |
| context.clearRect(0, 0, canvas.width, canvas.height); |
| 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 |
| ); |
| } |
| particles.update(deltaTime); |
| particles.draw(context, image); |
| } |
| function onResize() { |
| canvas.width = canvas.clientWidth; |
| canvas.height = canvas.clientHeight; |
| } |
| window.onresize = onResize; |
| setTimeout(function () { |
| onResize(); |
| render(); |
| }, 10); |
| })(document.getElementById("pinkboard")); |
| |
| </script> |
| </body> |
| </html> |
复制
第二种

代码如下:
| <!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”> |
| <HTML> |
| |
| <HEAD> |
| <TITLE> New Document </TITLE> |
| <META NAME=”Generator” CONTENT=”EditPlus”> |
| <META NAME=”Author” CONTENT=””> |
| <META NAME=”Keywords” CONTENT=””> |
| <META NAME=”Description” CONTENT=””> |
| <style> |
| html, |
| body { |
| |
| height: 100%; |
| padding: 0; |
| margin: 0; |
| background: #000; |
| } |
| |
| canvas { |
| |
| position: absolute; |
| width: 100%; |
| height: 100%; |
| } |
| </style> |
| </HEAD> |
| |
| <BODY> |
| <canvas id="pinkboard"></canvas> |
| <script> |
| var settings = { |
| |
| particles: { |
| |
| length: 500, |
| duration: 2, |
| velocity: 100, |
| effect: -0.75, |
| size: 30, |
| }, |
| }; |
| (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) } } }()); |
| 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; |
| })(); |
| 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; |
| })(); |
| var ParticlePool = (function () { |
| var particles, |
| firstActive = 0, |
| firstFree = 0, |
| duration = settings.particles.duration; |
| function ParticlePool(length) { |
| 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); |
| firstFree++; |
| if (firstFree == particles.length) firstFree = 0; |
| if (firstActive == firstFree) firstActive++; |
| if (firstActive == particles.length) firstActive = 0; |
| }; |
| ParticlePool.prototype.update = function (deltaTime) { |
| var i; |
| 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); |
| } |
| while (particles[firstActive].age >= duration && firstActive != firstFree) { |
| firstActive++; |
| if (firstActive == particles.length) firstActive = 0; |
| } |
| }; |
| ParticlePool.prototype.draw = function (context, image) { |
| 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; |
| })(); |
| (function (canvas) { |
| var context = canvas.getContext("2d"), |
| particles = new ParticlePool(settings.particles.length), |
| particleRate = settings.particles.length / settings.particles.duration, |
| time; |
| 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 |
| ); |
| } |
| var image = (function () { |
| var canvas = document.createElement("canvas"), |
| context = canvas.getContext("2d"); |
| canvas.width = settings.particles.size; |
| canvas.height = settings.particles.size; |
| 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; |
| } |
| context.beginPath(); |
| var t = -Math.PI; |
| var point = to(t); |
| context.moveTo(point.x, point.y); |
| while (t < Math.PI) { |
| t += 0.01; |
| point = to(t); |
| context.lineTo(point.x, point.y); |
| } |
| context.closePath(); |
| context.fillStyle = "#ea80b0"; |
| context.fill(); |
| var image = new Image(); |
| image.src = canvas.toDataURL(); |
| return image; |
| })(); |
| function render() { |
| requestAnimationFrame(render); |
| var newTime = new Date().getTime() / 1000, |
| deltaTime = newTime - (time || newTime); |
| time = newTime; |
| context.clearRect(0, 0, canvas.width, canvas.height); |
| 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); |
| } |
| particles.update(deltaTime); |
| particles.draw(context, image); |
| } |
| function onResize() { |
| canvas.width = canvas.clientWidth; |
| canvas.height = canvas.clientHeight; |
| } |
| window.onresize = onResize; |
| setTimeout(function () { |
| |
| onResize(); |
| render(); |
| }, 10); |
| })(document.getElementById("pinkboard")); |
| </script> |
| </BODY> |
| |
| </HTML> |
复制
第三种

代码如下:
| <!DOCTYPE html> |
| <html lang="en"> |
| |
| <head> |
| <meta charset="UTF-8"> |
| <meta http-equiv="X-UA-Compatible" content="IE=edge"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>爱心跳动效果</title> |
| <style> |
| * { |
| margin: 0; |
| padding: 0; |
| } |
| |
| .loveBox { |
| display: flex; |
| justify-content: center; |
| align-items: center; |
| height: 100vh; |
| background-color: rgb(36, 40, 66); |
| } |
| |
| .loveLine { |
| height: 200px; |
| } |
| |
| .loveLine li { |
| float: left; |
| list-style: none; |
| width: 20px; |
| height: 20px; |
| border-radius: 10px; |
| margin-right: 10px; |
| } |
| |
| .loveLine li:nth-child(1) { |
| background-color: red; |
| animation: jump1 3s infinite; |
| } |
| |
| .loveLine li:nth-child(2) { |
| background-color: rgb(238, 118, 5); |
| animation: jump2 3s 0.2s infinite; |
| } |
| |
| .loveLine li:nth-child(3) { |
| background-color: rgb(106, 10, 233); |
| animation: jump3 3s 0.4s infinite; |
| } |
| |
| .loveLine li:nth-child(4) { |
| background-color: darkmagenta; |
| animation: jump4 3s 0.6s infinite; |
| } |
| |
| .loveLine li:nth-child(5) { |
| background-color: rgb(245, 11, 147); |
| animation: jump5 3s 0.8s infinite; |
| } |
| |
| .loveLine li:nth-child(6) { |
| background-color: rgb(32, 9, 231); |
| animation: jump4 3s 1.0s infinite; |
| } |
| |
| .loveLine li:nth-child(7) { |
| background-color: rgb(36, 170, 81); |
| animation: jump3 3s 1.2s infinite; |
| } |
| |
| .loveLine li:nth-child(8) { |
| background-color: #f62e74; |
| animation: jump2 3s 1.4s infinite; |
| } |
| |
| .loveLine li:nth-child(9) { |
| background-color: red; |
| animation: jump1 3s 1.6s infinite; |
| } |
| |
| @keyframes jump1 { |
| |
| 30%, |
| 50% { |
| height: 60px; |
| transform: translateY(-30px); |
| } |
| |
| 70%, |
| 100% { |
| height: 20px; |
| transform: translateY(0px); |
| } |
| } |
| |
| @keyframes jump2 { |
| |
| 30%, |
| 50% { |
| height: 120px; |
| transform: translateY(-60px); |
| } |
| |
| 70%, |
| 100% { |
| height: 20px; |
| transform: translateY(0px); |
| } |
| } |
| |
| @keyframes jump3 { |
| |
| 30%, |
| 50% { |
| height: 160px; |
| transform: translateY(-75px); |
| } |
| |
| 70%, |
| 100% { |
| height: 20px; |
| transform: translateY(0px); |
| } |
| } |
| |
| @keyframes jump4 { |
| |
| 30%, |
| 50% { |
| height: 180px; |
| transform: translateY(-60px); |
| } |
| |
| 70%, |
| 100% { |
| height: 20px; |
| transform: translateY(0px); |
| } |
| } |
| |
| @keyframes jump5 { |
| |
| 30%, |
| 50% { |
| height: 200px; |
| transform: translateY(-45px); |
| } |
| |
| 70%, |
| 100% { |
| height: 20px; |
| transform: translateY(0px); |
| } |
| } |
| </style> |
| </head> |
| |
| <body> |
| <div class="loveBox"> |
| <ul class="loveLine"> |
| <li></li> |
| <li></li> |
| <li></li> |
| <li></li> |
| <li></li> |
| <li></li> |
| <li></li> |
| <li></li> |
| <li></li> |
| </ul> |
| </div> |
| </body> |
| |
| </html> |
复制