source: imaps-frontend/node_modules/konva/lib/shapes/Text.js

main
Last change on this file was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 19.0 KB
Line 
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.Text = exports.stringToArray = void 0;
4const Util_1 = require("../Util");
5const Factory_1 = require("../Factory");
6const Shape_1 = require("../Shape");
7const Global_1 = require("../Global");
8const Validators_1 = require("../Validators");
9const Global_2 = require("../Global");
10function stringToArray(string) {
11 return Array.from(string);
12}
13exports.stringToArray = stringToArray;
14var AUTO = 'auto', CENTER = 'center', INHERIT = 'inherit', JUSTIFY = 'justify', CHANGE_KONVA = 'Change.konva', CONTEXT_2D = '2d', DASH = '-', LEFT = 'left', LTR = 'ltr', TEXT = 'text', TEXT_UPPER = 'Text', TOP = 'top', BOTTOM = 'bottom', MIDDLE = 'middle', NORMAL = 'normal', PX_SPACE = 'px ', SPACE = ' ', RIGHT = 'right', RTL = 'rtl', WORD = 'word', CHAR = 'char', NONE = 'none', ELLIPSIS = '…', ATTR_CHANGE_LIST = [
15 'direction',
16 'fontFamily',
17 'fontSize',
18 'fontStyle',
19 'fontVariant',
20 'padding',
21 'align',
22 'verticalAlign',
23 'lineHeight',
24 'text',
25 'width',
26 'height',
27 'wrap',
28 'ellipsis',
29 'letterSpacing',
30], attrChangeListLen = ATTR_CHANGE_LIST.length;
31function normalizeFontFamily(fontFamily) {
32 return fontFamily
33 .split(',')
34 .map((family) => {
35 family = family.trim();
36 const hasSpace = family.indexOf(' ') >= 0;
37 const hasQuotes = family.indexOf('"') >= 0 || family.indexOf("'") >= 0;
38 if (hasSpace && !hasQuotes) {
39 family = `"${family}"`;
40 }
41 return family;
42 })
43 .join(', ');
44}
45var dummyContext;
46function getDummyContext() {
47 if (dummyContext) {
48 return dummyContext;
49 }
50 dummyContext = Util_1.Util.createCanvasElement().getContext(CONTEXT_2D);
51 return dummyContext;
52}
53function _fillFunc(context) {
54 context.fillText(this._partialText, this._partialTextX, this._partialTextY);
55}
56function _strokeFunc(context) {
57 context.setAttr('miterLimit', 2);
58 context.strokeText(this._partialText, this._partialTextX, this._partialTextY);
59}
60function checkDefaultFill(config) {
61 config = config || {};
62 if (!config.fillLinearGradientColorStops &&
63 !config.fillRadialGradientColorStops &&
64 !config.fillPatternImage) {
65 config.fill = config.fill || 'black';
66 }
67 return config;
68}
69class Text extends Shape_1.Shape {
70 constructor(config) {
71 super(checkDefaultFill(config));
72 this._partialTextX = 0;
73 this._partialTextY = 0;
74 for (var n = 0; n < attrChangeListLen; n++) {
75 this.on(ATTR_CHANGE_LIST[n] + CHANGE_KONVA, this._setTextData);
76 }
77 this._setTextData();
78 }
79 _sceneFunc(context) {
80 var textArr = this.textArr, textArrLen = textArr.length;
81 if (!this.text()) {
82 return;
83 }
84 var padding = this.padding(), fontSize = this.fontSize(), lineHeightPx = this.lineHeight() * fontSize, verticalAlign = this.verticalAlign(), direction = this.direction(), alignY = 0, align = this.align(), totalWidth = this.getWidth(), letterSpacing = this.letterSpacing(), fill = this.fill(), textDecoration = this.textDecoration(), shouldUnderline = textDecoration.indexOf('underline') !== -1, shouldLineThrough = textDecoration.indexOf('line-through') !== -1, n;
85 direction = direction === INHERIT ? context.direction : direction;
86 var translateY = lineHeightPx / 2;
87 var baseline = MIDDLE;
88 if (Global_1.Konva._fixTextRendering) {
89 var metrics = this.measureSize('M');
90 baseline = 'alphabetic';
91 translateY =
92 (metrics.fontBoundingBoxAscent - metrics.fontBoundingBoxDescent) / 2 +
93 lineHeightPx / 2;
94 }
95 var lineTranslateX = 0;
96 var lineTranslateY = 0;
97 if (direction === RTL) {
98 context.setAttr('direction', direction);
99 }
100 context.setAttr('font', this._getContextFont());
101 context.setAttr('textBaseline', baseline);
102 context.setAttr('textAlign', LEFT);
103 if (verticalAlign === MIDDLE) {
104 alignY = (this.getHeight() - textArrLen * lineHeightPx - padding * 2) / 2;
105 }
106 else if (verticalAlign === BOTTOM) {
107 alignY = this.getHeight() - textArrLen * lineHeightPx - padding * 2;
108 }
109 context.translate(padding, alignY + padding);
110 for (n = 0; n < textArrLen; n++) {
111 var lineTranslateX = 0;
112 var lineTranslateY = 0;
113 var obj = textArr[n], text = obj.text, width = obj.width, lastLine = obj.lastInParagraph, spacesNumber, oneWord, lineWidth;
114 context.save();
115 if (align === RIGHT) {
116 lineTranslateX += totalWidth - width - padding * 2;
117 }
118 else if (align === CENTER) {
119 lineTranslateX += (totalWidth - width - padding * 2) / 2;
120 }
121 if (shouldUnderline) {
122 context.save();
123 context.beginPath();
124 let yOffset = Global_1.Konva._fixTextRendering
125 ? Math.round(fontSize / 4)
126 : Math.round(fontSize / 2);
127 const x = lineTranslateX;
128 const y = translateY + lineTranslateY + yOffset;
129 context.moveTo(x, y);
130 spacesNumber = text.split(' ').length - 1;
131 oneWord = spacesNumber === 0;
132 lineWidth =
133 align === JUSTIFY && !lastLine ? totalWidth - padding * 2 : width;
134 context.lineTo(x + Math.round(lineWidth), y);
135 context.lineWidth = fontSize / 15;
136 const gradient = this._getLinearGradient();
137 context.strokeStyle = gradient || fill;
138 context.stroke();
139 context.restore();
140 }
141 if (shouldLineThrough) {
142 context.save();
143 context.beginPath();
144 let yOffset = Global_1.Konva._fixTextRendering ? -Math.round(fontSize / 4) : 0;
145 context.moveTo(lineTranslateX, translateY + lineTranslateY + yOffset);
146 spacesNumber = text.split(' ').length - 1;
147 oneWord = spacesNumber === 0;
148 lineWidth =
149 align === JUSTIFY && lastLine && !oneWord
150 ? totalWidth - padding * 2
151 : width;
152 context.lineTo(lineTranslateX + Math.round(lineWidth), translateY + lineTranslateY + yOffset);
153 context.lineWidth = fontSize / 15;
154 const gradient = this._getLinearGradient();
155 context.strokeStyle = gradient || fill;
156 context.stroke();
157 context.restore();
158 }
159 if (direction !== RTL && (letterSpacing !== 0 || align === JUSTIFY)) {
160 spacesNumber = text.split(' ').length - 1;
161 var array = stringToArray(text);
162 for (var li = 0; li < array.length; li++) {
163 var letter = array[li];
164 if (letter === ' ' && !lastLine && align === JUSTIFY) {
165 lineTranslateX += (totalWidth - padding * 2 - width) / spacesNumber;
166 }
167 this._partialTextX = lineTranslateX;
168 this._partialTextY = translateY + lineTranslateY;
169 this._partialText = letter;
170 context.fillStrokeShape(this);
171 lineTranslateX += this.measureSize(letter).width + letterSpacing;
172 }
173 }
174 else {
175 if (letterSpacing !== 0) {
176 context.setAttr('letterSpacing', `${letterSpacing}px`);
177 }
178 this._partialTextX = lineTranslateX;
179 this._partialTextY = translateY + lineTranslateY;
180 this._partialText = text;
181 context.fillStrokeShape(this);
182 }
183 context.restore();
184 if (textArrLen > 1) {
185 translateY += lineHeightPx;
186 }
187 }
188 }
189 _hitFunc(context) {
190 var width = this.getWidth(), height = this.getHeight();
191 context.beginPath();
192 context.rect(0, 0, width, height);
193 context.closePath();
194 context.fillStrokeShape(this);
195 }
196 setText(text) {
197 var str = Util_1.Util._isString(text)
198 ? text
199 : text === null || text === undefined
200 ? ''
201 : text + '';
202 this._setAttr(TEXT, str);
203 return this;
204 }
205 getWidth() {
206 var isAuto = this.attrs.width === AUTO || this.attrs.width === undefined;
207 return isAuto ? this.getTextWidth() + this.padding() * 2 : this.attrs.width;
208 }
209 getHeight() {
210 var isAuto = this.attrs.height === AUTO || this.attrs.height === undefined;
211 return isAuto
212 ? this.fontSize() * this.textArr.length * this.lineHeight() +
213 this.padding() * 2
214 : this.attrs.height;
215 }
216 getTextWidth() {
217 return this.textWidth;
218 }
219 getTextHeight() {
220 Util_1.Util.warn('text.getTextHeight() method is deprecated. Use text.height() - for full height and text.fontSize() - for one line height.');
221 return this.textHeight;
222 }
223 measureSize(text) {
224 var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
225 var _context = getDummyContext(), fontSize = this.fontSize(), metrics;
226 _context.save();
227 _context.font = this._getContextFont();
228 metrics = _context.measureText(text);
229 _context.restore();
230 const scaleFactor = fontSize / 100;
231 return {
232 actualBoundingBoxAscent: (_a = metrics.actualBoundingBoxAscent) !== null && _a !== void 0 ? _a : 71.58203125 * scaleFactor,
233 actualBoundingBoxDescent: (_b = metrics.actualBoundingBoxDescent) !== null && _b !== void 0 ? _b : 0,
234 actualBoundingBoxLeft: (_c = metrics.actualBoundingBoxLeft) !== null && _c !== void 0 ? _c : -7.421875 * scaleFactor,
235 actualBoundingBoxRight: (_d = metrics.actualBoundingBoxRight) !== null && _d !== void 0 ? _d : 75.732421875 * scaleFactor,
236 alphabeticBaseline: (_e = metrics.alphabeticBaseline) !== null && _e !== void 0 ? _e : 0,
237 emHeightAscent: (_f = metrics.emHeightAscent) !== null && _f !== void 0 ? _f : 100 * scaleFactor,
238 emHeightDescent: (_g = metrics.emHeightDescent) !== null && _g !== void 0 ? _g : -20 * scaleFactor,
239 fontBoundingBoxAscent: (_h = metrics.fontBoundingBoxAscent) !== null && _h !== void 0 ? _h : 91 * scaleFactor,
240 fontBoundingBoxDescent: (_j = metrics.fontBoundingBoxDescent) !== null && _j !== void 0 ? _j : 21 * scaleFactor,
241 hangingBaseline: (_k = metrics.hangingBaseline) !== null && _k !== void 0 ? _k : 72.80000305175781 * scaleFactor,
242 ideographicBaseline: (_l = metrics.ideographicBaseline) !== null && _l !== void 0 ? _l : -21 * scaleFactor,
243 width: metrics.width,
244 height: fontSize,
245 };
246 }
247 _getContextFont() {
248 return (this.fontStyle() +
249 SPACE +
250 this.fontVariant() +
251 SPACE +
252 (this.fontSize() + PX_SPACE) +
253 normalizeFontFamily(this.fontFamily()));
254 }
255 _addTextLine(line) {
256 const align = this.align();
257 if (align === JUSTIFY) {
258 line = line.trim();
259 }
260 var width = this._getTextWidth(line);
261 return this.textArr.push({
262 text: line,
263 width: width,
264 lastInParagraph: false,
265 });
266 }
267 _getTextWidth(text) {
268 var letterSpacing = this.letterSpacing();
269 var length = text.length;
270 return (getDummyContext().measureText(text).width +
271 (length ? letterSpacing * (length - 1) : 0));
272 }
273 _setTextData() {
274 var lines = this.text().split('\n'), fontSize = +this.fontSize(), textWidth = 0, lineHeightPx = this.lineHeight() * fontSize, width = this.attrs.width, height = this.attrs.height, fixedWidth = width !== AUTO && width !== undefined, fixedHeight = height !== AUTO && height !== undefined, padding = this.padding(), maxWidth = width - padding * 2, maxHeightPx = height - padding * 2, currentHeightPx = 0, wrap = this.wrap(), shouldWrap = wrap !== NONE, wrapAtWord = wrap !== CHAR && shouldWrap, shouldAddEllipsis = this.ellipsis();
275 this.textArr = [];
276 getDummyContext().font = this._getContextFont();
277 var additionalWidth = shouldAddEllipsis ? this._getTextWidth(ELLIPSIS) : 0;
278 for (var i = 0, max = lines.length; i < max; ++i) {
279 var line = lines[i];
280 var lineWidth = this._getTextWidth(line);
281 if (fixedWidth && lineWidth > maxWidth) {
282 while (line.length > 0) {
283 var low = 0, high = line.length, match = '', matchWidth = 0;
284 while (low < high) {
285 var mid = (low + high) >>> 1, substr = line.slice(0, mid + 1), substrWidth = this._getTextWidth(substr) + additionalWidth;
286 if (substrWidth <= maxWidth) {
287 low = mid + 1;
288 match = substr;
289 matchWidth = substrWidth;
290 }
291 else {
292 high = mid;
293 }
294 }
295 if (match) {
296 if (wrapAtWord) {
297 var wrapIndex;
298 var nextChar = line[match.length];
299 var nextIsSpaceOrDash = nextChar === SPACE || nextChar === DASH;
300 if (nextIsSpaceOrDash && matchWidth <= maxWidth) {
301 wrapIndex = match.length;
302 }
303 else {
304 wrapIndex =
305 Math.max(match.lastIndexOf(SPACE), match.lastIndexOf(DASH)) +
306 1;
307 }
308 if (wrapIndex > 0) {
309 low = wrapIndex;
310 match = match.slice(0, low);
311 matchWidth = this._getTextWidth(match);
312 }
313 }
314 match = match.trimRight();
315 this._addTextLine(match);
316 textWidth = Math.max(textWidth, matchWidth);
317 currentHeightPx += lineHeightPx;
318 var shouldHandleEllipsis = this._shouldHandleEllipsis(currentHeightPx);
319 if (shouldHandleEllipsis) {
320 this._tryToAddEllipsisToLastLine();
321 break;
322 }
323 line = line.slice(low);
324 line = line.trimLeft();
325 if (line.length > 0) {
326 lineWidth = this._getTextWidth(line);
327 if (lineWidth <= maxWidth) {
328 this._addTextLine(line);
329 currentHeightPx += lineHeightPx;
330 textWidth = Math.max(textWidth, lineWidth);
331 break;
332 }
333 }
334 }
335 else {
336 break;
337 }
338 }
339 }
340 else {
341 this._addTextLine(line);
342 currentHeightPx += lineHeightPx;
343 textWidth = Math.max(textWidth, lineWidth);
344 if (this._shouldHandleEllipsis(currentHeightPx) && i < max - 1) {
345 this._tryToAddEllipsisToLastLine();
346 }
347 }
348 if (this.textArr[this.textArr.length - 1]) {
349 this.textArr[this.textArr.length - 1].lastInParagraph = true;
350 }
351 if (fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx) {
352 break;
353 }
354 }
355 this.textHeight = fontSize;
356 this.textWidth = textWidth;
357 }
358 _shouldHandleEllipsis(currentHeightPx) {
359 var fontSize = +this.fontSize(), lineHeightPx = this.lineHeight() * fontSize, height = this.attrs.height, fixedHeight = height !== AUTO && height !== undefined, padding = this.padding(), maxHeightPx = height - padding * 2, wrap = this.wrap(), shouldWrap = wrap !== NONE;
360 return (!shouldWrap ||
361 (fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx));
362 }
363 _tryToAddEllipsisToLastLine() {
364 var width = this.attrs.width, fixedWidth = width !== AUTO && width !== undefined, padding = this.padding(), maxWidth = width - padding * 2, shouldAddEllipsis = this.ellipsis();
365 var lastLine = this.textArr[this.textArr.length - 1];
366 if (!lastLine || !shouldAddEllipsis) {
367 return;
368 }
369 if (fixedWidth) {
370 var haveSpace = this._getTextWidth(lastLine.text + ELLIPSIS) < maxWidth;
371 if (!haveSpace) {
372 lastLine.text = lastLine.text.slice(0, lastLine.text.length - 3);
373 }
374 }
375 this.textArr.splice(this.textArr.length - 1, 1);
376 this._addTextLine(lastLine.text + ELLIPSIS);
377 }
378 getStrokeScaleEnabled() {
379 return true;
380 }
381 _useBufferCanvas() {
382 const hasLine = this.textDecoration().indexOf('underline') !== -1 ||
383 this.textDecoration().indexOf('line-through') !== -1;
384 const hasShadow = this.hasShadow();
385 if (hasLine && hasShadow) {
386 return true;
387 }
388 return super._useBufferCanvas();
389 }
390}
391exports.Text = Text;
392Text.prototype._fillFunc = _fillFunc;
393Text.prototype._strokeFunc = _strokeFunc;
394Text.prototype.className = TEXT_UPPER;
395Text.prototype._attrsAffectingSize = [
396 'text',
397 'fontSize',
398 'padding',
399 'wrap',
400 'lineHeight',
401 'letterSpacing',
402];
403(0, Global_2._registerNode)(Text);
404Factory_1.Factory.overWriteSetter(Text, 'width', (0, Validators_1.getNumberOrAutoValidator)());
405Factory_1.Factory.overWriteSetter(Text, 'height', (0, Validators_1.getNumberOrAutoValidator)());
406Factory_1.Factory.addGetterSetter(Text, 'direction', INHERIT);
407Factory_1.Factory.addGetterSetter(Text, 'fontFamily', 'Arial');
408Factory_1.Factory.addGetterSetter(Text, 'fontSize', 12, (0, Validators_1.getNumberValidator)());
409Factory_1.Factory.addGetterSetter(Text, 'fontStyle', NORMAL);
410Factory_1.Factory.addGetterSetter(Text, 'fontVariant', NORMAL);
411Factory_1.Factory.addGetterSetter(Text, 'padding', 0, (0, Validators_1.getNumberValidator)());
412Factory_1.Factory.addGetterSetter(Text, 'align', LEFT);
413Factory_1.Factory.addGetterSetter(Text, 'verticalAlign', TOP);
414Factory_1.Factory.addGetterSetter(Text, 'lineHeight', 1, (0, Validators_1.getNumberValidator)());
415Factory_1.Factory.addGetterSetter(Text, 'wrap', WORD);
416Factory_1.Factory.addGetterSetter(Text, 'ellipsis', false, (0, Validators_1.getBooleanValidator)());
417Factory_1.Factory.addGetterSetter(Text, 'letterSpacing', 0, (0, Validators_1.getNumberValidator)());
418Factory_1.Factory.addGetterSetter(Text, 'text', '', (0, Validators_1.getStringValidator)());
419Factory_1.Factory.addGetterSetter(Text, 'textDecoration', '');
Note: See TracBrowser for help on using the repository browser.