index.js 11 KB

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