harmony 鸿蒙OffscreenCanvas

  • 2025-06-12
  • 浏览 (3)

OffscreenCanvas

OffscreenCanvas provides an offscreen canvas for drawing.

When using Canvas or Canvas API, rendering, animations, and user interactions generally occur on the main thread of an application. The computation relating to canvas animations and rendering may affect application performance. OffscreenCanvas allows for rendering off the screen. This means that some tasks can be run in a separate thread to reduce the load on the main thread.

NOTE

The APIs of this module are supported since API version 8. Updates will be marked with a superscript to indicate their earliest API version.

Child Components

Not supported

APIs

OffscreenCanvas(width: number, height: number, unit?: LengthMetricsUnit)

Widget capability: This API can be used in ArkTS widgets since API version 9.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Name Type Mandatory Description
width number Yes Width of the offscreen canvas.
Default unit: vp
height number Yes Height of the offscreen canvas.
Default unit: vp
unit12+ LengthMetricsUnit No Unit mode of the OffscreenCanvas object. The value cannot be dynamically changed once set. The configuration method is the same as that of CanvasRenderingContext2D.
Default value: DEFAULT

Attributes

Widget capability: This API can be used in ArkTS widgets since API version 9.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

The following attributes are supported.

Name Type Read Only Optional Description
width number No No Width of the offscreen canvas.
Default unit: vp
height number No No Height of the offscreen canvas.
Default unit: vp

width

// xxx.ets
@Entry
@Component
struct OffscreenCanvasPage {
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
  private offCanvas: OffscreenCanvas = new OffscreenCanvas(200, 300)

  build() {
    Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Start }) {
      Column() {
        Canvas(this.context)
          .width('100%')
          .height('100%')
          .borderWidth(5)
          .borderColor('#057D02')
          .backgroundColor('#FFFFFF')
          .onReady(() => {
            let offContext = this.offCanvas.getContext("2d", this.settings)
            offContext.fillStyle = '#CDCDCD'
            offContext.fillRect(0, 0, this.offCanvas.width, 150)
            let image = this.offCanvas.transferToImageBitmap()
            this.context.setTransform(1, 0, 0, 1, 50, 200)
            this.context.transferFromImageBitmap(image)
          })
      }
    }.width('100%').height('100%')
  }
}

en-us_image_0000001194032666

height

// xxx.ets
@Entry
@Component
struct OffscreenCanvasPage {
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
  private offCanvas: OffscreenCanvas = new OffscreenCanvas(200, 300)

  build() {
    Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Start }) {
      Column() {
        Canvas(this.context)
          .width('100%')
          .height('100%')
          .borderWidth(5)
          .borderColor('#057D02')
          .backgroundColor('#FFFFFF')
          .onReady(() => {
            let offContext = this.offCanvas.getContext("2d", this.settings)
            offContext.fillStyle = '#CDCDCD'
            offContext.fillRect(0, 0, 100, this.offCanvas.height)
            let image = this.offCanvas.transferToImageBitmap()
            this.context.setTransform(1, 0, 0, 1, 50, 200)
            this.context.transferFromImageBitmap(image)
          })
      }
    }.width('100%').height('100%')
  }
}

en-us_image_0000001194032666

Methods

transferToImageBitmap

transferToImageBitmap(): ImageBitmap

Creates an ImageBitmap object from the most recently rendered image of the offscreen canvas.

Widget capability: This API can be used in ArkTS widgets since API version 9.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Return value

Type Description
ImageBitmap ImageBitmap object created.

Example

// xxx.ets
@Entry
@Component
struct OffscreenCanvasPage {
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
  private offCanvas: OffscreenCanvas = new OffscreenCanvas(300, 500)

  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Canvas(this.context)
        .width('100%')
        .height('100%')
        .borderWidth(5)
        .borderColor('#057D02')
        .backgroundColor('#FFFFFF')
        .onReady(() => {
          let offContext = this.offCanvas.getContext("2d", this.settings)
          offContext.fillStyle = '#CDCDCD'
          offContext.fillRect(0, 0, 300, 500)
          offContext.fillStyle = '#000000'
          offContext.font = '70px serif bold'
          offContext.fillText("Offscreen : Hello World!", 20, 60)
          let image = this.offCanvas.transferToImageBitmap()
          this.context.transferFromImageBitmap(image)
        })
    }
    .width('100%')
    .height('100%')
  }
}

en-us_image_0000001194032666

getContext10+

getContext(contextType: “2d”, options?: RenderingContextSettings): OffscreenCanvasRenderingContext2D

Obtains the drawing context of the offscreen canvas.

Atomic service API: This API can be used in atomic services since API version 11.

System capability: SystemCapability.ArkUI.ArkUI.Full

Parameters

