ts-components-offscreencanvas.md 9.1 KB
Newer Older
L
limeng 已提交
1 2
#  OffscreenCanvas

L
limeng 已提交
3 4
OffscreenCanvas组件用于自定义绘制图形。

L
limeng 已提交
5
使用[Canvas](ts-components-canvas-canvas.md)组件或[Canvas API](ts-canvasrenderingcontext2d.md)时,渲染、动画和用户交互通常发生在应用程序的主线程上,与画布动画和渲染相关的计算可能会影响应用程序性能。OffscreenCanvas提供了一个可以在屏幕外渲染的画布,这样可以在单独的线程中运行一些任务,从而避免影响应用程序主线程性能。
L
limeng 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

> **说明:** 
>
> 该组件从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。

## 子组件

不支持。

## 接口

OffscreenCanvas(width: number, height: number)

从API version 9开始,该接口支持在ArkTS卡片中使用。

**参数:**

L
limeng 已提交
23 24 25 26
| 参数名 | 参数类型 | 必填 | 默认值 | 参数描述                              |
| ------ | -------- | ---- | ------ | ------------------------------------- |
| width  | number   | 是   | 0      | OffscreenCanvas组件的宽度,单位为vp。 |
| height | number   | 是   | 0      | OffscreenCanvas组件的高度,单位为vp。 |
L
limeng 已提交
27 28 29 30 31 32 33

## 属性

除支持[通用属性](ts-universal-attributes-size.md)外,还支持以下属性:

| 名称   | 类型   | 默认值 | 描述                                                         |
| ------ | ------ | ------ | ------------------------------------------------------------ |
L
limeng 已提交
34 35
| width  | number | 0      | OffscreenCanvas组件的宽度,单位为vp。从API version 9开始,该接口支持在ArkTS卡片中使用。 |
| height | number | 0      | OffscreenCanvas组件的高度,单位为vp。从API version 9开始,该接口支持在ArkTS卡片中使用。 |
L
limeng 已提交
36 37 38 39 40 41 42 43 44 45

### width

```ts
// xxx.ets
@Entry
@Component
struct OffscreenCanvasPage {
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
L
limeng 已提交
46
  private offCanvas: OffscreenCanvas = new OffscreenCanvas(200, 300)
L
limeng 已提交
47 48 49 50 51 52 53

  build() {
    Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Start }) {
      Column() {
        Canvas(this.context)
          .width('100%')
          .height('100%')
L
limeng 已提交
54 55
          .borderWidth(5)
          .borderColor('#00FF00')
L
limeng 已提交
56
          .backgroundColor('#FFFFFF')
L
limeng 已提交
57
          .onReady(() => {
L
liuliu 已提交
58
            let offContext = this.offCanvas.getContext("2d", this.settings)
L
limeng 已提交
59
            offContext.fillStyle = '#CDCDCD'
L
limeng 已提交
60
            offContext.fillRect(0, 0, this.offCanvas.width, 150)
L
liuliu 已提交
61
            let image = this.offCanvas.transferToImageBitmap()
L
limeng 已提交
62 63
            this.context.setTransform(1, 0, 0, 1, 50, 200)
            this.context.transferFromImageBitmap(image)
L
limeng 已提交
64 65 66 67 68 69 70
          })
      }
    }.width('100%').height('100%')
  }
}
```

L
limeng 已提交
71 72
![zh-cn_image_0000001194032666](figures/offscreen_canvas_width.png)

L
limeng 已提交
73 74 75 76 77 78 79 80 81
### height

```ts
// xxx.ets
@Entry
@Component
struct OffscreenCanvasPage {
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
L
limeng 已提交
82
  private offCanvas: OffscreenCanvas = new OffscreenCanvas(200, 300)
L
limeng 已提交
83 84 85 86 87 88 89

  build() {
    Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Start }) {
      Column() {
        Canvas(this.context)
          .width('100%')
          .height('100%')
L
limeng 已提交
90 91
          .borderWidth(5)
          .borderColor('#00FF00')
L
limeng 已提交
92
          .backgroundColor('#FFFFFF')
L
limeng 已提交
93
          .onReady(() => {
L
liuliu 已提交
94
            let offContext = this.offCanvas.getContext("2d", this.settings)
L
limeng 已提交
95
            offContext.fillStyle = '#CDCDCD'
L
limeng 已提交
96
            offContext.fillRect(0, 0, 100, this.offCanvas.height)
L
liuliu 已提交
97
            let image = this.offCanvas.transferToImageBitmap()
L
limeng 已提交
98 99
            this.context.setTransform(1, 0, 0, 1, 50, 200)
            this.context.transferFromImageBitmap(image)
L
limeng 已提交
100 101 102 103 104 105 106
          })
      }
    }.width('100%').height('100%')
  }
}
```

