DIY 场景编辑功能
适用范围:Wi-Fi + BLE 面板
🖼️ 预览:
DIY 场景编辑功能模块允许用户创建和编辑自定义灯光场景,支持两种编辑模式:动态场景编辑(基于颜色和动效参数)和静态场景编辑(基于灯珠涂抹)。该模块提供了完整的场景创建、编辑、预览、保存和管理功能,是用户个性化灯光效果的核心工具。
功能列表
- 动态 DIY 场景编辑:通过颜色列表和动效参数创建动态场景
- 静态 DIY 场景编辑:通过涂抹方式精确控制每个灯珠的颜色
- 场景预览:实时预览场景效果
- 场景保存:将场景保存到云存储
- 场景加载:从云存储加载已有场景进行编辑
- 场景删除:删除不需要的场景
- 场景列表管理:查看和管理所有 DIY 场景
功能实现详解
动态 DIY 场景编辑
动态 DIY 场景编辑使用SceneData数据结构,包含颜色列表和动效参数。编辑页面提供颜色管理和参数调整功能,场景数据通过rgbic_linerlight_scene DP 点下发。
核心组件
src/pages/diyEdit/index.tsx: 动态 DIY 场景编辑页面src/components/colors/index.tsx: 颜色列表组件src/components/motion-config/index.tsx: 动效参数配置组件src/hooks/useSceneSet.ts: 场景设置 Hook
数据流
flowchart TD
A[进入编辑页面] --> B[加载场景数据]
B --> C{是否编辑模式}
C -->|是| D[从云存储加载]
C -->|否| E[使用默认数据]
D --> F[显示颜色列表]
E --> F
F --> G[用户添加/删除颜色]
G --> H[选择动效类型]
H --> I[调整动效参数]
I --> J[预览场景]
J --> K[保存场景]
K --> L[编码场景数据]
L --> M[保存到云存储]
M --> N[下发DP到设备]关键代码片段
场景保存实现:
数据结构
场景数据格式:
静态 DIY 场景编辑
静态 DIY 场景编辑使用DiySceneData数据结构,包含每个灯珠的颜色信息。通过涂抹方式控制每个灯珠,场景数据通过diy_scene DP 点下发。
核心组件
src/pages/staticDiyEdit/index.tsx: 静态 DIY 场景编辑页面src/components/light-strip/index.tsx: 灯带可视化组件src/hooks/useDrawToolDataList.ts: 涂抹工具数据管理 Hooksrc/hooks/useCutDrawDiyScene.ts: 涂抹场景设置 Hook
数据流
sequenceDiagram
participant User as 用户
participant Page as 编辑页面
participant Strip as 灯带组件
participant Hook as 数据Hook
participant Protocol as 协议解析器
participant Device as 设备
User->>Page: 选择颜色和涂抹模式
User->>Strip: 选择灯珠
Strip->>Page: 更新选中状态
Page->>Hook: 调用更新函数
Hook->>Hook: 更新灯带数据
Hook->>Protocol: 编码场景数据
Protocol->>Device: 下发DP
Device-->>User: 显示效果
User->>Page: 保存场景
Page->>Hook: 保存到云存储关键代码片段
场景保存实现:
涂抹场景设置:
数据结构
DIY 场景数据格式:
场景预览
场景预览通过useSceneSet Hook 的preview方法实现,将场景数据编码后下发到设备,不保存到云存储。
核心组件
src/hooks/useSceneSet.ts: 场景设置 Hook
数据流
flowchart TD
A[用户点击预览] --> B[构建场景数据]
B --> C[useSceneSet.preview]
C --> D[编码场景数据]
D --> E[下发DP到设备]
E --> F[设备执行场景]
F --> G[用户观察效果]
G --> H{继续编辑?}
H -->|是| I[返回编辑]
H -->|否| J[保存场景]关键代码片段
预览实现:
场景保存
场景保存包括数据编码、云存储保存、DP 下发三个步骤。支持新增和更新两种模式,保存成功后触发场景创建事件。
核心组件
src/pages/diyEdit/index.tsx: 动态场景保存src/pages/staticDiyEdit/index.tsx: 静态场景保存src/hooks/useCloudStorageCombinedList.ts: 云存储列表管理src/hooks/useCloudDrawToolList.ts: 场景数据编解码
数据流
已在功能 1 和功能 2 中详细说明。
场景加载
场景加载从云存储读取场景数据,解码后填充到编辑页面。根据场景类型(动态或静态)加载到对应的编辑页面。
核心组件
src/pages/diyEdit/index.tsx: 动态场景加载src/pages/staticDiyEdit/index.tsx: 静态场景加载src/hooks/useCloudDrawToolList.ts: 场景数据解码
数据流
flowchart TD
A[用户选择编辑] --> B[获取场景ID]
B --> C[从云存储读取]
C --> D[解码场景数据]
D --> E{场景类型}
E -->|动态| F[加载到动态编辑页]
E -->|静态| G[加载到静态编辑页]
F --> H[填充颜色列表]
G --> I[填充灯珠数据]
H --> J[填充动效参数]
I --> K[显示灯带状态]场景删除
场景删除从云存储删除场景数据,更新场景列表。删除前需要用户确认。
核心组件
src/pages/diyEdit/index.tsx: 删除功能src/pages/staticDiyEdit/index.tsx: 删除功能src/hooks/useCloudStorageCombinedList.ts: 云存储删除
关键代码片段
删除实现(以动态场景为例):
场景列表管理
场景列表管理通过useDiySceneInit Hook 实现,从云存储读取所有场景,按类型分类显示,支持场景选择和切换。
核心组件
src/components/tab-diy/index.tsx: DIY 场景列表组件src/hooks/useDiySceneInit.ts: DIY 场景初始化 Hook
数据流
flowchart TD
A[进入DIY标签] --> B[useDiySceneInit初始化]
B --> C[从云存储读取场景列表]
C --> D[解码场景数据]
D --> E[按类型分类]
E --> F[显示场景卡片]
F --> G[用户选择场景]
G --> H{场景类型}
H -->|动态| I[应用动态场景]
H -->|静态| J[应用静态场景]
I --> K[下发场景DP]
J --> K
K --> L[更新当前场景ID]关键代码片段
场景初始化:
场景列表生成:
注意事项
实现难点
-
场景数据编解码:
- 难点:动态场景和静态场景使用不同的数据格式和 DP 点
- 解决方案:使用
encodeCloudSceneData和decodeCloudSceneData统一编解码,通过type字段区分场景类型
-
灯珠数据对齐:
- 难点:静态场景的灯珠数据需要与设备灯珠数量对齐
- 解决方案:在
useCutDrawDiySceneSet中检查数据长度,不足时补全默认颜色,超出时截断
-
场景类型区分:
- 难点:需要区分动态场景(scene)和静态场景(draw)
- 解决方案:在云存储数据中使用
type字段标识,加载时根据类型选择对应的处理逻辑
-
场景名称去重:
- 难点:防止场景名称重复
- 解决方案:使用
dedup函数检查名称,保存时提示用户修改
常见问题
-
问题:场景加载后数据不正确
- 原因:数据解码失败或格式不匹配
- 解决方法:检查数据格式,增加错误处理,使用默认值兜底
-
问题:预览无效果
- 原因:设备未连接或 DP 下发失败
- 解决方法:检查设备连接状态,查看 DP 下发日志
-
问题:静态场景灯珠数量不匹配
- 原因:设备灯珠数量变化或数据损坏
- 解决方法:自动对齐灯珠数量,补全或截断数据
性能优化
-
场景列表缓存:
- 使用
useMemo缓存场景列表,避免重复计算 - 场景列表按 ID 倒序排列,最新场景在前
- 使用
-
数据编码优化:
- 场景数据编码使用高效的字符串拼接
- 避免不必要的深拷贝
-
懒加载:
- 场景列表分页显示,避免一次性加载所有场景
- 场景数据按需解码
-
防抖处理:
- 场景保存使用防抖,避免重复保存
- 场景预览使用节流,避免频繁下发 DP
边界情况
-
场景列表为空:
- 处理:显示空状态提示,引导用户创建场景
- 提供默认场景选项
-
场景数据损坏:
- 处理:解码失败时使用默认数据
- 提示用户场景数据异常
-
设备灯珠数量变化:
- 处理:自动对齐灯珠数量
- 超出部分截断,不足部分补全默认颜色
-
场景名称过长:
- 处理:限制场景名称长度
- 超出部分截断或提示用户
-
同时编辑多个场景:
- 处理:同一时间只能编辑一个场景
- 切换编辑时保存当前场景