(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@antv/g-lite')) : typeof define === 'function' && define.amd ? define(['exports', '@antv/g-lite'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.G = global.G || {}, global.G.HTMLRenderer = {}), global.window.G)); }(this, (function (exports, gLite) { 'use strict'; function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } var toString = {}.toString; var isType = function (value, type) { return toString.call(value) === '[object ' + type + ']'; }; var isString = (function (str) { return isType(str, 'String'); }); /** * 判断是否数字 * @return {Boolean} 是否数字 */ var isNumber = function (value) { return isType(value, 'Number'); }; var HTML_PREFIX = 'g-html-'; var CANVAS_CAMERA_ID = 'g-canvas-camera'; var HTMLRenderingPlugin = /*#__PURE__*/function () { function HTMLRenderingPlugin() { this.context = void 0; /** * wrapper for camera */ this.$camera = void 0; } var _proto = HTMLRenderingPlugin.prototype; _proto.joinTransformMatrix = function joinTransformMatrix(matrix) { return "matrix(" + [matrix[0], matrix[1], matrix[4], matrix[5], matrix[12], matrix[13]].join(',') + ")"; }; _proto.apply = function apply(context) { var _this = this; var camera = context.camera, renderingContext = context.renderingContext, renderingService = context.renderingService; this.context = context; var canvas = renderingContext.root.ownerDocument.defaultView; var setTransform = function setTransform(object, $el) { $el.style.transform = _this.joinTransformMatrix(object.getWorldTransform()); }; var handleMounted = function handleMounted(e) { var object = e.target; if (object.nodeName === gLite.Shape.HTML) { if (!_this.$camera) { _this.$camera = _this.createCamera(camera); } // create DOM element var $el = _this.getOrCreateEl(object); _this.$camera.appendChild($el); // apply documentElement's style var attributes = object.ownerDocument.documentElement.attributes; Object.keys(attributes).forEach(function (name) { $el.style[name] = attributes[name]; }); Object.keys(object.attributes).forEach(function (name) { _this.updateAttribute(name, object); }); setTransform(object, $el); gLite.runtime.nativeHTMLMap.set($el, object); } }; var handleUnmounted = function handleUnmounted(e) { var object = e.target; if (object.nodeName === gLite.Shape.HTML && _this.$camera) { var $el = _this.getOrCreateEl(object); if ($el) { $el.remove(); gLite.runtime.nativeHTMLMap.delete($el); } // const existedId = this.getId(object); // const $existedElement: HTMLElement | null = this.$camera.querySelector('#' + existedId); // if ($existedElement) { // this.$camera.removeChild($existedElement); // } } }; var handleAttributeChanged = function handleAttributeChanged(e) { var object = e.target; if (object.nodeName === gLite.Shape.HTML) { var attrName = e.attrName; _this.updateAttribute(attrName, object); } }; var handleBoundsChanged = function handleBoundsChanged(e) { var object = e.target; if (object.nodeName === gLite.Shape.HTML) { var $el = _this.getOrCreateEl(object); setTransform(object, $el); } }; var handleCanvasResize = function handleCanvasResize() { if (_this.$camera) { var _this$context$config = _this.context.config, width = _this$context$config.width, height = _this$context$config.height; _this.$camera.style.width = (width || 0) + "px"; _this.$camera.style.height = (height || 0) + "px"; } }; renderingService.hooks.init.tap(HTMLRenderingPlugin.tag, function () { canvas.addEventListener(gLite.CanvasEvent.RESIZE, handleCanvasResize); canvas.addEventListener(gLite.ElementEvent.MOUNTED, handleMounted); canvas.addEventListener(gLite.ElementEvent.UNMOUNTED, handleUnmounted); canvas.addEventListener(gLite.ElementEvent.ATTR_MODIFIED, handleAttributeChanged); canvas.addEventListener(gLite.ElementEvent.BOUNDS_CHANGED, handleBoundsChanged); }); renderingService.hooks.endFrame.tap(HTMLRenderingPlugin.tag, function () { if (_this.$camera && renderingContext.renderReasons.has(gLite.RenderReason.CAMERA_CHANGED)) { _this.$camera.style.transform = _this.joinTransformMatrix(camera.getOrthoMatrix()); } }); renderingService.hooks.destroy.tap(HTMLRenderingPlugin.tag, function () { // remove camera if (_this.$camera) { _this.$camera.remove(); } canvas.removeEventListener(gLite.CanvasEvent.RESIZE, handleCanvasResize); canvas.removeEventListener(gLite.ElementEvent.MOUNTED, handleMounted); canvas.removeEventListener(gLite.ElementEvent.UNMOUNTED, handleUnmounted); canvas.removeEventListener(gLite.ElementEvent.ATTR_MODIFIED, handleAttributeChanged); canvas.removeEventListener(gLite.ElementEvent.BOUNDS_CHANGED, handleBoundsChanged); }); }; _proto.getId = function getId(object) { return object.id || HTML_PREFIX + object.entity; }; _proto.createCamera = function createCamera(camera) { var _this$context$config2 = this.context.config, doc = _this$context$config2.document, width = _this$context$config2.width, height = _this$context$config2.height; var $canvas = this.context.contextService.getDomElement(); var $container = $canvas.parentNode; if ($container) { var cameraId = CANVAS_CAMERA_ID; var $existedCamera = $container.querySelector('#' + cameraId); if (!$existedCamera) { var $camera = (doc || document).createElement('div'); $existedCamera = $camera; $camera.id = cameraId; // use absolute position $camera.style.position = 'absolute'; // account for DOM element's offset @see https://github.com/antvis/G/issues/1150 $camera.style.left = ($canvas.offsetLeft || 0) + "px"; $camera.style.top = ($canvas.offsetTop || 0) + "px"; $camera.style.transformOrigin = 'left top'; $camera.style.transform = this.joinTransformMatrix(camera.getOrthoMatrix()); // HTML elements should not overflow with canvas @see https://github.com/antvis/G/issues/1163 $camera.style.overflow = 'hidden'; $camera.style.pointerEvents = 'none'; $camera.style.width = (width || 0) + "px"; $camera.style.height = (height || 0) + "px"; $container.appendChild($camera); } return $existedCamera; } return null; }; _proto.getOrCreateEl = function getOrCreateEl(object) { var doc = this.context.config.document; var existedId = this.getId(object); var $existedElement = this.$camera.querySelector('#' + existedId); if (!$existedElement) { $existedElement = (doc || document).createElement('div'); object.parsedStyle.$el = $existedElement; $existedElement.id = existedId; if (object.name) { $existedElement.setAttribute('name', object.name); } if (object.className) { $existedElement.className = object.className; } // use absolute position $existedElement.style.position = 'absolute'; // @see https://github.com/antvis/G/issues/1150 $existedElement.style.left = "0px"; $existedElement.style.top = "0px"; $existedElement.style['will-change'] = 'transform'; $existedElement.style.transform = this.joinTransformMatrix(object.getWorldTransform()); } return $existedElement; }; _proto.updateAttribute = function updateAttribute(name, object) { var $el = this.getOrCreateEl(object); switch (name) { case 'innerHTML': var innerHTML = object.parsedStyle.innerHTML; if (isString(innerHTML)) { $el.innerHTML = innerHTML; } else { $el.innerHTML = ''; $el.appendChild(innerHTML); } break; case 'transformOrigin': var transformOrigin = object.parsedStyle.transformOrigin; $el.style['transform-origin'] = transformOrigin[0].value + " " + transformOrigin[1].value; break; case 'width': if (gLite.runtime.enableCSSParsing) { var width = object.computedStyleMap().get('width'); $el.style.width = width.toString(); } else { var _width = object.parsedStyle.width; $el.style.width = isNumber(_width) ? _width + "px" : _width.toString(); } break; case 'height': if (gLite.runtime.enableCSSParsing) { var height = object.computedStyleMap().get('height'); $el.style.height = height.toString(); } else { var _height = object.parsedStyle.height; $el.style.height = isNumber(_height) ? _height + "px" : _height.toString(); } break; case 'zIndex': var zIndex = object.parsedStyle.zIndex; $el.style['z-index'] = "" + zIndex; break; case 'visibility': var visibility = object.parsedStyle.visibility; $el.style.visibility = visibility; break; case 'pointerEvents': var pointerEvents = object.parsedStyle.pointerEvents; $el.style.pointerEvents = pointerEvents; break; case 'opacity': var opacity = object.parsedStyle.opacity; $el.style.opacity = "" + opacity; break; case 'fill': var fill = object.parsedStyle.fill; var color = ''; if (gLite.isCSSRGB(fill)) { if (fill.isNone) { color = 'transparent'; } else { color = object.getAttribute('fill'); } } else if (Array.isArray(fill)) { color = object.getAttribute('fill'); } else if (gLite.isPattern(fill)) ; $el.style.background = color; break; case 'stroke': var stroke = object.parsedStyle.stroke; var borderColor = ''; if (gLite.isCSSRGB(stroke)) { if (stroke.isNone) { borderColor = 'transparent'; } else { borderColor = object.getAttribute('stroke'); } } else if (Array.isArray(stroke)) { borderColor = object.getAttribute('stroke'); } else if (gLite.isPattern(stroke)) ; $el.style['border-color'] = borderColor; $el.style['border-style'] = 'solid'; break; case 'lineWidth': var lineWidth = object.parsedStyle.lineWidth; $el.style['border-width'] = (lineWidth || 0) + "px"; break; case 'lineDash': $el.style['border-style'] = 'dashed'; break; case 'filter': var filter = object.style.filter; $el.style.filter = filter; break; } }; return HTMLRenderingPlugin; }(); HTMLRenderingPlugin.tag = 'HTMLRendering'; var Plugin = /*#__PURE__*/function (_AbstractRendererPlug) { _inheritsLoose(Plugin, _AbstractRendererPlug); function Plugin() { var _this; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _AbstractRendererPlug.call.apply(_AbstractRendererPlug, [this].concat(args)) || this; _this.name = 'html-renderer'; return _this; } var _proto = Plugin.prototype; _proto.init = function init() { this.addRenderingPlugin(new HTMLRenderingPlugin()); }; _proto.destroy = function destroy() { this.removeAllRenderingPlugins(); }; return Plugin; }(gLite.AbstractRendererPlugin); exports.Plugin = Plugin; Object.defineProperty(exports, '__esModule', { value: true }); })));