前言
最近在我司的工作中,摸鱼的时间愈发稀少。刚入职时,只需写几行代码,借助前辈们留下的“恩惠”,就能秒杀任务。而最近两周,开始参与更多的技术评审和完整的新需求,工作量陡然上升。同时,由于自己gap了一阵子没深度参与需求开发,缺乏规划,慢慢地“班味”又有些上来了。
所以在这里对平时对工作内容中涉及的一些技术方案做一些回顾,包括上一期的UI组件搭建之后也会同步。
使用 Canvas Confetti 实现炫酷的撒花效果
掘金最近有年度人气创作者榜单投票的活动,投票成功会有这么一个动画效果
刚好在我司也刚做了一个类似到需求,所以今天我们来讲一下使用Canvas Confetti 实现类似这样的撒花效果
Canvas Confetti 简介
是什么?
Canvas Confetti 是一个轻量级的 JavaScript 库,用于在网页中实现动态、炫酷的撒花动画效果。其基于 HTML5 Canvas API,提供了高性能和极其灵活的定制能力。
有什么特点?
- 轻量高效:仅依赖 Canvas,库的体积非常小,性能表现优异。
- 高度可定制:支持多种粒子样式、动画方向、颜色和数量。
- 即插即用:只需几行代码即可实现基础撒花效果。
- 响应式兼容:在 PC 和移动端都表现流畅。
用户故事
公司原本用了 vue-confetti-explosion这个经过Vue3封装的组件库,为了实现更丰富的效果以及更高的灵活性,于是采用了Canvas Confetti
官方资源
- GitHub 项目地址:Canvas Confetti
- 在线示例网站:Canvas Confetti Demo
如何使用 Canvas Confetti 实现撒花效果
接下来,我们将通过一个完整的案例,从零开始实现撒花动画。包括从安装到定制效果,一步步拆解。
1. 安装库
如果项目使用的是现代化的构建工具(如 Vite、Webpack),可以通过 npm 安装 Canvas Confetti:
npm install canvas-confetti
如果直接在 HTML 中引入,也可以通过 CDN 使用:
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.6.0/dist/confetti.browser.min.js"></script>
2. 基础撒花效果
以下是一个简单的撒花动画示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas Confetti 示例</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f3f4f6;
}
button {
padding: 12px 24px;
font-size: 16px;
cursor: pointer;
border: none;
border-radius: 4px;
background-color: #4caf50;
color: white;
}
</style>
</head>
<body>
<button id="celebrateButton">撒花庆祝!</button>
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.6.0/dist/confetti.browser.min.js"></script>
<script>
const button = document.getElementById('celebrateButton');
button.addEventListener('click', () => {
confetti({
particleCount: 100,
spread: 70, // 撒花的范围角度
origin: { x: 0.5, y: 0.5 } // 动画起点(默认屏幕中心)
});
});
</script>
</body>
</html>
效果说明
- 点击按钮后,页面会从中心位置撒出 100 个粒子。
spread属性控制粒子散开的角度范围,值越大效果越“爆炸”。
3. 自定义撒花样式
Canvas Confetti 提供了丰富的选项,我们可以通过定制颜色、方向、粒子形状等,创建更具个性化的撒花效果。
示例代码:
<script>
button.addEventListener('click', () => {
confetti({
particleCount: 200,
angle: 90, // 撒花方向,90 表示垂直向上
spread: 120, // 粒子扩散角度
origin: { x: 0.5, y: 0.9 }, // 动画起点(屏幕底部中心)
colors: ['#bb0000', '#ffffff'], // 自定义粒子颜色
scalar: 1.2 // 粒子大小比例
});
});
</script>
关键配置项
particleCount:粒子数量。angle:撒花的方向角度。colors:粒子的颜色列表。scalar:粒子的缩放大小。
4. 连续撒花效果
如果需要在短时间内多次触发撒花动画,可以使用 setInterval 模拟:
<script>
button.addEventListener('click', () => {
const duration = 3 * 1000; // 撒花持续时间(毫秒)
const end = Date.now() + duration;
(function frame() {
confetti({
particleCount: 5,
startVelocity: 30,
spread: 360,
origin: {
x: Math.random(),
y: Math.random() - 0.2
}
});
if (Date.now() < end) {
requestAnimationFrame(frame);
}
})();
});
</script>
效果说明
- 每次生成 5 个粒子,并从随机位置撒花。
- 动画持续 3 秒,直到
end时间结束。
5. 集成到 Vue 项目中
上面其实都是最基本的在h5和js中的使用,也用来过滤一部分读者,下面涉及在 Vue 项目中用Composable的思想将 Canvas Confetti 封装成一个全局的配置和方法,方便在多个组件中调用:
创建 confetti-animation.ts 配置文件:
import confetti from 'canvas-confetti';
class ConfettiAnimation {
private interval: ReturnType<typeof setInterval> | null = null
private animationEnd: number
private duration: number
private configs: ConfettiConfig[]
private animationType: 'interval' | 'frame'
constructor(options: ConfettiOptions) {
this.duration = options.duration || 8 * 1000
this.animationEnd = Date.now() + this.duration
this.configs = options.configs.map(config => ({
colors: config.colors,
startVelocity: config.startVelocity || 50,
spread: config.spread || 100,
particleCount: config.particleCount || 45,
scalar: config.scalar || 1.5,
gravity: config.gravity || 0.5,
ticks: config.ticks || 200,
zIndex: 2001,
...config,
}))
this.animationType = options.animationType || 'interval'
}
start() {
if (this.animationType === 'frame') {
this.startFrameAnimation()
} else {
this.startIntervalAnimation()
}
}
.....
}
配置文件的核心就是传入你想要配置的options来自定义动画的效果,以及定时器和帧动画两种渲染方式
因为撒花庆祝要配置每一个confetti的位置等属性,所以要逐个配置
this.configs.forEach(config => {
confetti({
...config,
colors: [...config.colors!],
particleCount: config.particleCount,
origin: { ...config.origin },
})
})
Composable文件配置
export const useConfettiAnimation = ({ autostart, configs, duration, animationType }: UseConfettiAnimationArgs) => {
const confettiAnimation = createConfettiAnimation({ configs, duration, animationType })
const start = () => confettiAnimation.start()
const stop = () => confettiAnimation.stop()
onMounted(() => {
if (autostart) {
start()
}
})
onBeforeUnmount(() => {
if (autostart) {
stop()
}
})
return { start, stop }
暴露出方法在页面组件中调用,结合具体的业务场景,一般都是支付和特定活动最后完成的反馈页的dialog中显示。
在 Vue 组件中使用:
<template>
<div>
<p >撒花庆祝反馈页面</p>
</div>
</template>
<script lang="ts" setup>
import { ConfettiConfig } from 'utils/confetti-animation'
import { useConfettiAnimation } from '@/composables/confetti-animation'
const configs: ConfettiConfig[] = [
{
origin: { x: 0 },
colors: ['',''],
angle: 60,
particleCount: 2,
spread: 55,
},
{
origin: { x: 1 },
colors: ['',''],
angle: 120,
particleCount: 2,
spread: 55,
},
]
const { stop } = useConfettiAnimation({ autostart: true, configs, animationType: 'frame' })
</script>
<style>
div {
padding: 8px 16px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
</style>
示例预览
总结
通过 Canvas Confetti,我们可以轻松地在项目中添加炫酷的撒花动画效果。无论是表单提交成功后的提示,还是特殊节日的庆祝场景。之后对于工作流,自动化工具,我可能会做一些个人的分享,如果各位有更好的玩法或想法,欢迎在评论区交流分享!
完整源代码较长,可关注后联系作者获取(无套路,直接给)
微信公众号:冻柠葡萄呗