这可不是一个普通的粒子苹果树!而是一个可实时交互记忆存储工具!

:red_apple: 3D粒子苹果树项目介绍

:glowing_star: 在线体验

在线体验:3D粒子苹果树 | 交互式Web艺术作品

https://apple-tree-sand.vercel.app/

:bust_in_silhouette: 作者

作者:小陈

:wrench: 技术栈

技术栈:原生HTML · CSS · JavaScript · Three.js · MediaPipe

:date: 开发周期

周期:两周,从"老师布置的苹果相关创作题目"开始 → 交互式3D粒子苹果树上线

:package: 开源仓库

项目截图:

手部实时交互:

视频链接:https://www.douyin.com/user/self?from_tab_name=main&modal_id=7637730920849476907&showTab=post

:sparkles: 功能特性

  • :artist_palette: 精美的星空背景和3D粒子苹果树
  • :sparkles: 扩散/聚合动画效果
  • :musical_note: 音频可视化
  • :camera_with_flash: 照片模式和粒子编辑器
  • :raised_hand: 手势控制(MediaPipe)
  • :artist_palette: 颜色编辑器
  • :wastebasket: 完整的数据删除功能

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 扩散/聚合动画

功能说明: 实现粒子从树形结构到球形扩散、再聚合回树形的流畅过渡动画。

交互方式

  • 点击界面上的「:sparkles: 扩散/聚合」按钮触发

  • 或使用手势控制(双手捏合/张开)

  • 动画过程约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);

动画特性

  • :white_check_mark: 使用三次缓动函数确保自然流畅

  • :white_check_mark: 粒子按类型分批显示/隐藏

  • :white_check_mark: 支持动画过程中的暂停和反向

  • :white_check_mark: 动态粒子可见性调整

2.2 星空背景系统

2.2.1 多层星空渲染

功能说明: 实现四层深度的星空背景,营造沉浸式宇宙氛围。

层次结构

  1. CSS星星层:约200个静态闪烁星星,最远距离

  2. Canvas星星层:约500个中距离星星,带视差滚动

  3. 星云粒子层:约150个彩色星云粒子,平滑漂移

  4. 流星系统:随机出现的流星划过动画

技术实现

// 四层视差滚动速度
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视角

双手捏合

聚合粒子

将扩散的粒子聚合回树形

双手张开

扩散粒子

将粒子扩散成球形

手势识别流程

  1. 视频捕获:获取用户摄像头画面

  2. 手部检测:MediaPipe检测手部关键点

  3. 手势解析:分析手指关节位置和距离

  4. 动作映射:将手势转换为对应操作

  5. 平滑处理:使用卡尔曼滤波减少抖动

性能优化

// 动态调整检测频率
if (fps < 25) {
  detectionInterval = 60;  // 低性能时降低频率
} else if (fps > 50) {
  detectionInterval = 45;  // 高性能时提高频率
}

2.3.3 自动旋转模式

功能说明: 自动旋转视角,展示3D树的各个角度。

操作方式

  • 点击「:counterclockwise_arrows_button: 自动旋转」按钮切换

  • 旋转速度可调:0.2x - 2.0x

应用场景

  • 展示作品时使用

  • 无需交互时自动浏览

  • 作为动态壁纸效果

2.4 粒子编辑系统

2.4.1 粒子选择与高亮

功能说明: 支持单个和多个粒子的选择、高亮显示。

选择方式

  1. 单击选择:点击单个粒子选中

  2. 框选:拖拽鼠标框选多个粒子

  3. 类型选择:选择同类型的所有粒子

高亮效果

  • 选中粒子放大1.5倍

  • 添加发光特效

  • 显示粒子信息悬浮框

2.4.2 颜色编辑器

功能说明: 强大的粒子颜色自定义系统。

编辑功能

  • :white_check_mark: 拾色器选择颜色

  • :white_check_mark: RGB滑块精确调节

  • :white_check_mark: 透明度调节

  • :white_check_mark: 颜色历史记录(最近10个)

  • :white_check_mark: 批量应用到多个粒子

  • :white_check_mark: 一键重置颜色

