---
title: canvas - 画布
---

## Canvas

<div style={{display:'flex',flexWrap:'wrap',alignItems:'center', marginTop: '8px'}}><span style={{fontSize:'0.8125rem',fontWeight:600,marginRight:6,whiteSpace:'nowrap'}}>版本要求:</span><div style={{display:'flex',flexWrap:'wrap',gap:6}}><span style={{display:'inline-flex',alignItems:'center',gap:4,fontSize:'0.8125rem',lineHeight:1,padding:'3px 8px',borderRadius:4,backgroundColor:'rgba(229,231,235,0.6)'}}><span style={{opacity:0.7}}>@ray-js/ray</span><span style={{opacity:0.5}}>&ge;</span><strong>0.5.10</strong></span></div></div>

### 描述

画布组件。

### 使用方法

> 在 Ray 中使用 canvas 进行[混合开发](/cn/miniapp/develop/ray/framework/mixed-development)

- 方法一: 使用 [RJS](/cn/miniapp/develop/ray/framework/render) 进行绘制，可以获取到 canvas 节点，可以绘制图表、动画和各种图形等。

- 方法二: 在逻辑层 js 中配合 [createCanvasContext](/cn/miniapp/develop/miniapp/api/canvas/CanvasContext/createCanvasContext) API 使用，此方法获取不到 canvas node 节点。

```js
import { createCanvasContext } from '@ray-js/ray';

const context = createCanvasContext('***');
```

> 推荐使用方法一 [RJS](/cn/miniapp/develop/ray/framework/render) 进行绘制，性能更好。

### 属性

| 属性             | 类型                               | 必填 | 默认值 | 描述                                                                |
| ---------------- | ---------------------------------- | ---- | ------ | ------------------------------------------------------------------- |
| canvas-id        | string                             | 是   | ""     | canvas 组件的唯一标识符，必须设置该属性                             |
| type             | string                             | 否   | "2d"   | 指定 canvas 类型，有效值值为 2d                                     |
| disable-scroll   | boolean                            | 否   | false  | 当在 canvas 中移动时且有绑定手势事件时，禁止屏幕滚动以及下拉刷新    |
| auto-resize      | boolean                            | 否   | -      | 启动画布自适应尺寸，当布局发生变化会触发 bind:resize 事件           |
| bind:touchstart  | (event: CanvasTouchEvent) => void  | 否   | -      | 手指触摸动作开始                                                    |
| bind:touchmove   | (event: CanvasTouchEvent) => void  | 否   | -      | 手指触摸后移动                                                      |
| bind:touchend    | (event: CanvasTouchEvent) => void  | 否   | -      | 手指触摸动作结束                                                    |
| bind:touchcancel | (event: CanvasTouchEvent) => void  | 否   | -      | 手指触摸动作被打断，如来电提醒，弹窗                                |
| bind:longpress   | (event: CanvasTouchEvent) => void  | 否   | -      | 手指长按 500ms 之后触发，触发了长按事件后进行移动不会触发屏幕的滚动 |
| bind:error       | (event: CanvasErrorEvent) => void  | 否   | -      | 当发生错误时触发 error 事件                                         |
| bind:resize      | (event: CanvasResizeEvent) => void | 否   | -      | 使用 rpx 单位自适应布局时，当屏幕尺寸发生变化，画布尺寸变更时触发   |

### 示例代码

#### 使用 RJS 进行绘制（推荐）

```tsx
// index.tsx
import { usePageEvent, usePageInstance, View } from '@ray-js/ray';
import Render from './index.rjs';
import React from 'react';

export default function () {
  const ctx = usePageInstance();

  usePageEvent('onReady', () => {
    const render = new Render(ctx);
    render.init('pageCanvas2');
  });

  return (
    <View>
      <View style={{ padding: '32rpx' }}>页面中通过 RJS 绘制的 canvas</View>
      <canvas id="pageCanvas2" style={{ width: '350px', height: '250px' }} canvas-id="pageCanvas2"></canvas>
    </View>
  );
}
```

```javascript
// render.rjs
export default Render({
  init(canvasId) {
    getCanvasById(canvasId).then((canvas) => {
      if (canvas) {
        const ctx = canvas.getContext('2d');
        this.canvas = canvas;
        this.ctx = ctx;
        this.width = canvas.width;
        this.height = canvas.height;
        this.drawBackground();
        this.drawCircle();
        this.drawRect();
        this.drawText();
      }
    });
  },

  drawBackground() {
    this.ctx.fillStyle = '#ffffff';
    this.ctx.fillRect(0, 0, this.width, this.height);
  },

  drawCircle() {
    this.ctx.beginPath();
    this.ctx.arc(100, 100, 50, 0, 2 * Math.PI);
    this.ctx.fillStyle = '#ff6b6b';
    this.ctx.fill();
    this.ctx.strokeStyle = '#c92a2a';
    this.ctx.lineWidth = 3;
    this.ctx.stroke();
  },

  drawRect() {
    this.ctx.fillStyle = '#4dabf7';
    this.ctx.fillRect(200, 50, 100, 100);
    this.ctx.strokeStyle = '#1971c2';
    this.ctx.lineWidth = 3;
    this.ctx.strokeRect(200, 50, 100, 100);
  },

  drawText() {
    this.ctx.font = '20px sans-serif';
    this.ctx.fillStyle = '#333';
    this.ctx.fillText('RJS Canvas', 120, 200);
  },
});
```

#### 使用 createCanvasContext API 绘制

```tsx | sandbox previewTitle="使用 createCanvasContext API 绘制"
import React, { useEffect } from 'react';
import { usePageEvent, createCanvasContext, View } from '@ray-js/ray';

export default function () {
  useEffect(() => {
    const context = createCanvasContext('pageCanvas1');
    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();
  }, [])

  return (
    <View>
      <View style={{ padding: '32rpx' }}>页面中直接绘制的 canvas</View>
      <canvas style={{ width: '300px', height: '200px' }} canvas-id="pageCanvas1"></canvas>
    </View>
  );
}
```

### 相关链接

相关 API: [createCanvasContext](/cn/miniapp/develop/miniapp/api/canvas/CanvasContext/createCanvasContext)。

<DemoBlock 
  githubUrl="https://github.com/Tuya-Community/tuya-miniapp-demo/tree/master/rayRjsPlugin" 
  qrCodeUrl="/images/qrCode/rayRjsPlugin.png" 
  lang="zh">
</DemoBlock>
