你会得到什么
PixelLogoLoader.vue:一个<script setup lang="ts">单文件组件,内置 Logo 的采样点阵(最多 1600 个点)。- 除了 Vue 不需要任何依赖。组件在一个 Canvas 上用 2D 接口绘制。
- Vue 导出需要 Pro。
1. 导出组件
- 打开工坊。
- 上传 Logo:点击选择 PNG、SVG、JPG 或 WebP 文件,也可以拖到页面上,或按 Ctrl+V / ⌘+V 粘贴。透明背景或纯色背景的 Logo 效果最好;如果有部分没采到,可以调节点阵密度和提取阈值。
- 从 9 种效果里选一个,调整粒子大小、形状(方块或圆点)和速度。
- 点击导出代码,切到 Vue 3 组件 标签,点下载文件(或复制代码)。这个格式需要 Pro。
2. 放进项目
把文件保存为 src/components/PixelLogoLoader.vue,然后:
<script setup lang="ts">
import PixelLogoLoader from './components/PixelLogoLoader.vue';
</script>
<template>
<PixelLogoLoader :height="420" />
</template>
组件默认宽度是容器的 100%,高度 420 像素。Logo 会缩放到容器的 72% 以内并居中。外层默认是黑底、16 像素圆角、细边框和阴影,可以在组件文件底部的 .pixel-loader-container 样式里修改。
3. 参数
| 参数 | 类型 | 默认值 | 作用 |
|---|---|---|---|
variant | string | 导出时选的效果 | 播放哪种效果,可选值见下表 |
width | number | string | '100%' | 数字按像素计算 |
height | number | string | 420 | 数字按像素计算 |
autoPlay | boolean | true | 自动循环播放:每轮 duration 秒,之后停 1.2 秒 |
duration | number | 3.2 | 每轮的秒数 |
progress | number | 无 | 0 到 100。传入后动画按这个值显示,不再自动播放 |
colors | string[] | 导出时选的配色 | 粒子颜色;自带颜色的点(原图配色)保留自己的颜色 |
particleSize | number | 导出时的大小 | 基础粒子大小,会按容器尺寸缩放 |
particleShape | 'square' | 'circle' | 导出时的形状 | 方块或圆点 |
speedMultiplier | number | 导出时的速度 | 粒子移向目标位置的速度倍数 |
interactive | boolean | true | 是否响应鼠标:经过时推开粒子,点击触发冲击波 |
修改 variant、colors、particleSize 或 particleShape 时,组件会重新生成粒子。variant 可选值:
| variant 值 | 效果 |
|---|---|
condense | 量子凝聚态 |
mobius-flow | 莫比乌斯拓扑光流 |
vortex | 星系引力坍缩 |
scan | 全息光栅断层扫描 |
diffusion-denoise | 扩散降噪重构 |
flux-wave | 超导磁通涟漪 |
swarm-assembly | 纳米蜂群智能组装 |
gravitational-slingshot | 引力弹弓时间逆流 |
cymatics-resonance | 克拉尼声波共振 |
4. 做成加载页
传入 progress 后,粒子只移动到这个进度对应的位置,加载完成时 Logo 正好成形:
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import PixelLogoLoader from './components/PixelLogoLoader.vue';
const progress = ref(0);
const ready = ref(false);
onMounted(async () => {
// 换成你自己的加载步骤
const steps = [() => fetch('/api/user'), () => fetch('/api/projects')];
for (let i = 0; i < steps.length; i++) {
await steps[i]();
progress.value = ((i + 1) / steps.length) * 100;
}
ready.value = true;
});
</script>
<template>
<PixelLogoLoader v-if="!ready" :progress="progress" :height="360" />
<main v-else>…</main>
</template>
5. Nuxt 与服务端渲染
组件只在 onMounted 里开始绘制,服务端只会渲染一个空容器。如果你的项目在服务端渲染时报错,用 Nuxt 的 <ClientOnly> 包起来即可。
6. 性能与无障碍
- 每个组件只有一个 requestAnimationFrame 循环,在
onBeforeUnmount时停止,并断开 ResizeObserver。 - 每个组件最多 1600 个粒子。在低端手机上尽量不要同时放很多个。
- 组件没有检测系统的“减少动态效果”设置。可以在用户开启这个设置时传入固定的
progress为 100,粒子会直接组成 Logo,不再循环:
<script setup lang="ts">
const reduceMotion =
typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
</script>
<template>
<PixelLogoLoader :progress="reduceMotion ? 100 : undefined" />
</template>