【HarmonyOS 鸿蒙实战开发】橡皮擦案例

往期知识点整理

介绍

本示例通过 @ohos.graphics.drawing 库和 blendMode颜色混合 实现了橡皮擦功能,能够根据手指移动轨迹擦除之前绘制的内容,并且可以进行图案的撤销和恢复。

效果图预览

使用说明

  1. 页面底部左侧展示涂鸦和橡皮擦按钮,点击可以切换选中状态和当前的绘制模式,右侧为线宽列表,点击可以修改绘制时的轨迹宽度。
  2. 在图片上触摸并拖动手指,可以绘制路径,涂鸦模式时绘制橙色线条,橡皮擦模式时擦除线条。
  3. 页面顶部按钮默认不可用,进行绘制操作后左侧撤销按钮高亮,点击可以撤销上一步绘制,撤销后未进行绘制时右侧恢复按钮高亮,点击可以恢复上一次撤销。

实现思路

  1. 使用NodeContainer构建绘制区域。
  • 定义NodeController的子类MyNodeController,实例化后可以通过将自绘制渲染节点RenderNode挂载到对应节点容器NodeContainer上实现自定义绘制。
   /**
    * NodeController的子类MyNodeController
    */
   export class MyNodeController extends NodeController {
   
   
     private rootNode: FrameNode | null = null; // 根节点
     rootRenderNode: RenderNode | null = null; // 从NodeController根节点获取的RenderNode,用于添加和删除新创建的MyRenderNode实例
   
     // MyNodeController实例绑定的NodeContainer创建时触发,创建根节点rootNode并将其挂载至NodeContainer
     makeNode(uiContext: UIContext): FrameNode {
   
   
       this.rootNode = new FrameNode(uiContext);
       if (this.rootNode !== null) {
   
   
         this.rootRenderNode = this.rootNode.getRenderNode();
       }
       return this.rootNode;
     }
   
     // 绑定的NodeContainer布局时触发,获取NodeContainer的宽高
     aboutToResize(size: Size): void {
   
   
       if (this.rootRenderNode !== null) {
   
   
         // NodeContainer布局完成后设置rootRenderNode的背景透明
         this.rootRenderNode.backgroundColor = 0X00000000;
         // rootRenderNode的位置从组件NodeContainer的左上角(0,0)坐标开始,大小为NodeContainer的宽高
         this.rootRenderNode.frame = {
   
   
           x: 0,
           y: 0,
           width: size.width,
           height: size.height
         };
       }
     }
   
     // 添加节点
     addNode(node: RenderNode): void {
   
   
       if (this.rootNode === null) {
   
   
         return;
       }
       if (this.rootRenderNode !== null) {
   
   
         this.rootRenderNode.appendChild(node);
       }
     }
   
     // 清空节点
     clearNodes(): void {
   
   
       if (this.rootNode === null) {
   
   
         return;
       }
       if (this.rootRenderNode !== null) {
   
   
         this.rootRenderNode.clearChildren();
       }
     }
   }
  • 创建自定义节点容器组件NodeContainer,接收MyNodeController的实例,组件的宽高为图片加载完成后实际内容区域的宽高,并通过相对容器布局的alignRules使NodeContainer与图片内容区域重叠,控制绘制区域。
   @Builder
   drawingArea() {
   
   
     Image($r('app.media.palette_picture'))
       .width($r('app.string.palette_full_size'))
       .objectFit(ImageFit
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值