HarmonyOS @ohos.graphics.drawing绘制模块中的RenderNode怎么制定坐标绘制图片

在RenderNode节点中添加一个自定义的图片节点,想把图片绘制到容器的中央,无法拿确定中心点坐标,怎么能绘制到中心去呢?

HarmonyOS
16h前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
zbw_apple

可以使用componentUtils获取组件属性自己去计算:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-arkui-componentutils-V5

demo参考:

//index.ets
import { ImageRenderNode, MyNodeController, MyRenderNode } from '../RenderNodeModel';
import inspector from '@ohos.arkui.inspector';
import { image } from '@kit.ImageKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { componentUtils } from '@kit.ArkUI';
const NODE_CONTAINER_ID = 'root';
@Entry
@Component
struct Index {
  private myNodeController: MyNodeController = new MyNodeController();
  private currentNode: MyRenderNode | null = null; // 当前正在绘制的节点
  listener: inspector.ComponentObserver = inspector.createComponentObserver(NODE_CONTAINER_ID)
  aboutToAppear(): void {
    let onLayoutComplete: () => void = async (): Promise<void> => {
      let value = componentUtils.getRectangleById(NODE_CONTAINER_ID)
      console.log('xxxx:' + JSON.stringify(value));
      let valueW = value.size.width;
      let valueH = value.size.height;
      //获取pixelMap
      hilog.error(0x0000, "tag", "组件布局完成")
      let resourceManager = getContext().resourceManager;
      let uint8Array = resourceManager.getRawFileContentSync('ardilla1.png');
      let pixelMap = await image.createImageSource(uint8Array.buffer).createPixelMap();
      pixelMap.getImageInfo().then((imageInfo: image.ImageInfo) => {
        if (imageInfo == undefined) {
          console.error(`Failed to obtain the image pixel map information.`);
        }
        let wit = imageInfo.size.width;
        let hig = imageInfo.size.height;
        console.log(`Succeeded in obtaining the image pixel map information., ${JSON.stringify(wit)}, ${JSON.stringify(hig)}`);
        let imageNode = new ImageRenderNode(pixelMap, valueW / 2 - wit/2, valueH / 2-hig/2)
        imageNode.frame = {
          x: 0,
          y: 0,
          width: this.myNodeController.width,
          height: this.myNodeController.height
        };
        this.myNodeController.rootRenderNode?.appendChild(imageNode)
      })
    }
    this.listener.on('draw', onLayoutComplete)
  }
  build() {
    Column() {
      NodeContainer(this.myNodeController)
        .width('100%')
        .height('100%')
        .id(NODE_CONTAINER_ID)
        .key(NODE_CONTAINER_ID)
        .onTouch((event: TouchEvent) => {
          this.onTouchEvent(event);
        })
    }
    .border({
      width: 1,
      style: BorderStyle.Dashed
    })
    .margin({
      top: 30,
      bottom: 30,
      right: 20,
      left: 20
    })
  }
import { DrawContext, FrameNode, NodeController, RenderNode, Size } from '@kit.ArkUI';
import { common2D, drawing } from '@kit.ArkGraphics2D';
import { image } from '@kit.ImageKit';
export class ImageRenderNode extends RenderNode {
  pixelMap?: image.PixelMap = undefined;
  xLeft: number = 0;
  yTop: number = 0;
  constructor(pixelMap: image.PixelMap, x: number, y: number) {
    super();
    this.pixelMap = pixelMap;
    this.xLeft = x;
    this.yTop = y;
  }
  draw(context: DrawContext) {
    context.canvas.drawImage(this.pixelMap, this.xLeft, this.yTop)
  }
}
/**
 * MyRenderNode类,初始化画笔和绘制路径
 */
export class MyRenderNode extends RenderNode {
  path: drawing.Path = new drawing.Path(); // 新建路径对象,用于绘制手指移动轨迹
  penWidth: number = 10
  isErase: boolean = false;
  rote = 0
  pen_color: common2D.Color = {
    alpha: 255,
    red: 255,
    green: 0,
    blue: 0
  }
  // RenderNode进行绘制时会调用draw方法
  async draw(context: DrawContext): Promise<void> {
    const canvas = context.canvas;
    // 创建一个画笔Pen对象,Pen对象用于形状的边框线绘制
    const pen = new drawing.Pen();
    // 设置画笔开启反走样,可以使得图形的边缘在显示时更平滑
    pen.setAntiAlias(true);
    // 设置画笔的线宽为5px
    pen.setStrokeWidth(this.penWidth);
    pen.setDither(true);
    pen.setColor(this.pen_color)
    // 将Pen画笔设置到canvas中
    canvas.attachPen(pen);
    // 绘制path
    canvas.drawPath(this.path);
    canvas.detachPen();
  }
}
/**
 * NodeController的子类MyNodeController
 */
export class MyNodeController extends NodeController {
  private rootNode: FrameNode | null = null; // 根节点
  rootRenderNode: RenderNode | null = null; // 从NodeController根节点获取的RenderNode,用于添加和删除新创建的MyRenderNode实例
  width: number = 0; // 实例绑定的NodeContainer组件的宽,单位px
  height: number = 0; // 实例绑定的NodeContainer组件的宽,单位px
  // 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 {
    this.width = size.width;
    this.height = size.height;
    // 设置画布底色为白色
    if (this.rootRenderNode !== null) {
      // NodeContainer布局完成后设置rootRenderNode的背景色为白色
      this.rootRenderNode.backgroundColor = 0XFFFFFFFF;
      // rootRenderNode的位置从组件NodeContainer的左上角(0,0)坐标开始,大小为NodeContainer的宽高
      this.rootRenderNode.frame = {
        x: 0,
        y: 0,
        width: this.width,
        height: this.height
      };
    }
  }
}
分享
微博
QQ
微信
回复
15h前
相关问题
HarmonyOS Canvas关于绘制图片问题
400浏览 • 1回复 待解决
画布上绘制图片如何实现?
350浏览 • 1回复 待解决
HarmonyOS 根据圆心坐标绘制圆问题
24浏览 • 1回复 待解决
使用Native、XComponent和EGL绘制图
1005浏览 • 1回复 待解决
使用Drawing实现图形绘制与显示
915浏览 • 1回复 待解决
Polyline组件绘制坐标不准确
1980浏览 • 1回复 待解决
使用Drawing进行2d图像绘制
949浏览 • 1回复 待解决
绘制手动生成线条坐标
746浏览 • 1回复 待解决
canvas怎么绘制资源目录下图片
689浏览 • 1回复 待解决
HarmonyOS 怎么绘制emoji
33浏览 • 1回复 待解决