L
limeng 已提交
107 108
![zh-cn_image_0000001194032666](figures/offscreen_canvas_height.png)

L
limeng 已提交
109 110 111 112 113 114
## 方法

### transferToImageBitmap

transferToImageBitmap(): ImageBitmap

L
limeng 已提交
115
从OffscreenCanvas组件中最近渲染的图像创建一个ImageBitmap对象。
L
limeng 已提交
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133

从API version 9开始,该接口支持在ArkTS卡片中使用。

**返回值:**

| 类型                                               | 描述                    |
| -------------------------------------------------- | ----------------------- |
| [ImageBitmap](ts-components-canvas-imagebitmap.md) | 创建的ImageBitmap对象。 |

**示例:**

```ts
// xxx.ets
@Entry
@Component
struct OffscreenCanvasPage {
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
L
limeng 已提交
134
  private offCanvas: OffscreenCanvas = new OffscreenCanvas(300, 500)
L
limeng 已提交
135 136 137 138 139 140

  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Canvas(this.context)
        .width('100%')
        .height('100%')
L
limeng 已提交
141
        .borderWidth(5)
L
limeng 已提交
142
        .borderColor('#00FF00')
L
limeng 已提交
143
        .backgroundColor('#FFFFFF')
L
limeng 已提交
144
        .onReady(() => {
L
liuliu 已提交
145
          let offContext = this.offCanvas.getContext("2d", this.settings)
L
limeng 已提交
146 147 148 149
          offContext.fillStyle = '#CDCDCD'
          offContext.fillRect(0, 0, 300, 500)
          offContext.fillStyle = '#000000'
          offContext.font = '70px serif bold'
L
limeng 已提交
150
          offContext.fillText("Offscreen : Hello World!", 20, 60)
L
liuliu 已提交
151
          let image = this.offCanvas.transferToImageBitmap()
L
limeng 已提交
152
          this.context.transferFromImageBitmap(image)
L
limeng 已提交
153 154 155 156 157 158 159
        })
    }
    .width('100%')
    .height('100%')
  }
}
```
L
limeng 已提交
160 161 162

![zh-cn_image_0000001194032666](figures/offscreen_canvas_transferToImageBitmap.png)

L
limeng 已提交
163 164 165 166
### getContext<sup>10+</sup>

getContext(contextType: "2d", option?: RenderingContextSettings): OffscreenCanvasRenderingContext2D

L
limeng 已提交
167
返回OffscreenCanvas组件的绘图上下文。
L
limeng 已提交
168 169 170 171 172

**参数:**

| 参数        | 类型                                                         | 必填 | 默认值 | 说明                                                         |
| ----------- | ------------------------------------------------------------ | ---- | ------ | ------------------------------------------------------------ |
L
limeng 已提交
173
| contextType | string                                                       | 是   | "2d"   | OffscreenCanvas组件绘图上下文的类型,当前仅支持"2d"类型。                       |
L
limeng 已提交
174 175 176 177
| option      | [RenderingContextSettings](ts-canvasrenderingcontext2d.md#renderingcontextsettings) | 否   | -      | 见[RenderingContextSettings](ts-canvasrenderingcontext2d.md#renderingcontextsettings)。 |

**返回值:**

L
limeng 已提交
178 179
| 类型                                                         | 描述                              |
| ------------------------------------------------------------ | --------------------------------- |
L
limeng 已提交
180
| [OffscreenCanvasRenderingContext2D](ts-offscreencanvasrenderingcontext2d.md) | OffscreenCanvas组件的绘图上下文。如果getContext方法的入参contextType为"2d"以外类型(包括null或者undefined),返回null。 |
L
limeng 已提交
181 182 183 184 185 186 187 188 189

**示例:**

```ts
@Entry
@Component
struct OffscreenCanvasExamplePage {
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
L
limeng 已提交
190
  private offscreenCanvas: OffscreenCanvas = new OffscreenCanvas(600, 800)
L
limeng 已提交
191 192 193 194 195 196 197 198 199

  build() {
    Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Start, justifyContent: FlexAlign.Start }) {
      Column() {
        Canvas(this.context)
          .width('100%')
          .height('100%')
          .backgroundColor('#FFFFFF')
          .onReady(() => {
L
liuliu 已提交
200
            let offContext = this.offscreenCanvas.getContext("2d", this.settings)
L
limeng 已提交
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
            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)
L
liuliu 已提交
220
            let imageData = this.offscreenCanvas.transferToImageBitmap()
L
limeng 已提交
221 222 223 224 225 226 227 228 229 230
            this.context.transferFromImageBitmap(imageData)
          })
      }.width('100%').height('100%')
    }
    .width('100%')
    .height('100%')
  }
}
```

L
limeng 已提交
231
![zh-cn_image_0000001194032666](figures/offscreen_canvas.png)
L
limeng 已提交
232