UNPKG

@antv/g-mobile-canvas

Version:

A renderer implemented with Canvas2D API in mobile environment

320 lines (305 loc) 10.5 kB
/*! * @antv/g-mobile-canvas * @description A renderer implemented with Canvas2D API in mobile environment * @version 1.1.1 * @date 12/24/2025, 11:57:27 AM * @author AntVis * @docs https://g.antv.antgroup.com/ */ 'use strict'; var _createClass = require('@babel/runtime/helpers/createClass'); var _classCallCheck = require('@babel/runtime/helpers/classCallCheck'); var _callSuper = require('@babel/runtime/helpers/callSuper'); var _inherits = require('@babel/runtime/helpers/inherits'); var gLite = require('@antv/g-lite'); var gCanvas = require('@antv/g-canvas'); var DragDropEvent = require('@antv/g-plugin-dragndrop'); var GesturePlugin = require('@antv/g-plugin-gesture'); var util = require('@antv/util'); var _regeneratorRuntime = require('@babel/runtime/helpers/regeneratorRuntime'); var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator'); var EventEmitter = require('eventemitter3'); function _interopNamespaceDefault(e) { var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var DragDropEvent__namespace = /*#__PURE__*/_interopNamespaceDefault(DragDropEvent); var GesturePlugin__namespace = /*#__PURE__*/_interopNamespaceDefault(GesturePlugin); function isCanvasElement(el) { if (!el || typeof el !== 'object') return false; if (el.nodeType === 1 && el.nodeName) { // HTMLCanvasElement return true; } // CanvasElement return !!el.isCanvasElement; } var Canvas2DContextService = /*#__PURE__*/function () { function Canvas2DContextService(context) { _classCallCheck(this, Canvas2DContextService); this.canvasConfig = context.config; } return _createClass(Canvas2DContextService, [{ key: "init", value: function () { var _init = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() { var _this$canvasConfig, canvas, devicePixelRatio, dpr; return _regeneratorRuntime().wrap(function (_context) { while (1) switch (_context.prev = _context.next) { case 0: _this$canvasConfig = this.canvasConfig, canvas = _this$canvasConfig.canvas, devicePixelRatio = _this$canvasConfig.devicePixelRatio; this.$canvas = canvas; // 实际获取到小程序环境的上下文 this.context = this.$canvas.getContext('2d'); // use user-defined dpr first dpr = devicePixelRatio || 1; dpr = dpr >= 1 ? Math.ceil(dpr) : 1; this.dpr = dpr; this.resize(this.canvasConfig.width, this.canvasConfig.height); case 1: case "end": return _context.stop(); } }, _callee, this); })); function init() { return _init.apply(this, arguments); } return init; }() }, { key: "getContext", value: function getContext() { return this.context; } }, { key: "getDomElement", value: function getDomElement() { return this.$canvas; } }, { key: "getDPR", value: function getDPR() { return this.dpr; } }, { key: "getBoundingClientRect", value: function getBoundingClientRect() { if (this.$canvas.getBoundingClientRect) { return this.$canvas.getBoundingClientRect(); } } }, { key: "destroy", value: function destroy() { // TODO: 小程序环境销毁 context this.context = null; this.$canvas = null; } }, { key: "resize", value: function resize(width, height) { var devicePixelRatio = this.canvasConfig.devicePixelRatio; var pixelRatio = devicePixelRatio; var canvasDOM = this.$canvas; // HTMLCanvasElement or canvasElement // 浏览器环境设置style样式 if (canvasDOM.style) { canvasDOM.style.width = "".concat(width, "px"); canvasDOM.style.height = "".concat(height, "px"); } if (isCanvasElement(canvasDOM)) { canvasDOM.width = width * pixelRatio; canvasDOM.height = height * pixelRatio; if (pixelRatio !== 1) { this.context.scale(pixelRatio, pixelRatio); } } } }, { key: "applyCursorStyle", value: function applyCursorStyle(cursor) { // 小程序环境无需设置鼠标样式 } }, { key: "toDataURL", value: function () { var _toDataURL = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(options) { var type, encoderOptions; return _regeneratorRuntime().wrap(function (_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: type = options.type, encoderOptions = options.encoderOptions; return _context2.abrupt("return", this.context.canvas.toDataURL(type, encoderOptions)); case 1: case "end": return _context2.stop(); } }, _callee2, this); })); function toDataURL(_x) { return _toDataURL.apply(this, arguments); } return toDataURL; }() }]); }(); var ContextRegisterPlugin = /*#__PURE__*/function (_AbstractRendererPlug) { function ContextRegisterPlugin() { var _this; _classCallCheck(this, ContextRegisterPlugin); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _callSuper(this, ContextRegisterPlugin, [].concat(args)); _this.name = 'mobile-canvas-context-register'; return _this; } _inherits(ContextRegisterPlugin, _AbstractRendererPlug); return _createClass(ContextRegisterPlugin, [{ key: "init", value: function init() { this.context.ContextService = Canvas2DContextService; } }, { key: "destroy", value: function destroy() { delete this.context.ContextService; } }]); }(gLite.AbstractRendererPlugin); var CanvasElement = /*#__PURE__*/function () { function CanvasElement(ctx) { _classCallCheck(this, CanvasElement); this.isCanvasElement = true; this.emitter = new EventEmitter(); this.context = ctx; // 有可能是 node canvas 创建的 context 对象 var canvas = ctx.canvas || {}; this.width = canvas.width || 0; this.height = canvas.height || 0; } return _createClass(CanvasElement, [{ key: "getContext", value: function getContext(contextId, contextAttributes) { return this.context; } }, { key: "getBoundingClientRect", value: function getBoundingClientRect() { var width = this.width; var height = this.height; // 默认都处理成可视窗口的顶部位置 return { top: 0, right: width, bottom: height, left: 0, width: width, height: height, x: 0, y: 0 }; } }, { key: "addEventListener", value: function addEventListener(type, listener, options) { // TODO: implement options this.emitter.on(type, listener); } }, { key: "removeEventListener", value: function removeEventListener(type, listener, options) { this.emitter.off(type, listener); } /** * @see https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget-dispatchEvent */ }, { key: "dispatchEvent", value: function dispatchEvent(e) { this.emitter.emit(e.type, e); return true; } }]); }(); function supportEventListener(canvas) { if (!canvas) { return false; } // 非 HTMLCanvasElement if (canvas.nodeType !== 1 || !canvas.nodeName || canvas.nodeName.toLowerCase() !== 'canvas') { return false; } // 微信小程序canvas.getContext('2d')时也是CanvasRenderingContext2D // 也会有ctx.canvas, 而且nodeType也是1,所以还要在看下是否支持addEventListener var support = false; try { canvas.addEventListener('eventTest', function () { support = true; }); canvas.dispatchEvent(new Event('eventTest')); } catch (_unused) { support = false; } return support; } function createMobileCanvasElement(ctx) { if (!ctx) { return null; } if (supportEventListener(ctx.canvas)) { return ctx.canvas; } return new CanvasElement(ctx); } var Renderer = /*#__PURE__*/function (_AbstractRenderer) { function Renderer(config) { var _this; _classCallCheck(this, Renderer); _this = _callSuper(this, Renderer, [config]); // register Canvas2DContext _this.registerPlugin(new ContextRegisterPlugin()); _this.registerPlugin(new gLite.ImageLoader.Plugin()); _this.registerPlugin(new gCanvas.CanvasPathGenerator.Plugin()); // enable rendering with Canvas2D API _this.registerPlugin(new gCanvas.CanvasRenderer.Plugin()); _this.registerPlugin(new gLite.MobileInteraction.Plugin()); // enable picking with Canvas2D API _this.registerPlugin(new gCanvas.CanvasPicker.Plugin()); _this.registerPlugin(new DragDropEvent__namespace.Plugin({ isDocumentDraggable: util.isNil(config === null || config === void 0 ? void 0 : config.isDocumentDraggable) ? true : config.isDocumentDraggable, isDocumentDroppable: util.isNil(config === null || config === void 0 ? void 0 : config.isDocumentDroppable) ? true : config.isDocumentDroppable, dragstartDistanceThreshold: util.isNil(config === null || config === void 0 ? void 0 : config.dragstartDistanceThreshold) ? 10 : config.dragstartDistanceThreshold, dragstartTimeThreshold: util.isNil(config === null || config === void 0 ? void 0 : config.dragstartTimeThreshold) ? 50 : config.dragstartTimeThreshold })); _this.registerPlugin(new GesturePlugin__namespace.Plugin({ isDocumentGestureEnabled: true })); return _this; } _inherits(Renderer, _AbstractRenderer); return _createClass(Renderer); }(gLite.AbstractRenderer); Object.defineProperty(exports, 'CanvasPicker', { enumerable: true, get: function () { return gCanvas.CanvasPicker; } }); Object.defineProperty(exports, 'CanvasRenderer', { enumerable: true, get: function () { return gCanvas.CanvasRenderer; } }); exports.Renderer = Renderer; exports.createMobileCanvasElement = createMobileCanvasElement; //# sourceMappingURL=index.js.map