颜色历史管理

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位置。

操作方式

  1. 进入粒子编辑模式

  2. 选中粒子

  3. 拖拽鼠标移动粒子

  4. 松开完成编辑

坐标映射

  • 屏幕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 删除确认机制

功能说明: 安全的删除确认系统,防止误操作。

删除类型

  1. 清空数据:清除粒子的标题、描述、媒体等,保留粒子单元

  2. 删除单元:完全删除粒子数据单元

确认对话框

  • 显示被删除粒子的信息

  • 明确说明删除后果

  • 取消和确认双按钮

  • 支持ESC键关闭

2.6.2 删除操作流程

操作步骤

  1. 用户点击删除按钮

  2. 系统弹出确认对话框

  3. 用户确认删除

  4. 系统执行删除操作

  5. 更新LocalStorage

  6. 刷新界面显示

  7. 显示操作反馈

错误处理

  • 数据完整性检查

  • 删除失败回滚

  • 用户友好的错误提示

2.7 性能监控与诊断系统

2.7.1 实时性能指标

监控内容

  • :thermometer: FPS(每秒帧数)

  • :stopwatch: 帧时间(毫秒)

  • :chart_decreasing: 失帧数统计

  • :bar_chart: 平均FPS

  • :chart_increasing: FPS方差

  • :bullseye: 当前场景状态

  • :warning: 异常事件计数

显示方式

  • 信息面板实时更新

  • 历史数据图表

  • 性能告警提示

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 加载优化

分阶段加载

  1. 首屏:基础UI + 简单树

  2. 第二阶段:完整粒子系统

  3. 第三阶段:星空背景

  4. 第四阶段:加载用户数据


7. 预期价值与应用场景

7.1 教育价值

STEAM教育

  • :triangular_ruler: 数学:分形几何、3D坐标、三角函数

  • :microscope: 科学:粒子系统、物理模拟

  • :artist_palette: 艺术:视觉设计、色彩理论

  • :laptop: 技术:WebGL、Three.js、前端开发

教学应用

  • 计算机图形学入门演示

  • 交互式学习工具

  • 课程作业参考

7.2 创意应用场景

7.2.1 数字纪念册

用法

  • 每个粒子代表一个回忆

  • 附加照片和故事

  • 形成3D记忆树

特点

  • 沉浸式浏览体验

  • 视觉化记忆网络

  • 时间轴呈现

7.2.2 交互式艺术装置

场景

  • 展览展示

  • 商场美陈

  • 科技馆互动

  • 活动背景墙

特性

  • 支持多人同时交互

  • 手势控制吸引眼球

  • 视觉效果震撼

7.2.3 个人网站主页

优势

  • 极具个性的视觉效果

  • 展示技术能力

  • 访客互动性强

7.2.4 教育科普工具

用途

  • 植物生长模拟

  • 分形几何教学

  • 粒子系统演示

7.3 技术示范价值

技术展示

  • :white_check_mark: Three.js 3D应用

  • :white_check_mark: 复杂粒子系统

  • :white_check_mark: MediaPipe 手势识别

  • :white_check_mark: WebGL 优化技巧

  • :white_check_mark: 前端工程实践

学习资源

  • 完整的代码实现

  • 详细的注释说明

  • 可扩展的架构设计

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+

:white_check_mark: 完全支持

Firefox

88+

:white_check_mark: 完全支持

Safari

14+

:white_check_mark: 完全支持

Edge

90+

:white_check_mark: 完全支持

移动端浏览器

-

:warning: 部分功能受限

C. 系统要求

最低配置

  • CPU:双核 2.0GHz

  • 内存:4GB

  • 显卡:支持WebGL

  • 网络:2Mbps

推荐配置

  • CPU:四核 2.5GHz+

  • 内存:8GB+

  • 显卡:独立显卡

  • 网络:10Mbps+


文档版本:v1.0
最后更新:2024-05-09
作者:小陈

小陈哥哥,能不能下次,不要整那么长

好的 :blush::blush: :blush:

1 个赞