跳到主要内容

Canvas

WdCanvas

基础能力说明

  1. canvas 的基础属性提供了 2d 和 webgl 两种类型供选择
  2. 不同 canvas 类型下,各提供一套示例模板供用户参考

拓展场景说明

示例:如何设置页面水印

预期效果如下:

配置方法一

添加一个 canvas 组件,默认渲染为 2D 水印效果,初始化代码中打开相关注释代码,即可实现。

配置方法二

添加一个 canvas 组件,通过 canvas 渲染完成事件绑定 js 方法实现,js 方法可参考

export default function({event, data}) {
//获取canvas实例
const canvas = $w.wdCanvas2.canvasInstance;
//获取canvas上下文
const ctx = $w.wdCanvas2.canvasCtx;
if (ctx && canvas && $w.wdCanvas2?.type === '2d') {
// web端使用fixed可不占用空间,实现与其他元素重叠
canvas.style.position = 'fixed';
canvas.style.top = '0';
canvas.style.left = '0';
canvas.style.zIndex = 1;
canvas.style.pointerEvents = 'none';

/** web端使用window.innerWidth和window.innerHeight可以让水印铺满全屏 */
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.font = '24px Arial';
ctx.setFillStyle('rgba(0, 0, 0, 0.1)');
ctx.setTextAlign('center');
ctx.setTextBaseline('middle');
ctx.rotate(Math.PI / 180 * 45);

for (let x = 0; x < canvas.width * 2; x += 140) {
for (let y = -canvas.height; y < canvas.height; y += 100) {
ctx.fillText('我是水印', x, y);
}
}
ctx.draw(true);
}
}

说明:canvas 组件是基于标准 Web 和小程序端 canvas API 实现的,因此您可以使用标准的 API 来操作 canvas 组件。其中平台支持通过$w.组件 id.canvasInstance、w.组件 id.canvasCtx 分别获得 canvas 实例和 canvas 上下文。

注意:由于 Web 端和小程序间的平台差异,某些 API 可能需要进行适配。在使用这些 API 时,请确保遵循各自平台的最佳实践。

应用场景说明

手写签名

