# canvas

画布组件。该组件是[原生组件](native-component.html)，使用时请注意相关限制

相关 api：[qa.createCanvasContext](../api/canvas/qa.createCanvasContext.html)。

| 属性 | 类型 | <div style="width: 50px">默认值 </div> | <div style="width: 50px">必填 </div> | 说明 |
| --- | --- | --- | --- | --- |
| type | string |  | 否 | 指定 canvas 类型，当前仅支持 2d |
| canvas-id | string |  | 否 | canvas 组件的唯一标识符 |
| disable-scroll | boolean | false | 否 | 当在 canvas 中移动时且有绑定手势事件时，禁止屏幕滚动以及下拉刷新 |
| bindtouchstart | eventhandle |  | 否 | 手指触摸动作开始 |
| bindtouchmove | eventhandle |  | 否 | 手指触摸后移动 |
| bindtouchend | eventhandle |  | 否 | 手指触摸动作结束 |
| bindtouchcancel | eventhandle |  | 否 | 手指触摸动作被打断，如来电提醒，弹窗 |
| bindlongtap | eventhandle |  | 否 | 手指长按 500ms 之后触发，触发了长按事件后进行移动不会触发屏幕的滚动 |
| binderror | eventhandle |  | 否 | 当发生错误时触发 error 事件，detail = {errMsg} |

## Bug & Tip

::: warning

- canvas 标签默认宽度 300px、高度 150px
- 同一页面中的 canvas-id 不可重复，如果使用一个已经出现过的 canvas-id，该 canvas 标签对应的画布将被隐藏并不再正常工作
- 请注意[原生组件使用限制](./native-component.html#原生组件的使用限制)
- 当前暂不支持存在多个 canvas 实例

:::

::: danger

- 避免设置过大的宽高，会有 crash 的问题

:::

## 示例代码

```html
<!-- canvas.qxml -->
<canvas style="width: 300px; height: 200px;" canvas-id="firstCanvas"></canvas>
<!-- 当使用绝对定位时，文档流后边的 canvas 的显示层级高于前边的 canvas -->
<canvas style="width: 400px; height: 500px;" canvas-id="secondCanvas"></canvas>
<!-- 因为 canvas-id 与前一个 canvas 重复，该 canvas 不会显示，并会发送一个错误事件到 AppService -->
<canvas style="width: 400px; height: 500px;" canvas-id="secondCanvas" binderror="canvasIdErrorCallback"></canvas>
```

```js
Page({
  canvasIdErrorCallback: function(e) {
    console.error(e.detail.errMsg)
  },
  onReady: function(e) {
    // 使用 qa.createContext 获取绘图上下文 context
    var context = qa.createCanvasContext('firstCanvas')

    context.setStrokeStyle('#00ff00')
    context.setLineWidth(5)
    context.rect(0, 0, 200, 200)
    context.stroke()
    context.setStrokeStyle('#ff0000')
    context.setLineWidth(2)
    context.moveTo(160, 100)
    context.arc(100, 100, 60, 0, 2 * Math.PI, true)
    context.moveTo(140, 100)
    context.arc(100, 100, 40, 0, Math.PI, false)
    context.moveTo(85, 80)
    context.arc(80, 80, 5, 0, 2 * Math.PI, true)
    context.moveTo(125, 80)
    context.arc(120, 80, 5, 0, 2 * Math.PI, true)
    context.stroke()
    context.draw()
  }
})
```
