实现一个炫酷的 DOM 转粒子动画

前言

在我网络冲浪的时候,无意之间看到了一位大佬做的粒子效果很是炫酷,不过只做了 Mac 端的示例,我于是就学习做了一个 Web 端的 DOM 转 Canvas 粒子动画效果。代码仓库、说明文档及NPM包都在结尾。

实现思路

实现思路的话十分好理解,一句话就可以说的清。

先用 html2canvas 将 DOM 转成 canvas ,然后将 canvas 转成粒子开始做动画。

全部实现下来核心代码 200 多行,7kb左右吧。不过由于依赖了 html2canvas,打包后还是有 200+ kb 的大小。

开发逻辑

输入

既然是要将 DOM 转为 Canvas 粒子,那么输入自然是 DOM 。这里预设了两种粒子效果,就如开篇的图所示。

获取图像数据

调用方法,传入 DOM 和 动画类型初始化后,直接就是获取图像数据,这些数据就是后面要创建的粒子。

自己传入进来的 DOM 什么样,就能截图显示成什么样?(当然,html2canvas 的小缺陷还是避免不了,比如跨域图片的加载 。)

然后除了图像数据外,还有 DOM 的尺寸也要记录下来,到时候在画布上渲染需要用得到。

开始动画

初始化好后,自然不一定希望立即动画,所以导出了一个 startAnimation 方法,一旦调用就开始动画。

而这个方法,自然有几处逻辑上的需要考虑,比如上一次的动画需要清除,动画的持续时间,动画结束之后又要清除以防内存泄露等等。考虑好后,自然就是逻辑上的开发了。

动画渲染

终于到了关键的一步,而这里却很简单。

几个步骤:

  1. 调用动画方法后,增加一个 Canvas 画布,用于渲染粒子。
  2. requestAnimationFrame 渲染动画。
  3. html2canvas 获取的图像数据,遍历创建粒子,这些粒子的位置随 requestAnimationFrame 改变。

核心逻辑就是这样,不过还有一些小细节要考虑。比如要更新一下传入 DOM 的位置,放置窗口 Resize 或者页面 Scroll 造成的位置影响。或者粒子的动画效果该如何去设置。不过这些都是优化项,主要初步的能渲染就行,粒子的动画效果无非就是改变 x || y 值,做匀速、匀加速、正弦余弦波动,几种组合在一起,整的花里胡哨的。

然后还有就是粒子的数量对浏览器的 FPS 的影响。

使用方法

经过两天的时间,开发了一个 html2particle NPM 包,并写了一个简要的说明文档和用法示例。使用 TS 开发的,编译成 JS 发布上去的,所以使用也无关前端框架,都可以使用。这里只放一个 Vue 版本(包括样式)的示例,用 Vitepress 写的说明文档还有原生和 React 的用法。

vue

vue 复制代码
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import html2particle from 'html2particle'

const item4Ref = ref<HTMLElement>()
let handleItem4Click = () => { }
const isShow4 = ref(true)
function initItem4Event() {
  const { startAnimation } = html2particle(item4Ref.value!, { type: 'ExplodingParticle' })
  handleItem4Click = () => {
    isShow4.value = false
    startAnimation()
  }
}

const item5Ref = ref<HTMLElement>()
let handleItem5Click = () => { }
const isShow5 = ref(true)
function initItem5Event() {
  const { startAnimation } = html2particle(item5Ref.value!, { type: 'SinWaveParticle' })
  handleItem5Click = () => {
    isShow5.value = false
    startAnimation()
  }
}

onMounted(() => {
  initItem4Event()
  initItem5Event()
})
</script>

<template>
  <div class="container">
    <div ref="item4Ref" class="image" @click="handleItem4Click">
      <img v-if="isShow4" src="/1.jpg" alt="">
    </div>

    <div ref="item5Ref" class="image" @click="handleItem5Click">
      <img v-if="isShow5" src="/2.jpg" alt="">
    </div>
  </div>
</template>

<style scoped>
.container {
  align-items: center;
  user-select: none;
  display: flex;
  flex-direction: row;
}

.image {
  width: 300px;
  height: 200px;
  cursor: pointer;
  margin: 0 auto 20px;
  display: flex;
  justify-content: center;
  align-items: center;
}

img {
  object-fit: cover;
  width: 100%;
  height: 100%;
  border-radius: 10px;
  overflow: hidden;
  outline: 2px solid #887cc8;
  outline-offset: 2px;
}
</style>

结尾

总的来说,因为样式炫目,才引起的兴趣研究一下这个。虽然代码量不多,不过还是有点意思。如果可以自定义传入粒子效果,而不是只有这两种,那应该更好用些。

Demo 及文档预览 : html2particle.mmeme.me/guide/demo....

NPM 包地址 : www.npmjs.com/package/htm...

GitHub 仓库地址 : github.com/pinky-pig/h...

相关推荐
崔庆才丨静觅4 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60615 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了5 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅5 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅6 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment6 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅6 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊6 小时前
jwt介绍
前端
爱敲代码的小鱼6 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax