当前位置:首页 > 行业动态 > 正文

爱心飘落动态图js

使用HTML5 Canvas结合JS实现,通过随机生成爱心坐标与下落轨迹,利用requestAnimationFrame逐帧绘制飘落动画,可添加重力加速度与旋转效果增强真实感

实现原理

通过HTML5 Canvas绘制多个爱心图形,利用JavaScript控制爱心的下落轨迹、速度、旋转等属性,结合requestAnimationFrame实现平滑动画效果。

爱心飘落动态图js  第1张


完整代码示例

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">爱心飘落动画</title>
  <style>
    body {
      margin: 0;
      background: #222;
      overflow: hidden;
    }
    canvas {
      display: block;
    }
  </style>
</head>
<body>
  <canvas id="heartCanvas"></canvas>
  <script>
    // 获取Canvas元素
    const canvas = document.getElementById('heartCanvas');
    const ctx = canvas.getContext('2d');
    // 设置Canvas尺寸
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    // 监听窗口大小变化
    window.addEventListener('resize', () => {
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
    });
    // 定义爱心数量
    const heartCount = 100;
    // 存储所有爱心对象
    const hearts = [];
    // 生成随机数工具函数
    const random = (min, max) => Math.random()  (max min) + min;
    // 初始化爱心数组
    for (let i = 0; i < heartCount; i++) {
      hearts.push(createHeart());
    }
    // 创建单个爱心对象
    function createHeart() {
      return {
        x: random(0, canvas.width), // 初始X坐标
        y: random(-200, -50),       // 初始Y坐标(画布外)
        size: random(8, 15),        // 爱心大小
        speed: random(1, 3),        // 下落速度
        rotate: random(0, Math.PI  2), // 初始旋转角度
        alpha: random(0.5, 1)       // 透明度
      };
    }
    // 绘制单个爱心
    function drawHeart(heart) {
      ctx.save();
      ctx.fillStyle = `rgba(255, 105, 180, ${heart.alpha})`; // 粉色半透明
      ctx.translate(heart.x, heart.y);
      ctx.rotate(heart.rotate);
      ctx.fillStyle = `rgba(255, 105, 180, ${heart.alpha})`;
      drawHeartShape(heart.size);
      ctx.restore();
    }
    // 绘制心形路径
    function drawHeartShape(size) {
      ctx.beginPath();
      ctx.moveTo(0, -size / 2); // 顶部尖点
      ctx.bezierCurveTo(size, -size, size, size / 2, 0, size / 2); // 右半边
      ctx.bezierCurveTo(-size, size / 2, -size, -size, 0, -size / 2); // 左半边
      ctx.closePath();
      ctx.fill();
    }
    // 更新爱心状态
    function updateHearts() {
      hearts.forEach(heart => {
        heart.y += heart.speed; // 下落
        heart.rotate += 0.01;   // 缓慢旋转
        // 超出底部后重置位置
        if (heart.y > canvas.height) {
          heart.y = random(-200, -50);
          heart.x = random(0, canvas.width);
          heart.size = random(8, 15);
          heart.speed = random(1, 3);
          heart.rotate = random(0, Math.PI  2);
        }
      });
    }
    // 渲染动画帧
    function render() {
      ctx.clearRect(0, 0, canvas.width, canvas.height); // 清空画布
      hearts.forEach(drawHeart);                        // 绘制所有爱心
      updateHearts();                                   // 更新状态
      requestAnimationFrame(render);                   // 循环调用
    }
    // 启动动画
    render();
  </script>
</body>
</html>

参数说明表

参数名称 作用 默认值范围 调整建议
heartCount 爱心数量 50-200 数值越大越密集,性能消耗越高
size 单个爱心大小 8-15 增大可突出视觉效果,但过多大爱心可能显乱
speed 下落速度 1-3 数值越大下落越快,可配合风力效果调整
alpha 透明度 5-1 降低透明度可营造柔和感

注意事项

  1. 性能优化:当爱心数量超过200时,低配置设备可能出现卡顿,建议通过requestAnimationFrame替代setInterval保证流畅度。
  2. 移动端适配:需测试触摸设备效果,可适当减少爱心数量(如50-100)。
  3. 颜色自定义:修改ctx.fillStyle中RGBA值即可调整颜色(如红色rgba(255,50,50,0.8))。
  4. 背景兼容:若页面有复杂背景,建议给Canvas添加backgroundColor属性或调整爱心颜色对比度。

相关问题与解答

问题1:如何让爱心呈现不同颜色?

解答:在createHeart函数中为每个爱心随机生成颜色值,

function createHeart() {
  return {
    // ...其他属性
    color: `hsla(${Math.random()  360}, 70%, 50%, ${random(0.5, 1)})` 
  };
}

然后在drawHeart函数中使用heart.color替代固定颜色。

问题2:如何让爱心在鼠标悬停时暂停下落?

解答:监听mouseentermouseleave事件,通过标志位控制动画更新:

let isPaused = false;
canvas.addEventListener('mouseenter', () => isPaused = true);
canvas.addEventListener('mouseleave', () => isPaused = false);
function updateHearts() {
  if (isPaused) return; // 暂停更新
  hearts.forEach(heart => {
    // ...原有逻辑
  });
}
0