支付宝小程序画布组件 画布·Canvas
画布。画布是一个矩形区域,用于在页面上绘制图形,开发者可以控制其每一像素。 canvas 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。
相关 API:my.createCanvasContext。
扫码体验
示例代码
<!-- API-DEMO page/component/canvas/canvas.axml -->
<view class="page">
<view class="canvas-view">
<canvas
id="canvas"
width="610"
height="610"
class="canvas"
onTouchStart="log"
onTouchMove="log"
onTouchEnd="log"
/>
</view>
</view>
// API-DEMO page/component/canvas/canvas.js
Page({
onReady() {
this.point = {
x: Math.random() * 590,
y: Math.random() * 590,
dx: Math.random() * 10,
dy: Math.random() * 10,
r: Math.round(Math.random() * 255 | 0),
g: Math.round(Math.random() * 255 | 0),
b: Math.round(Math.random() * 255 | 0),
};
this.interval = setInterval(this.draw.bind(this), 17);
this.ctx = my.createCanvasContext('canvas');
},
draw() {
const { ctx } = this;
ctx.setFillStyle('#FFF');
ctx.fillRect(0, 0, 610, 610);
ctx.beginPath();
ctx.arc(this.point.x, this.point.y, 20, 0, 2 * Math.PI);
ctx.setFillStyle('rgb(' + this.point.r + ', ' + this.point.g + ', ' + this.point.b + ')');
ctx.fill();
ctx.draw();
this.point.x += this.point.dx;
this.point.y += this.point.dy;
if (this.point.x <= 10 || this.point.x >= 590) {
this.point.dx = -this.point.dx;
this.point.r = Math.round(Math.random() * 255 | 0);
this.point.g = Math.round(Math.random() * 255 | 0);
this.point.b = Math.round(Math.random() * 255 | 0);
}
if (this.point.y <= 10 || this.point.y >= 590) {
this.point.dy = -this.point.dy;
this.point.r = Math.round(Math.random() * 255 | 0);
this.point.g = Math.round(Math.random() * 255 | 0);
this.point.b = Math.round(Math.random() * 255 | 0);
}
},
drawBall() {
},
log(e) {
if (e.touches && e.touches[0]) {
console.log(e.type, e.touches[0].x, e.touches[0].y);
} else {
console.log(e.type);
}
},
onUnload() {
clearInterval(this.interval);
},
});
/* API-DEMO page/component/canvas/canvas.acss */
.canvas-view {
display: flex;
justify-content: center;
}
.canvas {
width: 305px;
height: 305px;
background-color: #fff;
}
属性
属性名 | 类型 | 默认值 | 描述 |
---|---|---|---|
id | String | - | 组件唯一标识符。注意:同一页面中的 id 不可重复 |
style | String | - | - |
class | String | - | - |
width | String | 300px | - |
height | String | 225px | - |
disable-scroll | Boolean | false | 禁止屏幕滚动以及下拉刷新。 |
onTap | EventHandle | - | 点击。 |
onTouchStart | EventHandle | - | 触摸动作开始。 |
onTouchMove | EventHandle | - | 触摸后移动。 |
onTouchEnd | EventHandle | - | 触摸动作结束。 |
onTouchCancel | EventHandle | - | 触摸动作被打断,如来电提醒,弹窗。 |
onLongTap | EventHandle | - | 长按 500ms 之后触发,触发了长按事件后进行移动将不会触发屏幕的滚动。 |
注意:
如果需要在高 DPR(devicePixelRatio)下取得更细腻的显示,需要先将 canvas 用属性设置放大,用样式缩小,例如
<!-- getSystemInfoSync().pixelRatio === 2 -->
<canvas width="200" height="200" style="width:100px;height:100px;"/>
原生 Canvas 组件适配
基础库版本 2.6.2 及以上
支付宝版本 10.2.0 及以上
为了提升性能、优化小程序体验,Canvas 组件会逐步切换为原生 Canvas 组件实现。实际使用中若遇到 iOS 平台上覆盖于 Canvas 组件上的 web 元素(后称:覆盖元素)无法收到 UI 事件时,可以进行如下适配,以确保顺利收到 UI 事件:
以下两个步骤缺一不可:
- 当前小程序 app.json 的
window
节点中配置enableComponentOverlayer
为 "YES"
{
"pages":[
"pages/index/index"
],
"window":{
"enableComponentOverlayer":"YES"
}
}
这个配置项用于指示小程序运行时将目标区域内 UI 事件派发给 Canvas 组件
- 为覆盖元素添加
AF-COMPONENT-OVERLAYER
class 属性来指示小程序运行时将 UI 事件派发给覆盖元素,而不传递给后边的 Canvas 组件;若不添加AF-COMPONENT-OVERLAYER
class 属性,则会默认派发给Canvas 组件。
/* declare style for top class in acss */
.top {
z-index: 2;
}
<!-- axml 中为覆盖元素增加 AF-COMPONENT-OVERLAYER class 属性的样例 -->
<view class="page">
<canvas style="width: 100%; height: 500px;"></canvas>
<!-- 假设下面的View需要盖在 canvas 上(即 z-index 层级要比 canvas 高),那么需要在这个 view 上增加class "AF-COMPONENT-OVERLAYER" 这样-->
<view class="top AF-COMPONENT-OVERLAYER" onTap="viewClick" >
</view>
</view>
注意:如果在开发中遇到 Canvas 组件上没有可见的 web 元素覆盖(即:开发视角下无覆盖元素)时也收不到 UI 事件,可以只采用步骤 1 来尝试解决。