最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Canvas 绘制自定义形状 UI 组件:状态与样式管理
时间:2026-08-27 20:49:47 编辑:袖梨 来源:一聚教程网
HarmonyOS ArkTS中Canvas自定义图形需状态驱动重绘:用@State管理参数,onReady保存context,封装drawShape()方法;样式通过计算属性、@Styles和Environment.theme动态配置;交互状态用@Link/@Prop同步;复杂场景采用OffscreenCanvas离屏缓存优化性能。
在 HarmonyOS ArkTS 开发中,用 Canvas 绘制自定义形状 UI 组件时,状态与样式管理不是靠写死参数,而是要让图形响应数据变化、支持交互反馈、适配不同主题或用户操作——核心在于把“画什么”和“怎么画”解耦,再通过 ArkTS 的状态装饰器驱动重绘。
状态驱动绘制逻辑
Canvas 本身不自动响应状态变化,必须手动触发重绘。关键是在状态变更后调用 context 的绘制方法,并确保 onReady 后的上下文可用。
- 用 @State 管理图形参数(如
fillColor、isFilled、rotation、size),这些变量一变,组件自动重新 build - 在 onReady 回调中保存 context 引用,后续所有绘制都基于这个实例;避免每次 build 都新建 context
- 把绘制逻辑封装成独立方法(如
drawShape()),在 @Watch 或事件回调里调用它,而不是只在 onReady 里画一次 - 注意:直接修改
this.context.fillStyle不会触发 UI 更新,必须配合状态变更 + 主动调用 draw 方法
样式复用与动态配置
同一个图形组件可能在不同场景下需要不同视觉表现(比如选中高亮、禁用灰化、深色模式适配),样式不应硬编码在 draw 函数里。
- 把颜色、线宽、透明度等提取为计算属性,例如:
get strokeColor() { return this.isSelected ? '#007AFF' : '#999'; } - 使用 @Styles 装饰器定义可复用的样式集,适用于多个 Canvas 组件共享基础描边/填充规则
- 结合 environment 模块读取系统主题(
Environment.theme),自动切换 fillStyle 和 strokeStyle 的深浅色值 - 避免在
drawPath()中重复设置 context 属性,统一在prepareStyle()中集中处理(参考 Shape 基类设计)
图形状态与 UI 状态同步
自定义图形常需响应点击、拖拽、缩放等交互,此时图形内部状态(如是否被选中、当前坐标)要和 UI 层状态对齐。
- 用 @Link 或 @Prop 接收父组件传入的控制状态(如
isSelected: boolean),实现父子联动 - 在手势事件(如
PanGesture.onActionUpdate)中更新本地坐标状态,并立即调用重绘,保证拖拽流畅 - 对多图形场景,建议用 @Observed + @ObjectLink 管理图形集合,单个图形属性变更时只重绘对应区域(需配合
clearRect局部擦除) - 选中态图形常需加边框或阴影,可在
draw()末尾追加描边或 shadow 相关设置,但记得开启context.shadowColor等开关
离屏缓存优化绘制性能
当图形复杂或频繁重绘(如动画、实时缩放),直接在主 Canvas 上逐帧绘制容易卡顿。离屏绘制能预渲染静态部分,提升响应速度。
- 用 OffscreenCanvasRenderingContext2D 创建离屏画布,预先绘制不变元素(如底纹、图标轮廓)
- 调用
offContext.transferToImageBitmap()生成图像位图,再用主 context 的transferFromImageBitmap()快速贴图 - 仅对动态部分(如拖拽中的高亮框、实时路径)在主 Canvas 上即时绘制,其余复用离屏结果
- 注意内存管理:ImageBitmap 使用后及时释放,避免离屏画布过大导致 OOM