HarmonyOS RenderNode draw回调里的context.canvas可以保存成图片吗?

我们需要在给定x,y坐标和宽高的区域里绘制text成图片,text有可能超出父组件的宽度

我们是用RenderNode draw回调里的ParagraphBuilder来绘制text,代码如图,绘制完后可以有什么api保存成图片吗

试了一下用componentSnapshot截图组件 只能截取组件可视范围内的部分,超出的部分不能截图

阅读 509
1 个回答

可参考如下demo:

// xxx.ets
@Entry
@Component
struct Page240829100205072 {
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
  private leftText: string = '文字左对齐'
  private centerText: string = '文字居中对齐'
  private rightText: string = '文字右对齐'
  private letterSpacing: number = 10
  private lineX: number = 200

  getTotalWidth(text: string): number {
    let totalWidth = 0
    for (let i = 0; i < text.length; i++) {
      //累计已占用宽度
      if (i === text.length - 1) {
        totalWidth += this.context.measureText(text[i]).width;
      } else {
        totalWidth += this.context.measureText(text[i]).width + this.letterSpacing;
      }
    }
    return totalWidth
  }

  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Canvas(this.context)
        .width('100%')
        .height('100%')
        .backgroundColor('#ffff00')
        .onReady(() => {
          this.context.strokeStyle = '#0000ff'
          this.context.moveTo(this.lineX, 10)
          this.context.lineTo(this.lineX, 160)
          this.context.stroke()

          // 左对齐
          let leftTotalWidth = this.lineX
          this.context.font = '24vp sans-serif'
          for (let i = 0; i < this.leftText.length; i++) {
            this.context.fillText(this.leftText[i], leftTotalWidth, 50);
            //累计已占用宽度
            if (i === this.leftText.length - 1) {
              leftTotalWidth += this.context.measureText(this.leftText[i]).width;
            } else {
              leftTotalWidth += this.context.measureText(this.leftText[i]).width + this.letterSpacing;
            }
          }

          // 居中对齐
          let centerTotalWidth = 0
          centerTotalWidth = this.getTotalWidth(this.centerText)
          centerTotalWidth = this.lineX - centerTotalWidth / 2
          for (let i = 0; i < this.centerText.length; i++) {
            this.context.fillText(this.centerText[i], centerTotalWidth, 90);
            //累计已占用宽度
            if (i === this.centerText.length - 1) {
              centerTotalWidth += this.context.measureText(this.centerText[i]).width;
            } else {
              centerTotalWidth += this.context.measureText(this.centerText[i]).width + this.letterSpacing;
            }
          }

          // 右对齐
          let rightTotalWidth = 0
          rightTotalWidth = this.getTotalWidth(this.rightText)
          rightTotalWidth = this.lineX - rightTotalWidth
          for (let i = 0; i < this.rightText.length; i++) {
            this.context.fillText(this.rightText[i], rightTotalWidth, 130);
            //累计已占用宽度
            if (i === this.rightText.length - 1) {
              rightTotalWidth += this.context.measureText(this.rightText[i]).width;
            } else {
              rightTotalWidth += this.context.measureText(this.rightText[i]).width + this.letterSpacing;
            }
          }
        })
    }
    .width('100%')
    .height('100%')
  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进