SVGRendererBase.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. import { getLocationHref } from '../main';
  2. import {
  3. createElementID,
  4. getExpressionsPlugin,
  5. } from '../utils/common';
  6. import {
  7. extendPrototype,
  8. } from '../utils/functionExtensions';
  9. import {
  10. createSizedArray,
  11. } from '../utils/helpers/arrays';
  12. import createNS from '../utils/helpers/svg_elements';
  13. import BaseRenderer from './BaseRenderer';
  14. import IImageElement from '../elements/ImageElement';
  15. import SVGShapeElement from '../elements/svgElements/SVGShapeElement';
  16. import SVGTextLottieElement from '../elements/svgElements/SVGTextElement'; // eslint-disable-line import/no-cycle
  17. import ISolidElement from '../elements/SolidElement';
  18. import NullElement from '../elements/NullElement';
  19. function SVGRendererBase() {
  20. }
  21. extendPrototype([BaseRenderer], SVGRendererBase);
  22. SVGRendererBase.prototype.createNull = function (data) {
  23. return new NullElement(data, this.globalData, this);
  24. };
  25. SVGRendererBase.prototype.createShape = function (data) {
  26. return new SVGShapeElement(data, this.globalData, this);
  27. };
  28. SVGRendererBase.prototype.createText = function (data) {
  29. return new SVGTextLottieElement(data, this.globalData, this);
  30. };
  31. SVGRendererBase.prototype.createImage = function (data) {
  32. return new IImageElement(data, this.globalData, this);
  33. };
  34. SVGRendererBase.prototype.createSolid = function (data) {
  35. return new ISolidElement(data, this.globalData, this);
  36. };
  37. SVGRendererBase.prototype.configAnimation = function (animData) {
  38. this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
  39. this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
  40. if (this.renderConfig.viewBoxSize) {
  41. this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
  42. } else {
  43. this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
  44. }
  45. if (!this.renderConfig.viewBoxOnly) {
  46. this.svgElement.setAttribute('width', animData.w);
  47. this.svgElement.setAttribute('height', animData.h);
  48. this.svgElement.style.width = '100%';
  49. this.svgElement.style.height = '100%';
  50. this.svgElement.style.transform = 'translate3d(0,0,0)';
  51. this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
  52. }
  53. if (this.renderConfig.width) {
  54. this.svgElement.setAttribute('width', this.renderConfig.width);
  55. }
  56. if (this.renderConfig.height) {
  57. this.svgElement.setAttribute('height', this.renderConfig.height);
  58. }
  59. if (this.renderConfig.className) {
  60. this.svgElement.setAttribute('class', this.renderConfig.className);
  61. }
  62. if (this.renderConfig.id) {
  63. this.svgElement.setAttribute('id', this.renderConfig.id);
  64. }
  65. if (this.renderConfig.focusable !== undefined) {
  66. this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
  67. }
  68. this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
  69. // this.layerElement.style.transform = 'translate3d(0,0,0)';
  70. // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
  71. this.animationItem.wrapper.appendChild(this.svgElement);
  72. // Mask animation
  73. var defs = this.globalData.defs;
  74. this.setupGlobalData(animData, defs);
  75. this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
  76. this.data = animData;
  77. var maskElement = createNS('clipPath');
  78. var rect = createNS('rect');
  79. rect.setAttribute('width', animData.w);
  80. rect.setAttribute('height', animData.h);
  81. rect.setAttribute('x', 0);
  82. rect.setAttribute('y', 0);
  83. var maskId = createElementID();
  84. maskElement.setAttribute('id', maskId);
  85. maskElement.appendChild(rect);
  86. this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
  87. defs.appendChild(maskElement);
  88. this.layers = animData.layers;
  89. this.elements = createSizedArray(animData.layers.length);
  90. };
  91. SVGRendererBase.prototype.destroy = function () {
  92. if (this.animationItem.wrapper) {
  93. this.animationItem.wrapper.innerText = '';
  94. }
  95. this.layerElement = null;
  96. this.globalData.defs = null;
  97. var i;
  98. var len = this.layers ? this.layers.length : 0;
  99. for (i = 0; i < len; i += 1) {
  100. if (this.elements[i] && this.elements[i].destroy) {
  101. this.elements[i].destroy();
  102. }
  103. }
  104. this.elements.length = 0;
  105. this.destroyed = true;
  106. this.animationItem = null;
  107. };
  108. SVGRendererBase.prototype.updateContainerSize = function () {
  109. };
  110. SVGRendererBase.prototype.findIndexByInd = function (ind) {
  111. var i = 0;
  112. var len = this.layers.length;
  113. for (i = 0; i < len; i += 1) {
  114. if (this.layers[i].ind === ind) {
  115. return i;
  116. }
  117. }
  118. return -1;
  119. };
  120. SVGRendererBase.prototype.buildItem = function (pos) {
  121. var elements = this.elements;
  122. if (elements[pos] || this.layers[pos].ty === 99) {
  123. return;
  124. }
  125. elements[pos] = true;
  126. var element = this.createItem(this.layers[pos]);
  127. elements[pos] = element;
  128. if (getExpressionsPlugin()) {
  129. if (this.layers[pos].ty === 0) {
  130. this.globalData.projectInterface.registerComposition(element);
  131. }
  132. element.initExpressions();
  133. }
  134. this.appendElementInPos(element, pos);
  135. if (this.layers[pos].tt) {
  136. var elementIndex = ('tp' in this.layers[pos])
  137. ? this.findIndexByInd(this.layers[pos].tp)
  138. : pos - 1;
  139. if (elementIndex === -1) {
  140. return;
  141. }
  142. if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
  143. this.buildItem(elementIndex);
  144. this.addPendingElement(element);
  145. } else {
  146. var matteElement = elements[elementIndex];
  147. var matteMask = matteElement.getMatte(this.layers[pos].tt);
  148. element.setMatte(matteMask);
  149. }
  150. }
  151. };
  152. SVGRendererBase.prototype.checkPendingElements = function () {
  153. while (this.pendingElements.length) {
  154. var element = this.pendingElements.pop();
  155. element.checkParenting();
  156. if (element.data.tt) {
  157. var i = 0;
  158. var len = this.elements.length;
  159. while (i < len) {
  160. if (this.elements[i] === element) {
  161. var elementIndex = 'tp' in element.data
  162. ? this.findIndexByInd(element.data.tp)
  163. : i - 1;
  164. var matteElement = this.elements[elementIndex];
  165. var matteMask = matteElement.getMatte(this.layers[i].tt);
  166. element.setMatte(matteMask);
  167. break;
  168. }
  169. i += 1;
  170. }
  171. }
  172. }
  173. };
  174. SVGRendererBase.prototype.renderFrame = function (num) {
  175. if (this.renderedFrame === num || this.destroyed) {
  176. return;
  177. }
  178. if (num === null) {
  179. num = this.renderedFrame;
  180. } else {
  181. this.renderedFrame = num;
  182. }
  183. // console.log('-------');
  184. // console.log('FRAME ',num);
  185. this.globalData.frameNum = num;
  186. this.globalData.frameId += 1;
  187. this.globalData.projectInterface.currentFrame = num;
  188. this.globalData._mdf = false;
  189. var i;
  190. var len = this.layers.length;
  191. if (!this.completeLayers) {
  192. this.checkLayers(num);
  193. }
  194. for (i = len - 1; i >= 0; i -= 1) {
  195. if (this.completeLayers || this.elements[i]) {
  196. this.elements[i].prepareFrame(num - this.layers[i].st);
  197. }
  198. }
  199. if (this.globalData._mdf) {
  200. for (i = 0; i < len; i += 1) {
  201. if (this.completeLayers || this.elements[i]) {
  202. this.elements[i].renderFrame();
  203. }
  204. }
  205. }
  206. };
  207. SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
  208. var newElement = element.getBaseElement();
  209. if (!newElement) {
  210. return;
  211. }
  212. var i = 0;
  213. var nextElement;
  214. while (i < pos) {
  215. if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
  216. nextElement = this.elements[i].getBaseElement();
  217. }
  218. i += 1;
  219. }
  220. if (nextElement) {
  221. this.layerElement.insertBefore(newElement, nextElement);
  222. } else {
  223. this.layerElement.appendChild(newElement);
  224. }
  225. };
  226. SVGRendererBase.prototype.hide = function () {
  227. this.layerElement.style.display = 'none';
  228. };
  229. SVGRendererBase.prototype.show = function () {
  230. this.layerElement.style.display = 'block';
  231. };
  232. export default SVGRendererBase;