实现电商页面(如双11、圣诞节、春节等大促活动)的落雪特效,主要有三种主流方案,按性能、复杂度、效果排序推荐:
✅ 推荐方案一:Canvas + 粒子系统(高性能、推荐)
适合:大量雪花、高性能要求、移动端兼容好
核心思路:
- 使用
<canvas> 绘制
- 每帧清空画布,重新绘制所有雪花位置
- 雪花为小圆点或自定义图片,带下落、飘动、旋转动画
示例代码(简化版):
<canvas id="snowCanvas"></canvas>
<script>
const canvas = document.getElementById('snowCanvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const snowflakes = [];
const count = 150; // 雪花数量
class Snowflake {
constructor() {
this.x = Math.random() * canvas.width;
this.y = Math.random() * canvas.height;
this.radius = Math.random() * 3 + 1;
this.speed = Math.random() * 2 + 1;
this.wind = Math.random() * 2 - 1;
this.opacity = Math.random() * 0.5 + 0.5;
}
update() {
this.y += this.speed;
this.x += this.wind;
if (this.y > canvas.height) {
this.y = -10;
this.x = Math.random() * canvas.width;
}
if (this.x > canvas.width) this.x = 0;
if (this.x < 0) this.x = canvas.width;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = `rgba(255, 255, 255, ${this.opacity})`;
ctx.fill();
}
}
for (let i = 0; i < count; i++) {
snowflakes.push(new Snowflake());
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
snowflakes.forEach(flake => {
flake.update();
flake.draw();
});
requestAnimationFrame(animate);
}
animate();
window.addEventListener('resize', () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
</script>
优点:
- 性能优秀,可支持数百个雪花
- 可自定义雪花形状(贴图)、大小、速度、风力
- 移动端友好
✅ 推荐方案二:CSS + JS 动态生成 DOM 元素
适合:少量雪花、简单效果、不想用 Canvas
核心思路:
- 用 JS 动态创建
<div> 元素作为雪花
- CSS 动画实现下落和飘动
- 定期清理超出屏幕的雪花,避免内存泄漏
示例代码:
<style>
.snowflake {
position: fixed;
top: -10px;
color: white;
font-size: 1em;
user-select: none;
pointer-events: none;
z-index: 9999;
animation: fall linear infinite;
}
@keyframes fall {
to {
transform: translateY(100vh) rotate(360deg);
}
}
</style>
<script>
function createSnowflake() {
const snow = document.createElement('div');
snow.classList.add('snowflake');
snow.textContent = '❄';
snow.style.left = Math.random() * 100 + 'vw';
snow.style.animationDuration = Math.random() * 3 + 2 + 's';
snow.style.opacity = Math.random() * 0.7 + 0.3;
snow.style.fontSize = Math.random() * 1.5 + 0.5 + 'em';
document.body.appendChild(snow);
// 动画结束后移除
snow.addEventListener('animationend', () => {
snow.remove();
});
}
setInterval(createSnowflake, 100); // 每100ms创建一个
</script>
优点:
- 实现简单,易定制样式
- 可结合 CSS 滤镜、阴影等增强视觉效果
缺点:
- DOM 元素多时性能较差,不建议超过 50~100 个
✅ 推荐方案三:使用现成库(如 snowstorm.js、particles.js)
适合:快速集成、不想手写
<script src="https://cdn.jsdelivr.net/npm/snowstorm@6.1.0/snowstorm.js"></script>
<script>
snowStorm.flakeImage = 'https://example.com/snowflake.png'; // 自定义雪花图片
snowStorm.flakeCount = 100;
</script>
优点:
缺点:
🎯 电商场景优化建议
-
性能优先:
- 移动端减少雪花数量(如 50~80 个)
- 使用
requestAnimationFrame 而非 setInterval
- 避免在低性能设备上启用特效
-
用户体验:
- 提供“关闭特效”按钮(尤其对光敏用户)
- 雪花不要遮挡关键内容(如按钮、价格)
- 背景深色时雪花更明显,浅色背景需调整颜色
-
视觉增强:
- 使用 PNG 雪花贴图(带透明通道)
- 添加轻微模糊、阴影效果
- 结合风力参数让雪花飘动更自然
-
节日主题:
- 春节可改为“花瓣”或“金币”
- 双11可改为“购物车”或“优惠券”图标
📌 归纳选型指南
| 方案 |
性能 |
复杂度 |
自定义性 |
推荐场景 |
| Canvas 粒子 |
中 |
高 |
大型活动、高性能要求 |
| CSS + DOM |
低 |
中 |
简单页面、少量雪花 |
| 第三方库 |
低 |
低 |
快速上线、标准需求 |
取消评论你是访客,请填写下个人信息吧