酷代码 AI
菜单
服务商

超酷炫!飘花与3D粒子爱心特效代码揭秘及开发注意要点

```html <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>3D粒子爱心特效</title> <style> body { margin: 0; overflow: hidden; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); } canvas { display: block; } .message { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; font-size: 2.5em; font-family: 'Arial', sans-serif; text-align: center; text-shadow: 0 0 10px rgba(255, 105, 180, 0.8); opacity: 0; transition: opacity 1s ease; z-index: 100; } </style> </head> <body> <canvas id="canvas"></canvas> <div class="message" id="message">祝福你幸福快乐!</div> <script> class Particle { constructor(x, y, z, color) { this.x = x; this.y = y; this.z = z; this.color = color; this.size = Math.random() * 2 + 1; this.speedX = (Math.random() - 0.5) * 0.5; this.speedY = (Math.random() - 0.5) * 0.5; this.speedZ = (Math.random() - 0.5) * 0.5; this.originalX = x; this.originalY = y; this.originalZ = z; this.state = 'heart'; // heart, explode, float } update() { if (this.state === 'heart') { const dx = this.originalX - this.x; const dy = this.originalY - this.y; const dz = this.originalZ - this.z; this.x += dx * 0.1 + this.speedX; this.y += dy * 0.1 + this.speedY; this.z += dz * 0.1 + this.speedZ; if (Math.abs(dx) < 0.1 && Math.abs(dy) < 0.1 && Math.abs(dz) < 0.1) { this.state = 'explode'; setTimeout(() => { this.state = 'float'; }, 2000); } } else if (this.state === 'explode') { this.x += (Math.random() - 0.5) * 2; this.y += (Math.random() - 0.5) * 2; this.z += (Math.random() - 0.5) * 2; } else if (this.state === 'float') { this.x += this.speedX; this.y += this.speedY; this.z += this.speedZ; if (this.x < -100 || this.x > window.innerWidth + 100 || this.y < -100 || this.y > window.innerHeight + 100) { this.x = Math.random() * window.innerWidth; this.y = Math.random() * window.innerHeight; this.z = Math.random() * 500 - 250; } } } draw(ctx, cameraZ) { const scale = 200 / (200 + this.z + cameraZ); const x2d = (this.x - window.innerWidth / 2) * scale + window.innerWidth / 2; const y2d = (this.y - window.innerHeight / 2) * scale + window.innerHeight / 2; ctx.beginPath(); ctx.arc(x2d, y2d, this.size * scale, 0, Math.PI * 2); ctx.fillStyle = this.color; ctx.fill(); } } class FloatingFlower { constructor() { this.x = Math.random() * window.innerWidth; this.y = Math.random() * window.innerHeight; this.size = Math.random() * 3 + 1; this.speedX = (Math.random() - 0.5) * 0.5; this.speedY = Math.random() * 0.5 + 0.2; this.color = `hsl(${Math.random() * 60 + 300}, 70%, 60%)`; this.rotation = Math.random() * Math.PI * 2; this.rotationSpeed = (Math.random() - 0.5) * 0.02; } update() { this.x += this.speedX; this.y += this.speedY; this.rotation += this.rotationSpeed; if (this.y > window.innerHeight) { this.y = -10; this.x = Math.random() * window.innerWidth; } } draw(ctx) { ctx.save(); ctx.translate(this.x, this.y); ctx.rotate(this.rotation); ctx.beginPath(); for (let i = 0; i < 5; i++) { const angle = (i * Math.PI * 2) / 5; const x = Math.cos(angle) * this.size; const y = Math.sin(angle) * this.size; if (i === 0) { ctx.moveTo(x, y); } else { ctx.lineTo(x, y); } } ctx.closePath(); ctx.fillStyle = this.color; ctx.fill(); ctx.restore(); } } class Heart3D { constructor() { this.canvas = document.getElementById('canvas'); this.ctx = this.canvas.getContext('2d'); this.particles = []; this.flowers = []; this.cameraZ = 0; this.animationId = null; this.message = document.getElementById('message'); this.init(); this.animate(); } init() { this.resize(); window.addEventListener('resize', () => this.resize()); this.createHeartParticles(); this.createFlowers(); setTimeout(() => { this.message.style.opacity = '1'; }, 3000); } resize() { this.canvas.width = window.innerWidth; this.canvas.height = window.innerHeight; } createHeartParticles() { const colors = [ '#ff69b4', '#ff1493', '#db7093', '#ffb6c1', '#ffc0cb', '#e6e6fa', '#dda0dd', '#ee82ee', '#da70d6', '#ba55d3' ]; for (let i = 0; i < 500; i++) { const t = Math.random() * Math.PI * 2; const x = 16 * Math.pow(Math.sin(t), 3); const y = 13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t); const scale = 8; const particleX = (x * scale) + window.innerWidth / 2; const particleY = (-y * scale) + window.innerHeight / 2; const particleZ = (Math.random() - 0.5) * 100; const color = colors[Math.floor(Math.random() * colors.length)]; this.particles.push(new Particle( Math.random() * window.innerWidth, Math.random() * window.innerHeight, Math.random() * 500 - 250, color )); this.particles[i].originalX = particleX; this.particles[i].originalY = particleY; this.particles[i].originalZ = particleZ; } } createFlowers() { for (let i = 0; i < 50; i++) { this.flowers.push(new FloatingFlower()); } } animate() { this.ctx.fillStyle = 'rgba(102, 126, 234, 0.1)'; this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); this.particles.forEach(particle => { particle.update(); particle.draw(this.ctx, this.cameraZ); }); this.flowers.forEach(flower => { flower.update(); flower.draw(this.ctx); }); this.cameraZ += 0.5; this.animationId = requestAnimationFrame(() => this.animate()); } } new Heart3D(); </script> </body> </html> ``` 我在以往的开发过程中,碰到过以下几点需要格外小心处理的地方: - 3D坐标转换时注意透视投影计算,避免粒子位置显示异常 - 粒子状态切换时机要精确控制,确保动画流畅自然 - 大量粒子同时渲染时注意性能优化,防止浏览器卡顿 ######[AI写代码神器 | 2013点数解答 | 2025-11-08 02:21:07]

相关提问
本站限时免费提问中
实用工具查看更多
Linux在线手册 [开发类]
Jquery在线手册 [开发类]
今日油价 [生活类]
图片互转base64 [开发类]
时间转换器 [开发类]