哈喽,各位小伙伴👋!马上就要迎来 2026 年跨年啦,小熊必须用代码给大家整一个有排面的跨年特效!今天给大家带来的是基于HTML+CSS+JAVASCRIPT开发的 3D 粒子跨年盛典页面,包含倒计时粒子动画、物理烟花效果、3D 分层蛋糕、动态祝福语气泡等炫酷功能,源码获取在文末!!
🎇 效果预览
2026年跨年倒计时代码祝福!
- 倒计时动画:5→4→3→2→1→2026,全程 3D 粒子数字呈现,缓动动画丝滑过渡
- 3D 蛋糕特效:三层彩色粒子蛋糕 + 动态闪烁蜡烛,无冗余文字干扰,视觉更纯粹
- 物理烟花效果:随机生成彩色烟花,模拟重力 + 阻力物理运动,淡出效果更真实
- 祝福语气泡:100 句新年祝福语随机生成,金色渐变气泡向上漂浮,氛围感拉满
- 交互体验:支持鼠标 / 手指拖动旋转视角、滚轮缩放,适配 PC + 移动端
🛠 技术栈
- 核心:HTML5 + CSS3 + 原生 JavaScript
- 3D 引擎:Three.js r128(WebGL 渲染,CDN 引入无需本地依赖)
- 动画:CSS3 keyframes + requestAnimationFrame 帧动画
- 适配:响应式布局,适配移动端 / PC 端不同屏幕尺寸
🚀 实现思路(核心要点)
Three.js 核心场景初始化
// 场景初始化
initScene() {
this.scene = new THREE.Scene();
this.scene.background = new THREE.Color(0x0a0a2a); // 深蓝星空背景
this.scene.fog = new THREE.Fog(0x0a0a2a, 10, 100); // 雾化增强3D感
}
// 相机+渲染器初始化
initCamera() {
this.camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 2000);
this.updateCameraPosition(); // 绑定旋转/缩放逻辑
}
initRenderer() {
this.renderer = new THREE.WebGLRenderer({
canvas: canvas,
antialias: true, // 抗锯齿
alpha: true
});
this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); // 高清屏适配
}
1. 倒计时粒子动画
基于 8x8 点阵定义数字轮廓,每个数字点位生成多粒子提升密度,通过缓动算法(1 - Math.pow (1 - progress, 3))实现粒子从随机位置向数字形状平滑过渡,倒计时结束自动触发烟花和蛋糕效果。
// 粒子动画到指定数字
animateToNumber(number) {
return new Promise(resolve => {
const positions = this.particles.geometry.attributes.position.array;
const numberPoints = this.getNumberPoints(number);
// 为每个粒子分配目标位置
for (let i = 0; i < positions.length / 3; i++) {
const pointIndex = i % numberPoints.length;
const point = numberPoints[pointIndex];
this.targetPositions[i * 3] = point.x;
this.targetPositions[i * 3 + 1] = point.y;
this.targetPositions[i * 3 + 2] = 0;
}
// 缓动动画(1 - Math.pow(1 - progress, 3) 实现缓出效果)
const duration = 1500;
const startTime = Date.now();
const animate = () => {
const elapsed = Date.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
const easeProgress = 1 - Math.pow(1 - progress, 3); // 缓出算法
// 更新粒子位置
for (let i = 0; i < positions.length; i += 3) {
positions[i] = this.originalPositions[i] + (this.targetPositions[i] - this.originalPositions[i]) * easeProgress;
positions[i + 1] = this.originalPositions[i + 1] + (this.targetPositions[i + 1] - this.originalPositions[i + 1]) * easeProgress;
positions[i + 2] = this.originalPositions[i + 2] + (this.targetPositions[i + 2] - this.originalPositions[i + 2]) * easeProgress;
}
this.particles.geometry.attributes.position.needsUpdate = true;
if (progress < 1) {
requestAnimationFrame(animate);
} else {
this.originalPositions = positions.slice();
resolve();
}
};
animate();
});
}
2. 3D 分层粒子蛋糕
- 三层不同颜色 / 尺寸的粒子蛋糕体(红 + 青 + 蓝渐变),随机粒子分布模拟蛋糕纹理
- 6 根动态闪烁蜡烛,实现上下晃动 + 亮度变化双动画,还原真实蜡烛效果
- 移除了蛋糕顶部冗余文字,仅保留纯粹的蛋糕粒子视觉效果
// 创建分层蛋糕
createCake() {
// 三层蛋糕配置(半径/高度/位置/颜色)
const cakeLayers = [
{ radius: 8, height: 2, y: 0, color: 0xff6b6b }, // 底层红
{ radius: 6, height: 2, y: 2.5, color: 0x4ecdc4 }, // 中层青
{ radius: 4, height: 2, y: 5, color: 0x45b7d1 } // 顶层蓝
];
// 生成每层蛋糕
cakeLayers.forEach(layer => this.createCakeLayer(layer.radius, layer.height, layer.y, layer.color));
// 生成蜡烛
this.createCandles();
}
// 创建单一层蛋糕
createCakeLayer(radius, height, y, color) {
const particleCount = window.innerWidth > 768 ? 800 : 400;
const geometry = new THREE.BufferGeometry();
const positions = new Float32Array(particleCount * 3);
const colors = new Float32Array(particleCount * 3);
for (let i = 0; i < particleCount; i++) {
const angle = Math.random() * Math.PI * 2;
const r = Math.sqrt(Math.random()) * radius;
const idx = i * 3;
// 随机分布粒子模拟蛋糕纹理
positions[idx] = Math.cos(angle) * r;
positions[idx + 1] = y + Math.random() * height;
positions[idx + 2] = Math.sin(angle) * r;
// 蛋糕层颜色赋值
colors[idx] = (color >> 16 & 255) / 255;
colors[idx + 1] = (color >> 8 & 255) / 255;
colors[idx + 2] = (color & 255) / 255;
}
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
const material = new THREE.PointsMaterial({
size: 3,
vertexColors: true,
transparent: true,
opacity: 0.9,
blending: THREE.AdditiveBlending // 叠加模式增强亮度
});
const layer = new THREE.Points(geometry, material);
this.scene.add(layer);
this.cakeParticles.push(layer);
}
// 蜡烛闪烁动画(模拟火焰晃动+亮度变化)
animateCandle(candle) {
let time = 0;
const originalSizes = [];
const positions = candle.geometry.attributes.position.array;
// 存储原始Y坐标
for (let i = 1; i < positions.length; i += 3) {
originalSizes.push(positions[i]);
}
const animate = () => {
if (!candle.parent) return;
time += 0.1;
// 蜡烛上下晃动
for (let i = 0; i < positions.length / 3; i++) {
const idx = i * 3 + 1;
positions[idx] = originalSizes[i] + Math.sin(time + i) * 0.3;
}
candle.geometry.attributes.position.needsUpdate = true;
candle.material.opacity = 0.7 + Math.sin(time) * 0.3; // 亮度闪烁
requestAnimationFrame(animate);
};
animate();
}
3. 物理烟花效果
- 每 800ms 自动生成烟花,初始 3 发烟花瞬间引爆氛围
- 模拟真实物理运动:随机初始速度 + 重力加速度 + 空气阻力,2 秒后自然淡出
- 随机 HSL 颜色生成,每一发烟花都有独特视觉效果
// 创建烟花(物理运动+淡出效果)
createFirework() {
const fireworkCount = 300;
const geometry = new THREE.BufferGeometry();
const positions = new Float32Array(fireworkCount * 3);
const velocities = new Float32Array(fireworkCount * 3);
const colors = new Float32Array(fireworkCount * 3);
// 烟花初始位置(随机分布)
const x = (Math.random() - 0.5) * 100;
const y = Math.random() * 30;
const z = (Math.random() - 0.5) * 100;
// 随机HSL颜色
const color = new THREE.Color();
color.setHSL(Math.random(), 1, 0.7);
// 初始化烟花粒子
for (let i = 0; i < fireworkCount; i++) {
const idx = i * 3;
// 初始位置
positions[idx] = x;
positions[idx + 1] = y;
positions[idx + 2] = z;
// 随机球面速度(向四周扩散)
const speed = 0.5 + Math.random() * 1.5;
const phi = Math.random() * Math.PI * 2;
const theta = Math.random() * Math.PI;
velocities[idx] = Math.sin(theta) * Math.cos(phi) * speed;
velocities[idx + 1] = Math.cos(theta) * speed;
velocities[idx + 2] = Math.sin(theta) * Math.sin(phi) * speed;
// 颜色赋值
colors[idx] = color.r;
colors[idx + 1] = color.g;
colors[idx + 2] = color.b;
}
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
const material = new THREE.PointsMaterial({
size: 2,
vertexColors: true,
transparent: true,
opacity: 1,
blending: THREE.AdditiveBlending
});
const firework = new THREE.Points(geometry, material);
this.scene.add(firework);
// 物理运动参数
const gravity = -0.01; // 重力加速度
const life = 2000; // 烟花生命周期(2秒)
const startTime = Date.now();
// 烟花动画逻辑
const animateFirework = () => {
const elapsed = Date.now() - startTime;
if (elapsed > life) {
// 清理烟花(释放内存)
this.scene.remove(firework);
geometry.dispose();
material.dispose();
return;
}
const positions = firework.geometry.attributes.position.array;
// 更新粒子位置(重力+阻力)
for (let i = 0; i < fireworkCount; i++) {
const idx = i * 3;
positions[idx] += velocities[idx];
positions[idx + 1] += velocities[idx + 1];
positions[idx + 2] += velocities[idx + 2];
// 叠加重力
velocities[idx + 1] += gravity;
// 空气阻力(速度衰减)
velocities[idx] *= 0.99;
velocities[idx + 1] *= 0.99;
velocities[idx + 2] *= 0.99;
}
firework.geometry.attributes.position.needsUpdate = true;
material.opacity = 1 - (elapsed / life); // 逐渐淡出
requestAnimationFrame(animateFirework);
};
animateFirework();
}
4. 动态祝福语气泡
- 内置 100 句新年祝福语,每 30ms 随机生成一个气泡
- 金色渐变背景 + 文字阴影,适配移动端字体大小
- 限制最大气泡数量(50 个),自动清理过期气泡,避免性能损耗
// 显示随机祝福语气泡
showRandomBlessing() {
// 限制最大气泡数量(避免性能损耗)
if (this.blessingElements.length >= this.maxBlessings) {
const oldest = this.blessingElements.shift();
oldest && oldest.remove();
}
// 随机选择祝福语(内置100句)
const blessingText = BLESSINGS[Math.floor(Math.random() * BLESSINGS.length)];
const bubble = document.createElement('div');
bubble.className = 'blessing-bubble';
bubble.textContent = blessingText;
// 随机位置(避免边缘)
const x = 10 + Math.random() * 80;
const y = 10 + Math.random() * 80;
bubble.style.left = `${x}%`;
bubble.style.top = `${y}%`;
// 随机大小+金色渐变背景
const size = 0.8 + Math.random() * 0.4;
bubble.style.transform = `translate(-50%, -50%) scale(${size})`;
const hue = Math.random() * 60;
bubble.style.background = `linear-gradient(135deg, hsla(${hue}, 100%, 60%, 0.9), hsla(${hue + 20}, 100%, 50%, 0.9))`;
// 添加到页面并管理生命周期
document.getElementById('blessings-container').appendChild(bubble);
this.blessingElements.push(bubble);
// 3秒后自动移除
setTimeout(() => {
bubble.style.opacity = 0;
setTimeout(() => bubble.remove(), 300);
const index = this.blessingElements.indexOf(bubble);
index > -1 && this.blessingElements.splice(index, 1);
}, 3000);
}
5. 多端交互适配
- 鼠标 / 触摸拖动:实现 3D 视角旋转,支持任意角度查看蛋糕 / 烟花
- 滚轮缩放:调整视角距离,放大查看细节 / 缩小看全局
- 响应式布局:适配 768px 以下移动端,自动调整粒子数量 / 字体大小
// 绑定交互事件(鼠标/触摸/缩放)
bindEvents() {
// 窗口适配
window.addEventListener('resize', () => {
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(window.innerWidth, window.innerHeight);
});
// 鼠标/触摸拖动旋转
const onPointerDown = (e) => {
this.isDragging = true;
this.previousPosition = {
x: e.clientX || e.touches[0].clientX,
y: e.clientY || e.touches[0].clientY
};
};
const onPointerMove = (e) => {
if (!this.isDragging) return;
const currentX = e.clientX || e.touches[0].clientX;
const currentY = e.clientY || e.touches[0].clientY;
const deltaX = currentX - this.previousPosition.x;
const deltaY = currentY - this.previousPosition.y;
// 更新旋转角度(限制X轴旋转范围)
this.cameraRotation.y += deltaX * 0.01;
this.cameraRotation.x -= deltaY * 0.01;
this.cameraRotation.x = Math.max(-Math.PI/2, Math.min(Math.PI/2, this.cameraRotation.x));
this.updateCameraPosition();
this.previousPosition = { x: currentX, y: currentY };
};
交互事件绑定
// 拖动旋转视角
const onPointerMove = (e) => {
if (!this.isDragging) return;
const deltaX = currentX - this.previousPosition.x;
const deltaY = currentY - this.previousPosition.y;
this.cameraRotation.y += deltaX * 0.01;
this.cameraRotation.x -= deltaY * 0.01;
this.updateCameraPosition();
};
// 滚轮缩放
canvas.addEventListener('wheel', (e) => {
e.preventDefault();
this.cameraDistance = Math.max(10, Math.min(50, this.cameraDistance + e.deltaY * 0.01));
this.updateCameraPosition();
});
📝 使用说明
1. 运行环境
- 浏览器:推荐 Chrome/Edge 最新版(需支持 WebGL)
- 移动端:支持微信 / QQ 内置浏览器、手机 Chrome 等
2. 操作方式
- 直接打开 HTML 文件即可运行(Three.js 通过 CDN 引入,无需本地安装依赖)
- 拖动鼠标 / 手指:旋转 3D 视角,查看蛋糕 / 烟花不同角度
- 滚轮缩放:放大 / 缩小视角,调整查看距离
3. 注意事项
- 若提示 “浏览器不支持 3D 特效”,请升级 Chrome/Edge 浏览器后重试
- 低配设备可能出现粒子卡顿,可适当减少粒子数量(代码中 particleCount 参数)
- 移动端建议横屏查看,体验更佳
📥 源码获取
本文展示的是核心实现思路,完整可运行的源码已上传至我的 CSDN 主页资源库👉 小熊的资源库,需要的小伙伴可以到我的主页资源库中下载,直接开箱即用!
🎉 跨年祝福
最后,小熊祝各位小伙伴 2026 新年快乐🎆!所求皆如愿,所行皆坦途,新的一年代码无 bug,薪资节节高,保持热爱,奔赴山海!
如果觉得这个跨年特效还不错,记得点赞 + 收藏 + 关注哦~你的支持就是我创作的最大动力!评论区留下你的新年愿望,2026 我们一起加油💪!
✨ 我是小熊,关注我,获取更多炫酷前端特效 / 后端实战教程~

3607

被折叠的 条评论
为什么被折叠?



