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

main
Last change on this file since 0c6b92a was 0c6b92a, checked in by stefan toskovski <stefantoska84@…>, 5 weeks ago

Pred finalna verzija

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