@antv/f-my
Version:
FEngine for alipay mini-program
204 lines • 6.35 kB
JavaScript
import { Canvas } from '@antv/f-engine';
function convertTouches(touches) {
if (!touches) return touches;
touches.forEach(function (touch) {
touch.clientX = touch.x;
touch.clientY = touch.y;
});
return touches;
}
function dispatchEvent(el, event, type) {
if (!el || !event) return;
if (!event.preventDefault) {
event.preventDefault = function () {};
}
event.type = type;
event.target = el;
var touches = event.touches,
changedTouches = event.changedTouches,
detail = event.detail;
event.touches = convertTouches(touches);
event.changedTouches = convertTouches(changedTouches);
if (detail) {
event.clientX = detail.x;
event.clientY = detail.y;
}
el.dispatchEvent(event);
}
var getPixelRatio = function getPixelRatio() {
return my.getSystemInfoSync().pixelRatio;
};
// 判断是否是新版 canvas 所支持的调用方法(AppX 2.7.0 及以上)
var isAppX2CanvasEnv = function isAppX2CanvasEnv() {
return my.canIUse('canvas.onReady') && my.canIUse('createSelectorQuery.return.node');
};
Component({
props: {
onRender: function onRender(_props) {},
// width height 会作为元素兜底的宽高使用
width: null,
height: null,
onError: function onError() {},
onCanvasReady: function onCanvasReady() {},
onCanvasRender: function onCanvasRender() {},
type: '2d' // canvas 2d, 基础库 2.7 以上支持
},
/**
* 组件创建时触发
* 注意:
* 使用该生命周期,项目配置需启用:"component2": true
*/
onInit: function onInit() {
this.setCanvasId();
},
didMount: function didMount() {
if (!isAppX2CanvasEnv()) {
console.error('当前基础库版本过低,请升级基础库版本到 2.7.0 或以上。');
}
// 为了兼容未配置 "component2": true 的情况
if (!this.data.id) {
this.setCanvasId();
}
},
didUpdate: function didUpdate() {
var _this = this;
var _a = this,
canvas = _a.canvas,
props = _a.props;
if (!canvas) return;
var theme = props.theme,
px2hd = props.px2hd;
var children = props.onRender(props);
var updateProps = {
theme: theme,
px2hd: px2hd,
children: children
};
canvas.update(updateProps).catch(function (error) {
_this.catchError(error);
});
},
didUnmount: function didUnmount() {
var canvas = this.canvas;
if (!canvas) return;
canvas.destroy();
},
methods: {
setCanvasId: function setCanvasId() {
var pageId = this.$page && this.$page.$id || 0;
var id = "f-canvas-".concat(pageId, "-").concat(this.$id);
this.setData({
id: id
});
},
onCanvasReady: function onCanvasReady() {
var _this = this;
var onCanvasReady = this.props.onCanvasReady;
onCanvasReady && onCanvasReady();
var id = this.data.id;
var query = my.createSelectorQuery();
query.select("#".concat(id))
// @ts-ignore
.node().exec(function (res) {
if (!res[0]) {
return;
}
var canvas = res[0].node;
if (!canvas) {
_this.catchError('获取canvas失败');
return;
}
var width = canvas.width,
height = canvas.height;
var pixelRatio = Math.ceil(getPixelRatio());
// 高清解决方案
_this.setData({
width: width * pixelRatio,
height: height * pixelRatio
}, function () {
var context = canvas.getContext('2d');
var fCanvas = _this.createCanvas({
width: width,
height: height,
pixelRatio: pixelRatio,
context: context,
createImage: canvas.createImage.bind(canvas),
requestAnimationFrame: canvas.requestAnimationFrame.bind(canvas),
cancelAnimationFrame: canvas.cancelAnimationFrame.bind(canvas)
});
fCanvas.render().catch(function (error) {
_this.catchError(error);
});
});
});
},
catchError: function catchError(error) {
console.error('图表渲染失败: ', error);
var onError = this.props.onError;
if (typeof onError === 'function') {
onError(error);
}
throw error;
},
createCanvas: function createCanvas(_a) {
var _b, _c;
var width = _a.width,
height = _a.height,
pixelRatio = _a.pixelRatio,
context = _a.context,
createImage = _a.createImage,
requestAnimationFrame = _a.requestAnimationFrame,
cancelAnimationFrame = _a.cancelAnimationFrame;
if (!width || !height) {
return;
}
var _d = this.props,
theme = _d.theme,
px2hd = _d.px2hd,
onCanvasRender = _d.onCanvasRender;
var children = this.props.onRender(this.props);
var canvas = new Canvas({
pixelRatio: pixelRatio,
width: width,
height: height,
theme: theme,
px2hd: px2hd,
context: context,
children: children,
createImage: createImage,
requestAnimationFrame: requestAnimationFrame,
cancelAnimationFrame: cancelAnimationFrame,
onRender: onCanvasRender,
// @ts-ignore
offscreenCanvas: my.createOffscreenCanvas(),
// useNativeClickEvent: false,
isTouchEvent: function isTouchEvent(e) {
return e.type.startsWith('touch');
},
isMouseEvent: function isMouseEvent(e) {
return e.type.startsWith('mouse');
}
});
this.canvas = canvas;
// @ts-ignore
if ((_c = (_b = canvas.canvas) === null || _b === void 0 ? void 0 : _b.context) === null || _c === void 0 ? void 0 : _c.config) {
// @ts-ignore g里面caf透传不了,暂时解决
canvas.canvas.context.config.cancelAnimationFrame = cancelAnimationFrame;
}
this.canvasEl = canvas.getCanvasEl();
return canvas;
},
click: function click(e) {
dispatchEvent(this.canvasEl, e, 'click');
},
touchStart: function touchStart(e) {
dispatchEvent(this.canvasEl, e, 'touchstart');
},
touchMove: function touchMove(e) {
dispatchEvent(this.canvasEl, e, 'touchmove');
},
touchEnd: function touchEnd(e) {
dispatchEvent(this.canvasEl, e, 'touchend');
}
}
});