index.esm.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. import { CanvasEvent, ElementEvent, RenderReason, isCSSRGB, isPattern, runtime, Shape, AbstractRendererPlugin } from '@antv/g-lite';
  2. import { isNumber, isString } from '@antv/util';
  3. function _inheritsLoose(subClass, superClass) {
  4. subClass.prototype = Object.create(superClass.prototype);
  5. subClass.prototype.constructor = subClass;
  6. _setPrototypeOf(subClass, superClass);
  7. }
  8. function _setPrototypeOf(o, p) {
  9. _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
  10. o.__proto__ = p;
  11. return o;
  12. };
  13. return _setPrototypeOf(o, p);
  14. }
  15. var HTML_PREFIX = 'g-html-';
  16. var CANVAS_CAMERA_ID = 'g-canvas-camera';
  17. var HTMLRenderingPlugin = /*#__PURE__*/function () {
  18. function HTMLRenderingPlugin() {
  19. this.context = void 0;
  20. /**
  21. * wrapper for camera
  22. */
  23. this.$camera = void 0;
  24. }
  25. var _proto = HTMLRenderingPlugin.prototype;
  26. _proto.joinTransformMatrix = function joinTransformMatrix(matrix) {
  27. return "matrix(" + [matrix[0], matrix[1], matrix[4], matrix[5], matrix[12], matrix[13]].join(',') + ")";
  28. };
  29. _proto.apply = function apply(context) {
  30. var _this = this;
  31. var camera = context.camera,
  32. renderingContext = context.renderingContext,
  33. renderingService = context.renderingService;
  34. this.context = context;
  35. var canvas = renderingContext.root.ownerDocument.defaultView;
  36. var setTransform = function setTransform(object, $el) {
  37. $el.style.transform = _this.joinTransformMatrix(object.getWorldTransform());
  38. };
  39. var handleMounted = function handleMounted(e) {
  40. var object = e.target;
  41. if (object.nodeName === Shape.HTML) {
  42. if (!_this.$camera) {
  43. _this.$camera = _this.createCamera(camera);
  44. }
  45. // create DOM element
  46. var $el = _this.getOrCreateEl(object);
  47. _this.$camera.appendChild($el);
  48. // apply documentElement's style
  49. var attributes = object.ownerDocument.documentElement.attributes;
  50. Object.keys(attributes).forEach(function (name) {
  51. $el.style[name] = attributes[name];
  52. });
  53. Object.keys(object.attributes).forEach(function (name) {
  54. _this.updateAttribute(name, object);
  55. });
  56. setTransform(object, $el);
  57. runtime.nativeHTMLMap.set($el, object);
  58. }
  59. };
  60. var handleUnmounted = function handleUnmounted(e) {
  61. var object = e.target;
  62. if (object.nodeName === Shape.HTML && _this.$camera) {
  63. var $el = _this.getOrCreateEl(object);
  64. if ($el) {
  65. $el.remove();
  66. runtime.nativeHTMLMap.delete($el);
  67. }
  68. // const existedId = this.getId(object);
  69. // const $existedElement: HTMLElement | null = this.$camera.querySelector('#' + existedId);
  70. // if ($existedElement) {
  71. // this.$camera.removeChild($existedElement);
  72. // }
  73. }
  74. };
  75. var handleAttributeChanged = function handleAttributeChanged(e) {
  76. var object = e.target;
  77. if (object.nodeName === Shape.HTML) {
  78. var attrName = e.attrName;
  79. _this.updateAttribute(attrName, object);
  80. }
  81. };
  82. var handleBoundsChanged = function handleBoundsChanged(e) {
  83. var object = e.target;
  84. if (object.nodeName === Shape.HTML) {
  85. var $el = _this.getOrCreateEl(object);
  86. setTransform(object, $el);
  87. }
  88. };
  89. var handleCanvasResize = function handleCanvasResize() {
  90. if (_this.$camera) {
  91. var _this$context$config = _this.context.config,
  92. width = _this$context$config.width,
  93. height = _this$context$config.height;
  94. _this.$camera.style.width = (width || 0) + "px";
  95. _this.$camera.style.height = (height || 0) + "px";
  96. }
  97. };
  98. renderingService.hooks.init.tap(HTMLRenderingPlugin.tag, function () {
  99. canvas.addEventListener(CanvasEvent.RESIZE, handleCanvasResize);
  100. canvas.addEventListener(ElementEvent.MOUNTED, handleMounted);
  101. canvas.addEventListener(ElementEvent.UNMOUNTED, handleUnmounted);
  102. canvas.addEventListener(ElementEvent.ATTR_MODIFIED, handleAttributeChanged);
  103. canvas.addEventListener(ElementEvent.BOUNDS_CHANGED, handleBoundsChanged);
  104. });
  105. renderingService.hooks.endFrame.tap(HTMLRenderingPlugin.tag, function () {
  106. if (_this.$camera && renderingContext.renderReasons.has(RenderReason.CAMERA_CHANGED)) {
  107. _this.$camera.style.transform = _this.joinTransformMatrix(camera.getOrthoMatrix());
  108. }
  109. });
  110. renderingService.hooks.destroy.tap(HTMLRenderingPlugin.tag, function () {
  111. // remove camera
  112. if (_this.$camera) {
  113. _this.$camera.remove();
  114. }
  115. canvas.removeEventListener(CanvasEvent.RESIZE, handleCanvasResize);
  116. canvas.removeEventListener(ElementEvent.MOUNTED, handleMounted);
  117. canvas.removeEventListener(ElementEvent.UNMOUNTED, handleUnmounted);
  118. canvas.removeEventListener(ElementEvent.ATTR_MODIFIED, handleAttributeChanged);
  119. canvas.removeEventListener(ElementEvent.BOUNDS_CHANGED, handleBoundsChanged);
  120. });
  121. };
  122. _proto.getId = function getId(object) {
  123. return object.id || HTML_PREFIX + object.entity;
  124. };
  125. _proto.createCamera = function createCamera(camera) {
  126. var _this$context$config2 = this.context.config,
  127. doc = _this$context$config2.document,
  128. width = _this$context$config2.width,
  129. height = _this$context$config2.height;
  130. var $canvas = this.context.contextService.getDomElement();
  131. var $container = $canvas.parentNode;
  132. if ($container) {
  133. var cameraId = CANVAS_CAMERA_ID;
  134. var $existedCamera = $container.querySelector('#' + cameraId);
  135. if (!$existedCamera) {
  136. var $camera = (doc || document).createElement('div');
  137. $existedCamera = $camera;
  138. $camera.id = cameraId;
  139. // use absolute position
  140. $camera.style.position = 'absolute';
  141. // account for DOM element's offset @see https://github.com/antvis/G/issues/1150
  142. $camera.style.left = ($canvas.offsetLeft || 0) + "px";
  143. $camera.style.top = ($canvas.offsetTop || 0) + "px";
  144. $camera.style.transformOrigin = 'left top';
  145. $camera.style.transform = this.joinTransformMatrix(camera.getOrthoMatrix());
  146. // HTML elements should not overflow with canvas @see https://github.com/antvis/G/issues/1163
  147. $camera.style.overflow = 'hidden';
  148. $camera.style.pointerEvents = 'none';
  149. $camera.style.width = (width || 0) + "px";
  150. $camera.style.height = (height || 0) + "px";
  151. $container.appendChild($camera);
  152. }
  153. return $existedCamera;
  154. }
  155. return null;
  156. };
  157. _proto.getOrCreateEl = function getOrCreateEl(object) {
  158. var doc = this.context.config.document;
  159. var existedId = this.getId(object);
  160. var $existedElement = this.$camera.querySelector('#' + existedId);
  161. if (!$existedElement) {
  162. $existedElement = (doc || document).createElement('div');
  163. object.parsedStyle.$el = $existedElement;
  164. $existedElement.id = existedId;
  165. if (object.name) {
  166. $existedElement.setAttribute('name', object.name);
  167. }
  168. if (object.className) {
  169. $existedElement.className = object.className;
  170. }
  171. // use absolute position
  172. $existedElement.style.position = 'absolute';
  173. // @see https://github.com/antvis/G/issues/1150
  174. $existedElement.style.left = "0px";
  175. $existedElement.style.top = "0px";
  176. $existedElement.style['will-change'] = 'transform';
  177. $existedElement.style.transform = this.joinTransformMatrix(object.getWorldTransform());
  178. }
  179. return $existedElement;
  180. };
  181. _proto.updateAttribute = function updateAttribute(name, object) {
  182. var $el = this.getOrCreateEl(object);
  183. switch (name) {
  184. case 'innerHTML':
  185. var innerHTML = object.parsedStyle.innerHTML;
  186. if (isString(innerHTML)) {
  187. $el.innerHTML = innerHTML;
  188. } else {
  189. $el.innerHTML = '';
  190. $el.appendChild(innerHTML);
  191. }
  192. break;
  193. case 'transformOrigin':
  194. var transformOrigin = object.parsedStyle.transformOrigin;
  195. $el.style['transform-origin'] = transformOrigin[0].value + " " + transformOrigin[1].value;
  196. break;
  197. case 'width':
  198. if (runtime.enableCSSParsing) {
  199. var width = object.computedStyleMap().get('width');
  200. $el.style.width = width.toString();
  201. } else {
  202. var _width = object.parsedStyle.width;
  203. $el.style.width = isNumber(_width) ? _width + "px" : _width.toString();
  204. }
  205. break;
  206. case 'height':
  207. if (runtime.enableCSSParsing) {
  208. var height = object.computedStyleMap().get('height');
  209. $el.style.height = height.toString();
  210. } else {
  211. var _height = object.parsedStyle.height;
  212. $el.style.height = isNumber(_height) ? _height + "px" : _height.toString();
  213. }
  214. break;
  215. case 'zIndex':
  216. var zIndex = object.parsedStyle.zIndex;
  217. $el.style['z-index'] = "" + zIndex;
  218. break;
  219. case 'visibility':
  220. var visibility = object.parsedStyle.visibility;
  221. $el.style.visibility = visibility;
  222. break;
  223. case 'pointerEvents':
  224. var pointerEvents = object.parsedStyle.pointerEvents;
  225. $el.style.pointerEvents = pointerEvents;
  226. break;
  227. case 'opacity':
  228. var opacity = object.parsedStyle.opacity;
  229. $el.style.opacity = "" + opacity;
  230. break;
  231. case 'fill':
  232. var fill = object.parsedStyle.fill;
  233. var color = '';
  234. if (isCSSRGB(fill)) {
  235. if (fill.isNone) {
  236. color = 'transparent';
  237. } else {
  238. color = object.getAttribute('fill');
  239. }
  240. } else if (Array.isArray(fill)) {
  241. color = object.getAttribute('fill');
  242. } else if (isPattern(fill)) ;
  243. $el.style.background = color;
  244. break;
  245. case 'stroke':
  246. var stroke = object.parsedStyle.stroke;
  247. var borderColor = '';
  248. if (isCSSRGB(stroke)) {
  249. if (stroke.isNone) {
  250. borderColor = 'transparent';
  251. } else {
  252. borderColor = object.getAttribute('stroke');
  253. }
  254. } else if (Array.isArray(stroke)) {
  255. borderColor = object.getAttribute('stroke');
  256. } else if (isPattern(stroke)) ;
  257. $el.style['border-color'] = borderColor;
  258. $el.style['border-style'] = 'solid';
  259. break;
  260. case 'lineWidth':
  261. var lineWidth = object.parsedStyle.lineWidth;
  262. $el.style['border-width'] = (lineWidth || 0) + "px";
  263. break;
  264. case 'lineDash':
  265. $el.style['border-style'] = 'dashed';
  266. break;
  267. case 'filter':
  268. var filter = object.style.filter;
  269. $el.style.filter = filter;
  270. break;
  271. }
  272. };
  273. return HTMLRenderingPlugin;
  274. }();
  275. HTMLRenderingPlugin.tag = 'HTMLRendering';
  276. var Plugin = /*#__PURE__*/function (_AbstractRendererPlug) {
  277. _inheritsLoose(Plugin, _AbstractRendererPlug);
  278. function Plugin() {
  279. var _this;
  280. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  281. args[_key] = arguments[_key];
  282. }
  283. _this = _AbstractRendererPlug.call.apply(_AbstractRendererPlug, [this].concat(args)) || this;
  284. _this.name = 'html-renderer';
  285. return _this;
  286. }
  287. var _proto = Plugin.prototype;
  288. _proto.init = function init() {
  289. this.addRenderingPlugin(new HTMLRenderingPlugin());
  290. };
  291. _proto.destroy = function destroy() {
  292. this.removeAllRenderingPlugins();
  293. };
  294. return Plugin;
  295. }(AbstractRendererPlugin);
  296. export { Plugin };