Name Type Mandatory Description
contextType string Yes Type of the drawing context of the offscreen canvas. The value can only be “2d”.
options RenderingContextSettings No Parameters of the OffscreenCanvasRenderingContext2D object. For details, see RenderingContextSettings.
Default value: null

Return value

Type Description
OffscreenCanvasRenderingContext2D Drawing context of the offscreen canvas. If contextType in getContext is set to a value other than “2d” (including null and undefined), null is returned.

Example

@Entry
@Component
struct OffscreenCanvasExamplePage {
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
  private offscreenCanvas: OffscreenCanvas = new OffscreenCanvas(600, 800)

  build() {
    Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Start }) {
      Column() {
        Canvas(this.context)
          .width('100%')
          .height('100%')
          .backgroundColor('#FFFFFF')
          .onReady(() => {
            let offContext = this.offscreenCanvas.getContext("2d", this.settings)
            offContext.font = '70px sans-serif'
            offContext.fillText("Offscreen : Hello World!", 20, 60)
            offContext.fillStyle = "#0000ff"
            offContext.fillRect(230, 350, 50, 50)
            offContext.fillStyle = "#EE0077"
            offContext.translate(70, 70)
            offContext.fillRect(230, 350, 50, 50)
            offContext.fillStyle = "#77EE0077"
            offContext.translate(-70, -70)
            offContext.fillStyle = "#00ffff"
            offContext.rotate(45 * Math.PI / 180);
            offContext.fillRect(180, 120, 50, 50);
            offContext.rotate(-45 * Math.PI / 180);
            offContext.beginPath()
            offContext.moveTo(10, 150)
            offContext.bezierCurveTo(20, 100, 200, 100, 200, 20)
            offContext.stroke()
            offContext.fillStyle = '#FF00FF'
            offContext.fillRect(100, 100, 60, 60)
            let imageData = this.offscreenCanvas.transferToImageBitmap()
            this.context.transferFromImageBitmap(imageData)
          })
      }.width('100%').height('100%')
    }
    .width('100%')
    .height('100%')
  }
}

en-us_image_0000001194032666

Concurrent Thread Drawing

Since API version 11, an application can call postMessage to pass an OffscreenCanvas instance to a worker thread for drawing, and call onmessage to receive the drawing result for display.

NOTE

After the OffscreenCanvas instance uses getContext to obtain the drawing context, it cannot be passed to other threads through postMessage. Otherwise, an exception is thrown.

After an OffscreenCanvas object is passed to a thread through postMessage, it cannot use the getContext or transferToImageBitmap APIs. Otherwise, an exception is thrown.

After an OffscreenCanvas object is passed to a thread through postMessage, it cannot be passed to any other thread through postMessage. Otherwise, an exception is thrown.

The content drawn in the Worker thread cannot be previewed in DevEco Studio Previewer.

Example

import { worker } from '@kit.ArkTS';

@Entry
@Component
struct OffscreenCanvasExamplePage {
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
  private myWorker = new worker.ThreadWorker('entry/ets/workers/Worker.ts');

  build() {
    Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Start }) {
      Column() {
        Canvas(this.context)
          .width('100%')
          .height('100%')
          .borderWidth(5)
          .borderColor('#057D02')
          .backgroundColor('#FFFFFF')
          .onReady(() => {
            let offCanvas = new OffscreenCanvas(600, 800)
            this.myWorker.postMessage({ myOffCanvas: offCanvas });
            this.myWorker.onmessage = (e): void => {
              if (e.data.myImage) {
                let image: ImageBitmap = e.data.myImage
                this.context.transferFromImageBitmap(image)
              }
            }
            
          })
      }.width('100%').height('100%')
    }
    .width('100%')
    .height('100%')
  }
}

After the main thread sends the OffscreenCanvas instance through postMessage, the worker thread can receive it in onmessage for display.

workerPort.onmessage = (e: MessageEvents) => {
  if (e.data.myOffCanvas) {
    let offCanvas: OffscreenCanvas = e.data.myOffCanvas
    let offContext = offCanvas.getContext("2d")
    offContext.fillStyle = '#CDCDCD'
    offContext.fillRect(0, 0, 200, 150)
    let image = offCanvas.transferToImageBitmap()
    workerPort.postMessage({ myImage: image });
  }
}

en-us_image_0000001194032666

你可能感兴趣的鸿蒙文章

harmony 鸿蒙ArcButton

harmony 鸿蒙ArcSlider

harmony 鸿蒙Chip

harmony 鸿蒙ChipGroup

harmony 鸿蒙ComposeListItem

harmony 鸿蒙ComposeTitleBar

harmony 鸿蒙advanced.Counter

harmony 鸿蒙Dialog Box (Dialog)

harmony 鸿蒙DialogV2

harmony 鸿蒙DownloadFileButton

0  赞