说明:在 canvas 的应用中,手写签名是一个比较普遍的使用场景,通过 canvas 组件实现三端兼容的手写签名功能,需要进行如下操作`

定义 canvas 所在页面的变量和函数
名称类型默认值含义
canvasRectObject{}保存触摸/点击时 canvas 的元素信息(top、left、clientX、clientY 等)
isMouseDownBooleanfalse是否已经触摸或鼠标已经按下
canvasClearFunction见下面说明清空 canvas 画布
canvasReadyFunction见下面说明canvas 渲染完成时初始化画布
canvasSaveFunction见下面说明将 canvas 画布内容转为图片
mousedownFunction见下面说明手指触摸开始或鼠标按下
mousemoveFunction见下面说明手指触摸移动或鼠标移动
mouseupFunction见下面说明手指触摸结束或鼠标抬起
  1. canvasClear 函数
export default function ({ event, data }) {
$w.canvas1.canvasCtx.clearRect(
0,
0,
$w.canvas1.canvasInstance.width,
$w.canvas1.canvasInstance.height
);

$w.canvas1.canvasCtx.setFillStyle('white');
$w.canvas1.canvasCtx.fillRect(
0,
0,
$w.canvas1.canvasInstance.width,
$w.canvas1.canvasInstance.height
);
$w.canvas1.canvasCtx.draw();
}
  1. canvasReady 函数
export default function ({ event, data }) {
$w.canvas1.canvasCtx.setFillStyle('white');
$w.canvas1.canvasCtx.fillRect(
0,
0,
$w.canvas1.canvasInstance.width,
$w.canvas1.canvasInstance.height
);
$w.canvas1.canvasCtx.draw();

if (!$w.wedaContext.platforms.includes('MP')) return;
const { pixelRatio: dpr } = wx.getSystemInfoSync() || {};

if (!dpr) return;
$w.canvas1.canvasCtx.scale(dpr, dpr);
}
  1. canvasSave 函数
export default function ({ event, data }) {
if ($w.wedaContext.platforms.includes('MP')) {
$w.canvas1.canvasCtx.draw(
true,
wx.canvasToTempFilePath({
quality: 1,
canvas: $w.canvas1.canvasInstance,
async success(res) {
console.log('image: ', res.tempFilePath);
$w.utils.showToast({ title: '图片生成成功' });
// 如果需要云存储,则可以执行下面的代码,文件存储详见https://docs.cloudbase.net/api-reference/webv2/storage#uploadfile
// const cloud = await $w.cloud.getCloudInstance();
// const upload = await cloud.uploadFile({
// cloudPath: 'test.png',
// filePath: res.tempFilePath,
// })
},
fail: (e) => {
console.log('fail', e);
$w.utils.showToast({ title: `图片生成失败: ${e}` });
},
})
);
} else {
try {
const dataUrl = $w.canvas1.canvasInstance.toDataURL();
console.log('image: ', dataUrl);
$w.utils.showToast({ title: '图片生成成功' });
} catch (e) {
console.log('fail', e);
$w.utils.showToast({ title: `图片生成失败: ${e}` });
}
}
}
  1. mousedown 函数
export default async function ({ event, data }) {
event.detail?.e?.preventDefault?.();
const touches =
event.changedTouches?.[0] ||
event.detail?.e?.changedTouches?.[0] ||
event.detail?.e ||
{};
const { clientX, clientY } = touches;
const { left, top } = await $w.canvas1.canvasInstance.getCanvasRectInfo();
$page.dataset.state.canvasRect = { left, top };
const x = clientX - left;
const y = clientY - top;

$w.page.dataset.state.isMouseDown = true;
$w.canvas1.canvasCtx.beginPath();
$w.canvas1.canvasCtx.moveTo(x, y);
}
  1. mousemove 函数
export default function ({ event, data }) {
if ($w.page.dataset.state.isMouseDown) {
event.detail?.e?.preventDefault?.();
const touches =
event.changedTouches?.[0] ||
event.detail?.e?.changedTouches?.[0] ||
event.detail?.e ||
{};
const { clientX, clientY } = touches;
const { left, top } = $page.dataset.state.canvasRect;
const x = clientX - left;
const y = clientY - top;

$w.canvas1.canvasCtx.lineTo(x, y);
$w.canvas1.canvasCtx.stroke();
}
}
  1. mouseup 函数
export default function ({ event, data }) {
$w.page.dataset.state.isMouseDown = false;
$w.canvas1.canvasCtx.closePath();
}
绑定 canvas 事件

属性说明

组件接收的外部传入的属性

属性名
属性标识
类型
说明
Canvas类型typestring

指定Canvas类型

示例:"2d"

模板templatestring

指定Canvas模板

示例:"2d"

函数codeobject
禁止屏幕滚动及下拉刷新disableScrollboolean

当在 Canvas 中移动时且有绑定手势事件时,禁止屏幕滚动以及下拉刷新

示例:false

事件说明

组件暴露的事件,可以监听组件的事件来触发一些外部的动作

事件名
事件code
事件出参 event.detail
适用情况
说明
canvas渲染完成canvasReadyobject
  • canvasInstance: object Canvas实例

    获取 canvas 元素的引用

    • canvasCtx: object Canvas上下文

      getContext() 方法返回的对象,该对象提供了用于在画布上绘图的方法和属性

      移动端,PC端,小程序

      用户选中的数据发生改变时触发,出参所选节点数据

      点击clickobject
      • e: Event 对象
      PC端

      -

      双击dblclickobject
      • e: Event 对象
      PC端

      -

      手指/鼠标长按longtap移动端,PC端,小程序

      手指/鼠标长按 500ms 之后触发,触发了长按事件后进行移动不会触发屏幕的滚动

      手指触摸开始touchstart移动端,小程序

      手指触摸动作开始

      手指触摸结束touchend移动端,小程序

      手指触摸动作结束

      手指触摸移动touchmove移动端,小程序

      手指触摸后移动

      手指触摸被打断touchcancel小程序

      手指触摸动作被打断,如来电提醒,弹窗

      鼠标按下mousedownobject
      • e: Event 对象
      PC端

      -

      鼠标抬起mouseupobject
      • e: Event 对象
      PC端

      -

      鼠标移动mousemoveobject
      • e: Event 对象
      PC端

      -

      错误error移动端,PC端,小程序

      当发生错误时触发 error 事件

      属性 API

      通过属性 API,可以获取组件内部的状态和属性值,可以通过$w.componentId.propertyName 来访问组件内部的值,如 $w.input1.value ,详请请参考 属性 API

      只读属性名
      属性标识
      类型
      说明
      Canvas类型typestring

      指定Canvas类型

      函数codeobject
      禁止屏幕滚动及下拉刷新disableScrollboolean

      当在 Canvas 中移动时且有绑定手势事件时,禁止屏幕滚动以及下拉刷新

      Canvas实例canvasInstanceobject

      获取 canvas 元素的引用

      Canvas上下文canvasCtxobject

      getContext() 方法返回的对象,该对象提供了用于在画布上绘图的方法和属性

      方法 API

      样式 API

      通过样式 API,可以覆盖组件中内部元素的样式来实现自定义,例如在低代码编辑器中中通过 #wd-page-root .wd-btn 即可为所有的按钮组件编写样式,通过 :scope 可以控制单个组件样式, 详细说明请参考样式 API

      名称
      类名
      说明和示例
      根元素.wd-canvascanvas组件根元素
      /* :scope 指的是当前组件元素 */
      /* 具体可参考样式 API 文档 */
      :scope.wd-canvas {
        /* 在这里编写CSS 样式 */
      }
      PC 端canvas组件根元素.wd-pc-canvas可以为 PC 端的canvas编写样式
      /* :scope 指的是当前组件元素 */
      /* 具体可参考样式 API 文档 */
      :scope.wd-pc-canvas {
        /* 在这里编写CSS 样式 */
      }
      H5 端canvas组件根元素.wd-h5-canvas可以为 H5 端的canvas编写样式
      /* :scope 指的是当前组件元素 */
      /* 具体可参考样式 API 文档 */
      :scope.wd-h5-canvas {
        /* 在这里编写CSS 样式 */
      }
      小程序canvas端组件根元素.wd-mp-canvas可以为小程序端的canvas编写样式
      /* :scope 指的是当前组件元素 */
      /* 具体可参考样式 API 文档 */
      :scope.wd-mp-canvas {
        /* 在这里编写CSS 样式 */
      }

      了解样式 API