CSS文本粒子动画特效之爱心粒子文字特效-Canvas

1. 效果图

2.完整代码

css 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    body,
    html {
      margin: 0;
      padding: 0;
      width: 100%;
      height: 100%;
      overflow: hidden;
    }

    canvas {
      display: block;
    }
  </style>
  <title>文本粒子动画</title>
</head>

<body>
  <canvas id="textCanvas"></canvas>
  <script>
    const canvas = document.getElementById('textCanvas');
    const ctx = canvas.getContext('2d');
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    const particles = [];
    const fontSize = 100;
    const text = '果粒橙汁儿up好腻害'; // 这里更改粒子文案

    ctx.font = `${fontSize}px Arial`;
    ctx.fillStyle = 'black';
    ctx.textAlign = 'center';
    ctx.fillText(text, canvas.width / 2, canvas.height / 2);

    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

    class Particle {
      constructor(x, y) {
        this.type = 'default'; // 定义粒子类型 分'image'和'default'
        this.x = x;
        this.y = y;
        if (this.type === 'image') {
          this.size = 10; // 调整粒子大小
        } else {
          this.size = 2; // 调整粒子大小
        }
        this.baseX = this.x;
        this.baseY = this.y;
        this.density = (Math.random() * 30) + 1;
        this.image = new Image();
        this.image.src = './heart.jpeg'; // 使用自定义的图像 路径写自己存放图片的途径和图片名字
      }

      draw() {
        if (this.type === 'image') {
          ctx.drawImage(this.image, this.x - this.size / 2, this.y - this.size / 2, this.size, this.size);
        } else {
          // 绘制其他类型的粒子
          ctx.fillStyle = 'black'; // 这里更改粒子颜色
          // ctx.fillStyle = `rgba(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255}`; // 随机彩色粒子
          ctx.beginPath();
          ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
          ctx.closePath();
          ctx.fill();
        }
      }


      update() {
        let dx = mouse.x - this.x;
        let dy = mouse.y - this.y;
        let distance = Math.sqrt(dx * dx + dy * dy);
        let forceDirectionX = dx / distance;
        let forceDirectionY = dy / distance;
        let maxDistance = mouse.radius;
        let force = (maxDistance - distance) / maxDistance;
        let directionX = forceDirectionX * force * this.density;
        let directionY = forceDirectionY * force * this.density;

        if (distance < mouse.radius) {
          this.x -= directionX;
          this.y -= directionY;
        } else {
          if (this.x !== this.baseX) {
            let dx = this.x - this.baseX;
            this.x -= dx / 5;
          }
          if (this.y !== this.baseY) {
            let dy = this.y - this.baseY;
            this.y -= dy / 5;
          }
        }
      }
    }

    let mouse = {
      x: null,
      y: null,
      radius: 150
    };

    window.addEventListener('mousemove', function (event) {
      mouse.x = event.x;
      mouse.y = event.y;
    });

    function init() {
      for (let y = 0, y2 = imageData.height; y < y2; y += 4) {
        for (let x = 0, x2 = imageData.width; x < x2; x += 4) {
          if (imageData.data[(y * 4 * imageData.width) + (x * 4) + 3] > 128) {
            let positionX = x;
            let positionY = y;
            particles.push(new Particle(positionX, positionY));
          }
        }
      }
    }

    function animate() {
      requestAnimationFrame(animate);
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      for (let i = 0; i < particles.length; i++) {
        particles[i].draw();
        particles[i].update();
      }
    }

    init();
    animate();
  </script>
</body>

</html>

代码出来的效果是黑色的,如果想要示例图那种爱心粒子,可以将type改成image,并且改变图片路径this.image.src,如果想要改变文案则改变text变量,如果要改变粒子颜色则改变ctx.fillStyle即可~

本案例使用的图片素材放在文章里啦,自取

相关推荐
天若有情6731 天前
XiangJsonCraft v1.2.0重大更新解读:本地配置优先+全量容错,JSON解耦开发体验再升级
前端·javascript·npm·json·xiangjsoncraft
2501_944525541 天前
Flutter for OpenHarmony 个人理财管理App实战 - 预算详情页面
android·开发语言·前端·javascript·flutter·ecmascript
打小就很皮...1 天前
《在 React/Vue 项目中引入 Supademo 实现交互式新手指引》
前端·supademo·新手指引
C澒1 天前
系统初始化成功率下降排查实践
前端·安全·运维开发
C澒1 天前
面单打印服务的监控检查事项
前端·后端·安全·运维开发·交通物流
pas1361 天前
39-mini-vue 实现解析 text 功能
前端·javascript·vue.js
qq_532453531 天前
使用 GaussianSplats3D 在 Vue 3 中构建交互式 3D 高斯点云查看器
前端·vue.js·3d
Swift社区1 天前
Flutter 路由系统,对比 RN / Web / iOS 有什么本质不同?
前端·flutter·ios
雾眠气泡水@1 天前
前端:解决同一张图片由于页面大小不统一导致图片模糊
前端
开发者小天1 天前
python中计算平均值
开发语言·前端·python