3D粒子苹果树项目介绍
在线体验
在线体验:3D粒子苹果树 | 交互式Web艺术作品
https://apple-tree-sand.vercel.app/
作者
作者:小陈
技术栈
技术栈:原生HTML · CSS · JavaScript · Three.js · MediaPipe
开发周期
周期:两周,从"老师布置的苹果相关创作题目"开始 → 交互式3D粒子苹果树上线
开源仓库
项目截图:
手部实时交互:
视频链接:https://www.douyin.com/user/self?from_tab_name=main&modal_id=7637730920849476907&showTab=post
功能特性
精美的星空背景和3D粒子苹果树
扩散/聚合动画效果
音频可视化
照片模式和粒子编辑器
手势控制(MediaPipe)
颜色编辑器
完整的数据删除功能
1. 项目概述
1.1 项目简介
3D粒子苹果树是一个交互式Web艺术作品,以8800个粒子构建的3D苹果树为核心,融合了精美的星空背景、流畅的动画效果、手势控制、音频可视化、粒子编辑等丰富功能。项目以"苹果"为创作主题,从课程作业起步,经过两周的开发周期,最终成为一个功能完善的交互式Web应用。
1.2 核心技术栈
技术
版本/说明
用途
HTML5
页面结构
CSS3
样式与动画
JavaScript
ES6+
业务逻辑
Three.js
r128
3D渲染引擎
MediaPipe Hands
0.4.1646424915
手势识别
WebGL
硬件加速渲染
LocalStorage
-
数据持久化
1.3 技术架构图
用户交互层
├── 鼠标/键盘控制
├── 手势识别 (MediaPipe)
└── 触摸支持
功能应用层
├── 3D粒子系统
├── 照片模式
├── 粒子编辑器
├── 颜色编辑器
└── 性能监控
数据管理层
├── LocalStorage 持久化
├── 粒子单元管理
└── 状态管理
渲染引擎层
├── Three.js 渲染
├── WebGL 加速
└── Canvas 2D 背景
2. 核心功能模块
2.1 3D粒子树可视化模块
2.1.1 粒子树结构构建
功能说明: 使用8800个粒子构建具有生物形态的3D苹果树,包含树干、主枝、次级分枝、叶子、花朵和果实等多个层次。
实现方式:
-
采用递归分形算法生成树结构
-
每个粒子根据层级分配不同类型(树干、树枝、叶子、花朵、果实)
-
粒子位置通过螺旋算法和高度曲线计算生成
技术细节:
// 粒子类型定义
const PARTICLE_TYPES = {
TRUNK: 0, // 树干 - 棕色
MAIN_BRANCH: 1, // 主枝 - 棕色
TWIG: 2, // 小枝 - 棕色
LEAF: 3, // 叶子 - 绿色
FLOWER: 4, // 花朵 - 白色/粉色
FRUIT: 5 // 果实 - 红色
};
粒子分布:
-
树干粒子:约1200个
-
树枝粒子:约2800个
-
叶子粒子:约3200个
-
花朵粒子:约1000个
-
果实粒子:约600个
2.1.2 扩散/聚合动画
功能说明: 实现粒子从树形结构到球形扩散、再聚合回树形的流畅过渡动画。
交互方式:
-
点击界面上的「
扩散/聚合」按钮触发 -
或使用手势控制(双手捏合/张开)
-
动画过程约3-4秒完成
技术实现:
// 使用缓动函数实现平滑过渡
function easeInOutCubic(t) {
return t < 0.5
? 4 * t * t * t
: 1 - Math.pow(-2 * t + 2, 3) / 2;
}
// 位置插值计算
currentPos = lerp(originalPos, explodedPos, easeProgress);
动画特性:
-
使用三次缓动函数确保自然流畅 -
粒子按类型分批显示/隐藏 -
支持动画过程中的暂停和反向 -
动态粒子可见性调整
2.2 星空背景系统
2.2.1 多层星空渲染
功能说明: 实现四层深度的星空背景,营造沉浸式宇宙氛围。
层次结构:
-
CSS星星层:约200个静态闪烁星星,最远距离
-
Canvas星星层:约500个中距离星星,带视差滚动
-
星云粒子层:约150个彩色星云粒子,平滑漂移
-
流星系统:随机出现的流星划过动画
技术实现:
// 四层视差滚动速度
const PARALLAX_SPEEDS = [0.02, 0.05, 0.08, 0.12];
// 星星闪烁频率
const FLICKER_FREQUENCY = [0.8, 1.2, 1.6, 2.0];
2.2.2 流星动画系统
功能说明: 随机生成流星从屏幕划过的动画,增强场景的生动性。
生成规则:
-
平均每8-15秒生成一颗流星
-
流星起始位置随机分布在屏幕边缘
-
飞行方向、速度、长度、亮度均有随机变化
视觉效果:
-
流星尾迹使用透明度渐变
-
头部最亮,尾部逐渐消失
-
流星持续时间约0.8-1.5秒
2.3 交互控制模块
2.3.1 鼠标/键盘控制
功能说明: 提供完整的鼠标和键盘控制方案。
控制操作:
操作
功能
左键拖拽
旋转视角
滚轮
缩放视角
右键拖拽
平移视角
单击粒子
选中粒子进行编辑
双击粒子
打开粒子编辑器
OrbitControls配置:
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // 启用阻尼
controls.dampingFactor = 0.05; // 阻尼系数
controls.autoRotate = false; // 自动旋转(可切换)
controls.autoRotateSpeed = 0.5; // 旋转速度
controls.minDistance = 20; // 最小缩放
controls.maxDistance = 150; // 最大缩放
2.3.2 手势控制系统(MediaPipe)
功能说明: 集成MediaPipe Hands手势识别,实现无接触的手势控制。
支持的手势:
手势
操作
功能说明
右手捏合
缩放控制
调节视角远近
右手张开+移动
旋转控制
旋转3D视角
双手捏合
聚合粒子
将扩散的粒子聚合回树形
双手张开
扩散粒子
将粒子扩散成球形
手势识别流程:
-
视频捕获:获取用户摄像头画面
-
手部检测:MediaPipe检测手部关键点
-
手势解析:分析手指关节位置和距离
-
动作映射:将手势转换为对应操作
-
平滑处理:使用卡尔曼滤波减少抖动
性能优化:
// 动态调整检测频率
if (fps < 25) {
detectionInterval = 60; // 低性能时降低频率
} else if (fps > 50) {
detectionInterval = 45; // 高性能时提高频率
}
2.3.3 自动旋转模式
功能说明: 自动旋转视角,展示3D树的各个角度。
操作方式:
-
点击「
自动旋转」按钮切换 -
旋转速度可调:0.2x - 2.0x
应用场景:
-
展示作品时使用
-
无需交互时自动浏览
-
作为动态壁纸效果
2.4 粒子编辑系统
2.4.1 粒子选择与高亮
功能说明: 支持单个和多个粒子的选择、高亮显示。
选择方式:
-
单击选择:点击单个粒子选中
-
框选:拖拽鼠标框选多个粒子
-
类型选择:选择同类型的所有粒子
高亮效果:
-
选中粒子放大1.5倍
-
添加发光特效
-
显示粒子信息悬浮框
2.4.2 颜色编辑器
功能说明: 强大的粒子颜色自定义系统。
编辑功能:
-
拾色器选择颜色 -
RGB滑块精确调节 -
透明度调节 -
颜色历史记录(最近10个) -
批量应用到多个粒子 -
一键重置颜色
颜色历史管理:
const MAX_COLOR_HISTORY = 10;
let colorHistory = [];
let colorHistoryIndex = -1;
// 记录颜色变更
function saveColorToHistory(color) {
if (colorHistory.length >= MAX_COLOR_HISTORY) {
colorHistory.shift();
}
colorHistory.push({...color});
}
2.4.3 粒子位置编辑
功能说明: 拖拽调整粒子的3D位置。
操作方式:
-
进入粒子编辑模式
-
选中粒子
-
拖拽鼠标移动粒子
-
松开完成编辑
坐标映射:
-
屏幕2D坐标 → 3D空间坐标
-
使用射线投射(Raycasting)计算
-
支持锁定轴向编辑
2.5 照片模式与数据管理
2.5.1 粒子数据单元
功能说明: 为每个粒子创建独立的数据单元,支持附加媒体和信息。
数据结构:
{
id: "uuid", // 唯一标识符
particleIndex: 1234, // 粒子索引
particleId: "粒子-1234", // 显示ID
title: "我的纪念", // 标题
description: "这是一个故事...", // 描述
photoData: "data:image/...", // 照片/视频数据
tags: ["纪念", "重要"], // 标签
createdAt: "2024-01-01", // 创建时间
updatedAt: "2024-01-01", // 更新时间
isPinned: false // 是否置顶
}
2.5.2 照片模式展示
功能说明: 网格形式展示所有附加了内容的粒子。
界面特点:
-
响应式网格布局
-
卡片式设计
-
文件类型标识(图片/视频)
-
标签显示
-
编辑和删除操作
2.5.3 数据导入导出
功能说明: 支持粒子数据的备份和分享。
导出格式:
-
JSON格式文件
-
包含所有粒子数据
-
Base64编码的媒体文件
导入功能:
-
验证文件格式
-
冲突检测与处理
-
增量更新支持
2.6 删除功能模块
2.6.1 删除确认机制
功能说明: 安全的删除确认系统,防止误操作。
删除类型:
-
清空数据:清除粒子的标题、描述、媒体等,保留粒子单元
-
删除单元:完全删除粒子数据单元
确认对话框:
-
显示被删除粒子的信息
-
明确说明删除后果
-
取消和确认双按钮
-
支持ESC键关闭
2.6.2 删除操作流程
操作步骤:
-
用户点击删除按钮
-
系统弹出确认对话框
-
用户确认删除
-
系统执行删除操作
-
更新LocalStorage
-
刷新界面显示
-
显示操作反馈
错误处理:
-
数据完整性检查
-
删除失败回滚
-
用户友好的错误提示
2.7 性能监控与诊断系统
2.7.1 实时性能指标
监控内容:
-
FPS(每秒帧数) -
帧时间(毫秒) -
失帧数统计 -
平均FPS -
FPS方差 -
当前场景状态 -
异常事件计数
显示方式:
-
信息面板实时更新
-
历史数据图表
-
性能告警提示
2.7.2 智能性能调节
功能说明: 根据设备性能自动调整渲染质量。
调节策略:
// 性能模式定义
const PERFORMANCE_MODES = {
HIGH: { particleRatio: 1.0, fpsTarget: 60 },
NORMAL: { particleRatio: 0.7, fpsTarget: 45 },
LOW: { particleRatio: 0.4, fpsTarget: 30 }
};
// 自动调节逻辑
if (avgFPS > 55) switchToHighPerf();
else if (avgFPS < 25) switchToLowPerf();
调节内容:
-
粒子显示数量(40%-100%)
-
渲染质量
-
手势检测频率
-
背景动画复杂度
3. 用户操作流程
3.1 新用户首次访问流程
1. 打开网站
↓
2. 看到3D粒子苹果树 + 星空背景
↓
3. 鼠标拖拽旋转视角 / 滚轮缩放
↓
4. 点击「✨ 扩散/聚合」体验动画
↓
5. 浏览其他功能按钮
↓
6. 点击任意粒子开始编辑
3.2 粒子编辑完整流程
1. 找到感兴趣的粒子
↓
2. 双击粒子打开编辑器
↓
3. 填写标题、描述、添加标签
↓
4. 上传照片或视频(可选)
↓
5. 点击「💾 保存」按钮
↓
6. 提示保存成功
↓
7. 点击「📸 翻转显示」查看照片墙
↓
8. 在照片墙中看到刚保存的内容
3.3 手势控制使用流程
1. 点击「✋ 手势控制」按钮
↓
2. 允许摄像头权限
↓
3. 将手放入摄像头视野
↓
4. 右手捏合 → 缩放视角
↓
5. 右手张开移动 → 旋转视角
↓
6. 双手捏合 → 聚合粒子
↓
7. 双手张开 → 扩散粒子
3.4 删除数据操作流程
1. 方式A:在照片墙点击「🗑️」
方式B:在粒子编辑器点击删除按钮
↓
2. 弹出删除确认对话框
↓
3. 确认删除后果
↓
4. 点击「确认删除」
↓
5. 数据被删除,界面自动更新
4. 技术特性详解
4.1 粒子系统算法
4.1.1 树形结构生成
分形递归算法:
函数 growBranch(起点, 角度, 层级)
if 层级 > 最大层级: return
创建此层级的粒子
按螺旋分布计算位置
应用高度曲线调整Y轴
if 层级 < 最大层级:
递归 growBranch(子节点1, 角度+θ, 层级+1)
递归 growBranch(子节点2, 角度-θ, 层级+1)
螺旋位置公式:
radius = baseRadius * (1 - progress) + tipRadius * progress
angle = startAngle + spiralRotations * 2π * progress
x = centerX + radius * cos(angle)
z = centerZ + radius * sin(angle)
y = baseY + arcHeight(progress)
4.1.2 扩散位置计算
球形均匀分布:
// 使用拒绝采样生成均匀分布的球面点
function generateUniformSpherePoint(minRadius, maxRadius, centerY) {
let x, y, z, length;
do {
x = Math.random() * 2 - 1;
y = Math.random() * 2 - 1;
z = Math.random() * 2 - 1;
length = x*x + y*y + z*z;
} while (length > 1); // 拒绝立方体外的点
// 归一化并缩放
const scale = minRadius + Math.random() * (maxRadius - minRadius);
return {
x: x / Math.sqrt(length) * scale,
y: y / Math.sqrt(length) * scale + centerY,
z: z / Math.sqrt(length) * scale
};
}
4.2 渲染优化技术
4.2.1 粒子批处理
技术说明: 使用单个BufferGeometry渲染所有粒子,而非多个独立Mesh。
性能提升:
-
Draw Call从8800降至1
-
GPU利用率大幅提高
-
内存占用减少约60%
实现代码:
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
geometry.setAttribute('size', new THREE.Float32BufferAttribute(sizes, 1));
const material = new THREE.PointsMaterial({
size: 0.3,
vertexColors: true,
transparent: true,
opacity: 0.9,
blending: THREE.AdditiveBlending
});
particles = new THREE.Points(geometry, material);
4.2.2 动态LOD(细节层次)
功能说明: 根据粒子到相机的距离,动态调整粒子大小和可见性。
距离区间:
距离
粒子大小
可见性
<20
1.2x
100%
20-50
1.0x
100%
50-100
0.8x
80%
>100
0.6x
60%
4.3 数据持久化方案
4.3.1 LocalStorage管理
存储结构:
{
"apple-tree-particle-units": {
"uuid-1": { /* 粒子数据 */ },
"uuid-2": { /* 粒子数据 */ },
...
},
"apple-tree-settings": {
"performanceMode": "normal",
"autoRotate": false,
"gestureEnabled": false
}
}
存储限制处理:
-
检测LocalStorage容量
-
超过5MB时提示用户
-
提供压缩选项
-
支持增量导出
4.3.2 错误恢复机制
数据验证:
-
加载时检查数据完整性
-
损坏数据自动修复或跳过
-
定期自动备份
5. 数据管理系统
5.1 粒子单元生命周期
创建阶段
├── 点击粒子
├── 生成UUID
├── 初始化默认数据
└── 关联粒子索引
编辑阶段
├── 修改属性
├── 上传媒体
├── 添加标签
├── 实时预览
└── 临时保存
持久化阶段
├── 验证数据
├── 序列化
├── 压缩处理
├── 写入LocalStorage
└── 备份原数据
展示阶段
├── 读取数据
├── 反序列化
├── 渲染卡片
└── 交互响应
删除阶段
├── 确认操作
├── 删除数据
├── 更新索引
└── 刷新界面
5.2 搜索与过滤系统
搜索功能:
-
按标题关键词搜索
-
按标签筛选
-
按创建时间排序
-
按更新时间排序
搜索算法:
function searchParticleUnits(query) {
const results = [];
const lowerQuery = query.toLowerCase();
for (const unit of Object.values(particleUnits)) {
const matchTitle = unit.title.toLowerCase().includes(lowerQuery);
const matchDesc = unit.description.toLowerCase().includes(lowerQuery);
const matchTags = unit.tags.some(tag =>
tag.toLowerCase().includes(lowerQuery));
if (matchTitle || matchDesc || matchTags) {
results.push(unit);
}
}
return results.sort((a, b) =>
new Date(b.updatedAt) - new Date(a.updatedAt));
}
6. 性能优化策略
6.1 渲染优化
优化技术
效果
实现方式
粒子批处理
减少90% Draw Call
单BufferGeometry
视锥体剔除
减少40%渲染量
Frustum Culling
动态粒子比例
自适应性能
30%-100%可调
增量更新
减少CPU占用
只更新变化的粒子
WebGL实例化
大幅提升效率
InstancedBufferGeometry
6.2 内存优化
策略:
-
对象池重用粒子对象
-
及时释放不再使用的纹理
-
使用Float32Array替代普通数组
-
媒体文件压缩存储
6.3 加载优化
分阶段加载:
-
首屏:基础UI + 简单树
-
第二阶段:完整粒子系统
-
第三阶段:星空背景
-
第四阶段:加载用户数据
7. 预期价值与应用场景
7.1 教育价值
STEAM教育:
-
数学:分形几何、3D坐标、三角函数 -
科学:粒子系统、物理模拟 -
艺术:视觉设计、色彩理论 -
技术:WebGL、Three.js、前端开发
教学应用:
-
计算机图形学入门演示
-
交互式学习工具
-
课程作业参考
7.2 创意应用场景
7.2.1 数字纪念册
用法:
-
每个粒子代表一个回忆
-
附加照片和故事
-
形成3D记忆树
特点:
-
沉浸式浏览体验
-
视觉化记忆网络
-
时间轴呈现
7.2.2 交互式艺术装置
场景:
-
展览展示
-
商场美陈
-
科技馆互动
-
活动背景墙
特性:
-
支持多人同时交互
-
手势控制吸引眼球
-
视觉效果震撼
7.2.3 个人网站主页
优势:
-
极具个性的视觉效果
-
展示技术能力
-
访客互动性强
7.2.4 教育科普工具
用途:
-
植物生长模拟
-
分形几何教学
-
粒子系统演示
7.3 技术示范价值
技术展示:
-
Three.js 3D应用 -
复杂粒子系统 -
MediaPipe 手势识别 -
WebGL 优化技巧 -
前端工程实践
学习资源:
-
完整的代码实现
-
详细的注释说明
-
可扩展的架构设计
7.4 商业扩展可能性
定制开发:
-
企业品牌树
-
产品展示树
-
组织架构树
-
知识图谱可视化
增值功能:
-
云端数据同步
-
多人协作编辑
-
AR/VR 版本
-
社交分享功能
8. 未来发展规划
8.1 短期规划(1-3个月)
-
性能进一步优化(目标FPS ≥ 60)
-
移动端适配优化
-
更多手势识别
-
音频响应可视化
8.2 中期规划(3-6个月)
-
云端数据同步
-
多语言支持
-
主题系统(春夏秋冬)
-
导出视频功能
8.3 长期愿景(6个月+)
-
AR版本(WebXR)
-
多人在线协作
-
AI辅助创作
-
社区分享平台
附录
A. 快捷键一览表
按键
功能
空格
暂停/继续动画
R
重置视角
E
切换编辑模式
C
打开颜色编辑器
P
切换照片模式
G
切换手势控制
ESC
关闭弹窗/退出模式
B. 浏览器兼容性
浏览器
最低版本
支持情况
Chrome
90+
完全支持
Firefox
88+
完全支持
Safari
14+
完全支持
Edge
90+
完全支持
移动端浏览器
-
部分功能受限
C. 系统要求
最低配置:
-
CPU:双核 2.0GHz
-
内存:4GB
-
显卡:支持WebGL
-
网络:2Mbps
推荐配置:
-
CPU:四核 2.5GHz+
-
内存:8GB+
-
显卡:独立显卡
-
网络:10Mbps+
文档版本:v1.0
最后更新:2024-05-09
作者:小陈



