diff --git a/src/Stage.ts b/src/Stage.ts index 16900efe..c9eb49a6 100644 --- a/src/Stage.ts +++ b/src/Stage.ts @@ -737,7 +737,7 @@ export class Stage extends Container { // always call preventDefault for desktop events because some browsers // try to drag and drop the canvas element - if (evt.cancelable && eventType !== "touch") { + if (evt.cancelable) { evt.preventDefault(); } } diff --git a/src/shapes/Text.ts b/src/shapes/Text.ts index e2260ee1..3e370d4b 100644 --- a/src/shapes/Text.ts +++ b/src/shapes/Text.ts @@ -492,27 +492,11 @@ export class Text extends Shape { this._addTextLine(match); textWidth = Math.max(textWidth, matchWidth); currentHeightPx += lineHeightPx; - if ( - !shouldWrap || - (fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx) - ) { - var lastLine = this.textArr[this.textArr.length - 1]; - if (lastLine) { - if (shouldAddEllipsis) { - var haveSpace = - this._getTextWidth(lastLine.text + ELLIPSIS) < maxWidth; - if (!haveSpace) { - lastLine.text = lastLine.text.slice( - 0, - lastLine.text.length - 3 - ); - } - - this.textArr.splice(this.textArr.length - 1, 1); - this._addTextLine(lastLine.text + ELLIPSIS); - } - } + var shouldHandleEllipsis = + this._shouldHandleEllipsis(currentHeightPx); + if (shouldHandleEllipsis) { + this._tryToAddEllipsisToLastLine(); /* * stop wrapping if wrapping is disabled or if adding * one more line would overflow the fixed height @@ -542,6 +526,10 @@ export class Text extends Shape { this._addTextLine(line); currentHeightPx += lineHeightPx; textWidth = Math.max(textWidth, lineWidth); + + if (this._shouldHandleEllipsis(currentHeightPx)) { + this._tryToAddEllipsisToLastLine(); + } } // if element height is fixed, abort if adding one more line would overflow if (fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx) { @@ -559,6 +547,52 @@ export class Text extends Shape { this.textWidth = textWidth; } + /** + * whether to handle ellipsis, there are two cases: + * 1. the current line is the last line + * 2. wrap is NONE + * @param {Number} currentHeightPx + * @returns + */ + _shouldHandleEllipsis(currentHeightPx: number): boolean { + 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; + + return ( + !shouldWrap || + (fixedHeight && currentHeightPx + lineHeightPx > maxHeightPx) + ); + } + + _tryToAddEllipsisToLastLine(): void { + var width = this.attrs.width, + fixedWidth = width !== AUTO && width !== undefined, + padding = this.padding(), + maxWidth = width - padding * 2, + shouldAddEllipsis = this.ellipsis(); + + var lastLine = this.textArr[this.textArr.length - 1]; + if (!lastLine || !shouldAddEllipsis) { + return; + } + + if (fixedWidth) { + var haveSpace = this._getTextWidth(lastLine.text + ELLIPSIS) < maxWidth; + if (!haveSpace) { + lastLine.text = lastLine.text.slice(0, lastLine.text.length - 3); + } + } + + this.textArr.splice(this.textArr.length - 1, 1); + this._addTextLine(lastLine.text + ELLIPSIS); + } + // for text we can't disable stroke scaling // if we do, the result will be unexpected getStrokeScaleEnabled() { diff --git a/test/unit/Text-test.ts b/test/unit/Text-test.ts index 42bb8a87..0a70507f 100644 --- a/test/unit/Text-test.ts +++ b/test/unit/Text-test.ts @@ -487,6 +487,39 @@ describe('Text', function () { } }); + // ====================================================== + it('multiline with ellipsis and lineWidth less than maxWidth', function () { + var stage = addStage(); + var layer = new Konva.Layer(); + + var text = new Konva.Text({ + x: 10, + y: 10, + text: "HEADING\nAll the\n world's a stage, merely players. They have theirrrrrrr exits and theirrrrr entrances; And one man in his time plays many parts.", + fontSize: 14, + fontFamily: 'Arial', + fontStyle: 'normal', + width: 100, + padding: 0, + align: 'center', + height: 30, + ellipsis: true, + }); + + layer.add(text); + stage.add(layer); + + assert.equal(text.textArr.length, 2); + assert.equal(text.textArr[1].text.slice(-1), '…'); + + if (isBrowser) { + assert.equal( + layer.getContext().getTrace(false, true), + 'clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);font=normal normal 14px Arial;textBaseline=middle;textAlign=left;translate(0,0);save();fillStyle=black;fillText(HEADING,18,7);restore();save();fillStyle=black;fillText(All the…,23,21);restore();restore();' + ); + } + }); + // ====================================================== it('make sure we respect false for ellipsis', function () { var stage = addStage();