CVTextElement.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. import {
  2. extendPrototype,
  3. } from '../../utils/functionExtensions';
  4. import {
  5. createSizedArray,
  6. } from '../../utils/helpers/arrays';
  7. import createTag from '../../utils/helpers/html_elements';
  8. import RenderableElement from '../helpers/RenderableElement';
  9. import BaseElement from '../BaseElement';
  10. import TransformElement from '../helpers/TransformElement';
  11. import HierarchyElement from '../helpers/HierarchyElement';
  12. import FrameElement from '../helpers/FrameElement';
  13. import ITextElement from '../TextElement';
  14. import CVBaseElement from './CVBaseElement';
  15. function CVTextElement(data, globalData, comp) {
  16. this.textSpans = [];
  17. this.yOffset = 0;
  18. this.fillColorAnim = false;
  19. this.strokeColorAnim = false;
  20. this.strokeWidthAnim = false;
  21. this.stroke = false;
  22. this.fill = false;
  23. this.justifyOffset = 0;
  24. this.currentRender = null;
  25. this.renderType = 'canvas';
  26. this.values = {
  27. fill: 'rgba(0,0,0,0)',
  28. stroke: 'rgba(0,0,0,0)',
  29. sWidth: 0,
  30. fValue: '',
  31. };
  32. this.initElement(data, globalData, comp);
  33. }
  34. extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement, ITextElement], CVTextElement);
  35. CVTextElement.prototype.tHelper = createTag('canvas').getContext('2d');
  36. CVTextElement.prototype.buildNewText = function () {
  37. var documentData = this.textProperty.currentData;
  38. this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
  39. var hasFill = false;
  40. if (documentData.fc) {
  41. hasFill = true;
  42. this.values.fill = this.buildColor(documentData.fc);
  43. } else {
  44. this.values.fill = 'rgba(0,0,0,0)';
  45. }
  46. this.fill = hasFill;
  47. var hasStroke = false;
  48. if (documentData.sc) {
  49. hasStroke = true;
  50. this.values.stroke = this.buildColor(documentData.sc);
  51. this.values.sWidth = documentData.sw;
  52. }
  53. var fontData = this.globalData.fontManager.getFontByName(documentData.f);
  54. var i;
  55. var len;
  56. var letters = documentData.l;
  57. var matrixHelper = this.mHelper;
  58. this.stroke = hasStroke;
  59. this.values.fValue = documentData.finalSize + 'px ' + this.globalData.fontManager.getFontByName(documentData.f).fFamily;
  60. len = documentData.finalText.length;
  61. // this.tHelper.font = this.values.fValue;
  62. var charData;
  63. var shapeData;
  64. var k;
  65. var kLen;
  66. var shapes;
  67. var j;
  68. var jLen;
  69. var pathNodes;
  70. var commands;
  71. var pathArr;
  72. var singleShape = this.data.singleShape;
  73. var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
  74. var xPos = 0;
  75. var yPos = 0;
  76. var firstLine = true;
  77. var cnt = 0;
  78. for (i = 0; i < len; i += 1) {
  79. charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
  80. shapeData = (charData && charData.data) || {};
  81. matrixHelper.reset();
  82. if (singleShape && letters[i].n) {
  83. xPos = -trackingOffset;
  84. yPos += documentData.yOffset;
  85. yPos += firstLine ? 1 : 0;
  86. firstLine = false;
  87. }
  88. shapes = shapeData.shapes ? shapeData.shapes[0].it : [];
  89. jLen = shapes.length;
  90. matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
  91. if (singleShape) {
  92. this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
  93. }
  94. commands = createSizedArray(jLen - 1);
  95. var commandsCounter = 0;
  96. for (j = 0; j < jLen; j += 1) {
  97. if (shapes[j].ty === 'sh') {
  98. kLen = shapes[j].ks.k.i.length;
  99. pathNodes = shapes[j].ks.k;
  100. pathArr = [];
  101. for (k = 1; k < kLen; k += 1) {
  102. if (k === 1) {
  103. pathArr.push(matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
  104. }
  105. pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToY(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToX(pathNodes.v[k][0], pathNodes.v[k][1], 0), matrixHelper.applyToY(pathNodes.v[k][0], pathNodes.v[k][1], 0));
  106. }
  107. pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToY(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
  108. commands[commandsCounter] = pathArr;
  109. commandsCounter += 1;
  110. }
  111. }
  112. if (singleShape) {
  113. xPos += letters[i].l;
  114. xPos += trackingOffset;
  115. }
  116. if (this.textSpans[cnt]) {
  117. this.textSpans[cnt].elem = commands;
  118. } else {
  119. this.textSpans[cnt] = { elem: commands };
  120. }
  121. cnt += 1;
  122. }
  123. };
  124. CVTextElement.prototype.renderInnerContent = function () {
  125. this.validateText();
  126. var ctx = this.canvasContext;
  127. ctx.font = this.values.fValue;
  128. this.globalData.renderer.ctxLineCap('butt');
  129. // ctx.lineCap = 'butt';
  130. this.globalData.renderer.ctxLineJoin('miter');
  131. // ctx.lineJoin = 'miter';
  132. this.globalData.renderer.ctxMiterLimit(4);
  133. // ctx.miterLimit = 4;
  134. if (!this.data.singleShape) {
  135. this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
  136. }
  137. var i;
  138. var len;
  139. var j;
  140. var jLen;
  141. var k;
  142. var kLen;
  143. var renderedLetters = this.textAnimator.renderedLetters;
  144. var letters = this.textProperty.currentData.l;
  145. len = letters.length;
  146. var renderedLetter;
  147. var lastFill = null;
  148. var lastStroke = null;
  149. var lastStrokeW = null;
  150. var commands;
  151. var pathArr;
  152. var renderer = this.globalData.renderer;
  153. for (i = 0; i < len; i += 1) {
  154. if (!letters[i].n) {
  155. renderedLetter = renderedLetters[i];
  156. if (renderedLetter) {
  157. renderer.save();
  158. renderer.ctxTransform(renderedLetter.p);
  159. renderer.ctxOpacity(renderedLetter.o);
  160. }
  161. if (this.fill) {
  162. if (renderedLetter && renderedLetter.fc) {
  163. if (lastFill !== renderedLetter.fc) {
  164. renderer.ctxFillStyle(renderedLetter.fc);
  165. lastFill = renderedLetter.fc;
  166. // ctx.fillStyle = renderedLetter.fc;
  167. }
  168. } else if (lastFill !== this.values.fill) {
  169. lastFill = this.values.fill;
  170. renderer.ctxFillStyle(this.values.fill);
  171. // ctx.fillStyle = this.values.fill;
  172. }
  173. commands = this.textSpans[i].elem;
  174. jLen = commands.length;
  175. this.globalData.canvasContext.beginPath();
  176. for (j = 0; j < jLen; j += 1) {
  177. pathArr = commands[j];
  178. kLen = pathArr.length;
  179. this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
  180. for (k = 2; k < kLen; k += 6) {
  181. this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
  182. }
  183. }
  184. this.globalData.canvasContext.closePath();
  185. renderer.ctxFill();
  186. // this.globalData.canvasContext.fill();
  187. /// ctx.fillText(this.textSpans[i].val,0,0);
  188. }
  189. if (this.stroke) {
  190. if (renderedLetter && renderedLetter.sw) {
  191. if (lastStrokeW !== renderedLetter.sw) {
  192. lastStrokeW = renderedLetter.sw;
  193. renderer.ctxLineWidth(renderedLetter.sw);
  194. // ctx.lineWidth = renderedLetter.sw;
  195. }
  196. } else if (lastStrokeW !== this.values.sWidth) {
  197. lastStrokeW = this.values.sWidth;
  198. renderer.ctxLineWidth(this.values.sWidth);
  199. // ctx.lineWidth = this.values.sWidth;
  200. }
  201. if (renderedLetter && renderedLetter.sc) {
  202. if (lastStroke !== renderedLetter.sc) {
  203. lastStroke = renderedLetter.sc;
  204. renderer.ctxStrokeStyle(renderedLetter.sc);
  205. // ctx.strokeStyle = renderedLetter.sc;
  206. }
  207. } else if (lastStroke !== this.values.stroke) {
  208. lastStroke = this.values.stroke;
  209. renderer.ctxStrokeStyle(this.values.stroke);
  210. // ctx.strokeStyle = this.values.stroke;
  211. }
  212. commands = this.textSpans[i].elem;
  213. jLen = commands.length;
  214. this.globalData.canvasContext.beginPath();
  215. for (j = 0; j < jLen; j += 1) {
  216. pathArr = commands[j];
  217. kLen = pathArr.length;
  218. this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
  219. for (k = 2; k < kLen; k += 6) {
  220. this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
  221. }
  222. }
  223. this.globalData.canvasContext.closePath();
  224. renderer.ctxStroke();
  225. // this.globalData.canvasContext.stroke();
  226. /// ctx.strokeText(letters[i].val,0,0);
  227. }
  228. if (renderedLetter) {
  229. this.globalData.renderer.restore();
  230. }
  231. }
  232. }
  233. };
  234. export default CVTextElement;