rendering fixes for letter spacing. fix #942

This commit is contained in:
Anton Lavrenov 2020-07-02 17:27:30 -05:00
parent f4ed8a485a
commit 4e1b1c7812
6 changed files with 84 additions and 16 deletions

View File

@ -8,7 +8,7 @@
* Konva JavaScript Framework v7.0.2
* http://konvajs.org/
* Licensed under the MIT
* Date: Tue Jun 30 2020
* Date: Thu Jul 02 2020
*
* Original work Copyright (C) 2011 - 2013 by Eric Rowell (KineticJS)
* Modified work Copyright (C) 2014 - present by Anton Lavrenov (Konva)
@ -5503,7 +5503,7 @@
* because it performs very poorly. Please use the {@link Konva.Stage#getIntersection} method if at all possible
* because it performs much better
* @method
* @name Konva.Container#getIntersection
* @name Konva.Container#getAllIntersections
* @param {Object} pos
* @param {Number} pos.x
* @param {Number} pos.y
@ -13502,7 +13502,7 @@
var letter = text[li];
// skip justify for the last line
if (letter === ' ' && n !== textArrLen - 1 && align === JUSTIFY) {
lineTranslateX += Math.floor((totalWidth - padding * 2 - width) / spacesNumber);
lineTranslateX += (totalWidth - padding * 2 - width) / spacesNumber;
// context.translate(
// Math.floor((totalWidth - padding * 2 - width) / spacesNumber),
// 0
@ -13512,8 +13512,7 @@
this._partialTextY = translateY + lineTranslateY;
this._partialText = letter;
context.fillStrokeShape(this);
lineTranslateX +=
Math.round(this.measureSize(letter).width) + letterSpacing;
lineTranslateX += this.measureSize(letter).width + letterSpacing;
}
}
else {

4
konva.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -308,7 +308,7 @@ export abstract class Container<ChildType extends Node> extends Node<
* because it performs very poorly. Please use the {@link Konva.Stage#getIntersection} method if at all possible
* because it performs much better
* @method
* @name Konva.Container#getIntersection
* @name Konva.Container#getAllIntersections
* @param {Object} pos
* @param {Number} pos.x
* @param {Number} pos.y

View File

@ -13,8 +13,7 @@ import { _registerNode } from './Global';
import * as PointerEvents from './PointerEvents';
import { GetSet, Vector2d } from './types';
import { HitCanvas, SceneCanvas, Canvas } from './Canvas';
import { Container } from './Container';
import { HitCanvas, SceneCanvas } from './Canvas';
// hack from here https://stackoverflow.com/questions/52667959/what-is-the-purpose-of-bivariancehack-in-typescript-types/52668133#52668133
export type ShapeConfigHandler<TTarget> = {

View File

@ -267,9 +267,7 @@ export class Text extends Shape<TextConfig> {
var letter = text[li];
// skip justify for the last line
if (letter === ' ' && n !== textArrLen - 1 && align === JUSTIFY) {
lineTranslateX += Math.floor(
(totalWidth - padding * 2 - width) / spacesNumber
);
lineTranslateX += (totalWidth - padding * 2 - width) / spacesNumber;
// context.translate(
// Math.floor((totalWidth - padding * 2 - width) / spacesNumber),
// 0
@ -279,8 +277,7 @@ export class Text extends Shape<TextConfig> {
this._partialTextY = translateY + lineTranslateY;
this._partialText = letter;
context.fillStrokeShape(this);
lineTranslateX +=
Math.round(this.measureSize(letter).width) + letterSpacing;
lineTranslateX += this.measureSize(letter).width + letterSpacing;
}
} else {
this._partialTextX = lineTranslateX;

View File

@ -559,7 +559,7 @@ suite('Text', function () {
stage.add(layer);
var trace =
'clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);font=normal normal 80px Arial;textBaseline=middle;textAlign=left;translate(0,0);save();save();beginPath();moveTo(0,80);lineTo(189,80);stroke();restore();fillStyle=red;fillText(h,0,40);fillStyle=red;fillText(e,49,40);fillStyle=red;fillText(l,98,40);fillStyle=red;fillText(l,121,40);fillStyle=red;fillText(o,144,40);restore();save();save();beginPath();moveTo(0,160);lineTo(211,160);stroke();restore();fillStyle=red;fillText(w,0,120);fillStyle=red;fillText(o,63,120);fillStyle=red;fillText(r,112,120);fillStyle=red;fillText(l,144,120);fillStyle=red;fillText(d,167,120);restore();restore();';
'clearRect(0,0,578,200);save();transform(1,0,0,1,10,10);font=normal normal 80px Arial;textBaseline=middle;textAlign=left;translate(0,0);save();save();beginPath();moveTo(0,80);lineTo(189,80);stroke();restore();fillStyle=red;fillText(h,0,40);fillStyle=red;fillText(e,49.492,40);fillStyle=red;fillText(l,98.984,40);fillStyle=red;fillText(l,121.758,40);fillStyle=red;fillText(o,144.531,40);restore();save();save();beginPath();moveTo(0,160);lineTo(211,160);stroke();restore();fillStyle=red;fillText(w,0,120);fillStyle=red;fillText(o,62.773,120);fillStyle=red;fillText(r,112.266,120);fillStyle=red;fillText(l,143.906,120);fillStyle=red;fillText(d,166.68,120);restore();restore();';
assert.equal(layer.getContext().getTrace(), trace);
});
@ -749,6 +749,79 @@ suite('Text', function () {
assert.equal(text.getTextWidth() > 0 && text.getTextWidth() < 100, true);
});
test('get text width of long text with spacing (check it visually!)', function () {
var stage = addStage();
stage.draggable(true);
var layer = new Konva.Layer();
stage.add(layer);
var textProps = {
x: 10,
y: 10,
fontSize: 19,
text:
'very long text, very long text, very long text, very long text, very long text, very long text, very long text, very long text, very long text, very long text, very long text, very long text, very long text, very long text.',
draggable: true,
};
var text1 = new Konva.Text(textProps);
layer.add(text1);
var box1 = new Konva.Rect(
Object.assign(text1.getClientRect(), { stroke: 'black' })
);
layer.add(box1);
// demo2
var text2 = new Konva.Text(
Object.assign(textProps, { letterSpacing: 4, y: 50 })
);
layer.add(text2);
var box2 = new Konva.Rect(
Object.assign(text2.getClientRect(), { stroke: 'black' })
);
layer.add(box2);
// demo3
var text3 = new Konva.Text(
Object.assign(textProps, {
text:
'gregrg44g4g4g4g4g4g4g4regrg44g4g4g4g4g4g4g4regrg44g4g4g4g4g4g4g4regrg44g4g4g4g4g4g4g4regrg44g4g4g4g4g4g4g4regrg44g4g4g4g4g4g4g4regrg4g4g4',
letterSpacing: 4,
fontSize: 20,
y: 100,
})
);
layer.add(text3);
var box3 = new Konva.Rect(
Object.assign(text3.getClientRect(), { stroke: 'black' })
);
layer.add(box3);
// demo4
var text4 = new Konva.Text(
Object.assign(textProps, {
text:
'gregrg44g4g4g4g4g4g4g4regrg44g4g4g4g4g4g4g4regrg44g4g4g4g4g4g4g4regrg44g4g4g4g4g4g4g4regrg44g4g4g4g4g4g4g4regrg44g4g4g4g4g4g4g4regrg4g4g4',
letterSpacing: 4,
fontSize: 19,
y: 150,
})
);
layer.add(text4);
var box4 = new Konva.Rect(
Object.assign(text4.getClientRect(), { stroke: 'black' })
);
layer.add(box4);
layer.draw();
assert.almostEqual(text1.width(), 1724.50048828125);
assert.almostEqual(text2.width(), 2612.50048828125);
assert.almostEqual(text3.width(), 2005.376953125);
assert.almostEqual(text4.width(), 1932.30810546875);
});
test('default text color should be black', function () {
var text = new Konva.Text();
assert.equal(text.fill(), 'black');