SVGElementsRenderer.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. import Matrix from '../../../3rd_party/transformation-matrix';
  2. import buildShapeString from '../../../utils/shapes/shapePathBuilder';
  3. import { bmFloor } from '../../../utils/common';
  4. const SVGElementsRenderer = (function () {
  5. var _identityMatrix = new Matrix();
  6. var _matrixHelper = new Matrix();
  7. var ob = {
  8. createRenderFunction: createRenderFunction,
  9. };
  10. function createRenderFunction(data) {
  11. switch (data.ty) {
  12. case 'fl':
  13. return renderFill;
  14. case 'gf':
  15. return renderGradient;
  16. case 'gs':
  17. return renderGradientStroke;
  18. case 'st':
  19. return renderStroke;
  20. case 'sh':
  21. case 'el':
  22. case 'rc':
  23. case 'sr':
  24. return renderPath;
  25. case 'tr':
  26. return renderContentTransform;
  27. case 'no':
  28. return renderNoop;
  29. default:
  30. return null;
  31. }
  32. }
  33. function renderContentTransform(styleData, itemData, isFirstFrame) {
  34. if (isFirstFrame || itemData.transform.op._mdf) {
  35. itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
  36. }
  37. if (isFirstFrame || itemData.transform.mProps._mdf) {
  38. itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
  39. }
  40. }
  41. function renderNoop() {
  42. }
  43. function renderPath(styleData, itemData, isFirstFrame) {
  44. var j;
  45. var jLen;
  46. var pathStringTransformed;
  47. var redraw;
  48. var pathNodes;
  49. var l;
  50. var lLen = itemData.styles.length;
  51. var lvl = itemData.lvl;
  52. var paths;
  53. var mat;
  54. var iterations;
  55. var k;
  56. for (l = 0; l < lLen; l += 1) {
  57. redraw = itemData.sh._mdf || isFirstFrame;
  58. if (itemData.styles[l].lvl < lvl) {
  59. mat = _matrixHelper.reset();
  60. iterations = lvl - itemData.styles[l].lvl;
  61. k = itemData.transformers.length - 1;
  62. while (!redraw && iterations > 0) {
  63. redraw = itemData.transformers[k].mProps._mdf || redraw;
  64. iterations -= 1;
  65. k -= 1;
  66. }
  67. if (redraw) {
  68. iterations = lvl - itemData.styles[l].lvl;
  69. k = itemData.transformers.length - 1;
  70. while (iterations > 0) {
  71. mat.multiply(itemData.transformers[k].mProps.v);
  72. iterations -= 1;
  73. k -= 1;
  74. }
  75. }
  76. } else {
  77. mat = _identityMatrix;
  78. }
  79. paths = itemData.sh.paths;
  80. jLen = paths._length;
  81. if (redraw) {
  82. pathStringTransformed = '';
  83. for (j = 0; j < jLen; j += 1) {
  84. pathNodes = paths.shapes[j];
  85. if (pathNodes && pathNodes._length) {
  86. pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
  87. }
  88. }
  89. itemData.caches[l] = pathStringTransformed;
  90. } else {
  91. pathStringTransformed = itemData.caches[l];
  92. }
  93. itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
  94. itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
  95. }
  96. }
  97. function renderFill(styleData, itemData, isFirstFrame) {
  98. var styleElem = itemData.style;
  99. if (itemData.c._mdf || isFirstFrame) {
  100. styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
  101. }
  102. if (itemData.o._mdf || isFirstFrame) {
  103. styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
  104. }
  105. }
  106. function renderGradientStroke(styleData, itemData, isFirstFrame) {
  107. renderGradient(styleData, itemData, isFirstFrame);
  108. renderStroke(styleData, itemData, isFirstFrame);
  109. }
  110. function renderGradient(styleData, itemData, isFirstFrame) {
  111. var gfill = itemData.gf;
  112. var hasOpacity = itemData.g._hasOpacity;
  113. var pt1 = itemData.s.v;
  114. var pt2 = itemData.e.v;
  115. if (itemData.o._mdf || isFirstFrame) {
  116. var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
  117. itemData.style.pElem.setAttribute(attr, itemData.o.v);
  118. }
  119. if (itemData.s._mdf || isFirstFrame) {
  120. var attr1 = styleData.t === 1 ? 'x1' : 'cx';
  121. var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
  122. gfill.setAttribute(attr1, pt1[0]);
  123. gfill.setAttribute(attr2, pt1[1]);
  124. if (hasOpacity && !itemData.g._collapsable) {
  125. itemData.of.setAttribute(attr1, pt1[0]);
  126. itemData.of.setAttribute(attr2, pt1[1]);
  127. }
  128. }
  129. var stops;
  130. var i;
  131. var len;
  132. var stop;
  133. if (itemData.g._cmdf || isFirstFrame) {
  134. stops = itemData.cst;
  135. var cValues = itemData.g.c;
  136. len = stops.length;
  137. for (i = 0; i < len; i += 1) {
  138. stop = stops[i];
  139. stop.setAttribute('offset', cValues[i * 4] + '%');
  140. stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
  141. }
  142. }
  143. if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
  144. var oValues = itemData.g.o;
  145. if (itemData.g._collapsable) {
  146. stops = itemData.cst;
  147. } else {
  148. stops = itemData.ost;
  149. }
  150. len = stops.length;
  151. for (i = 0; i < len; i += 1) {
  152. stop = stops[i];
  153. if (!itemData.g._collapsable) {
  154. stop.setAttribute('offset', oValues[i * 2] + '%');
  155. }
  156. stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
  157. }
  158. }
  159. if (styleData.t === 1) {
  160. if (itemData.e._mdf || isFirstFrame) {
  161. gfill.setAttribute('x2', pt2[0]);
  162. gfill.setAttribute('y2', pt2[1]);
  163. if (hasOpacity && !itemData.g._collapsable) {
  164. itemData.of.setAttribute('x2', pt2[0]);
  165. itemData.of.setAttribute('y2', pt2[1]);
  166. }
  167. }
  168. } else {
  169. var rad;
  170. if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
  171. rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
  172. gfill.setAttribute('r', rad);
  173. if (hasOpacity && !itemData.g._collapsable) {
  174. itemData.of.setAttribute('r', rad);
  175. }
  176. }
  177. if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
  178. if (!rad) {
  179. rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
  180. }
  181. var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
  182. var percent = itemData.h.v;
  183. if (percent >= 1) {
  184. percent = 0.99;
  185. } else if (percent <= -1) {
  186. percent = -0.99;
  187. }
  188. var dist = rad * percent;
  189. var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
  190. var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
  191. gfill.setAttribute('fx', x);
  192. gfill.setAttribute('fy', y);
  193. if (hasOpacity && !itemData.g._collapsable) {
  194. itemData.of.setAttribute('fx', x);
  195. itemData.of.setAttribute('fy', y);
  196. }
  197. }
  198. // gfill.setAttribute('fy','200');
  199. }
  200. }
  201. function renderStroke(styleData, itemData, isFirstFrame) {
  202. var styleElem = itemData.style;
  203. var d = itemData.d;
  204. if (d && (d._mdf || isFirstFrame) && d.dashStr) {
  205. styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
  206. styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
  207. }
  208. if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
  209. styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
  210. }
  211. if (itemData.o._mdf || isFirstFrame) {
  212. styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
  213. }
  214. if (itemData.w._mdf || isFirstFrame) {
  215. styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
  216. if (styleElem.msElem) {
  217. styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
  218. }
  219. }
  220. }
  221. return ob;
  222. }());
  223. export default SVGElementsRenderer;