possible fix for all our text problems

This commit is contained in:
Anton Lavrenov 2024-05-15 20:35:26 -05:00
parent fdd0e64aad
commit 0ec3425d99
2 changed files with 82 additions and 31 deletions

View File

@ -201,11 +201,18 @@ export class Text extends Shape<TextConfig> {
shouldUnderline = textDecoration.indexOf('underline') !== -1, shouldUnderline = textDecoration.indexOf('underline') !== -1,
shouldLineThrough = textDecoration.indexOf('line-through') !== -1, shouldLineThrough = textDecoration.indexOf('line-through') !== -1,
n; n;
direction = direction === INHERIT ? context.direction : direction; direction = direction === INHERIT ? context.direction : direction;
var translateY = 0;
var translateY = lineHeightPx / 2; var translateY = lineHeightPx / 2;
const baseline = this.textBaseline();
if (baseline === 'alphabetic') {
var metrics = this.measureSize('M'); // Use a sample character to get the ascent
translateY =
(metrics.fontBoundingBoxAscent - metrics.fontBoundingBoxDescent) / 2 +
lineHeightPx / 2;
}
var lineTranslateX = 0; var lineTranslateX = 0;
var lineTranslateY = 0; var lineTranslateY = 0;
@ -216,11 +223,10 @@ export class Text extends Shape<TextConfig> {
context.setAttr('font', this._getContextFont()); context.setAttr('font', this._getContextFont());
context.setAttr('textBaseline', MIDDLE); context.setAttr('textBaseline', baseline);
context.setAttr('textAlign', LEFT); context.setAttr('textAlign', LEFT);
// handle vertical alignment // handle vertical alignment
if (verticalAlign === MIDDLE) { if (verticalAlign === MIDDLE) {
alignY = (this.getHeight() - textArrLen * lineHeightPx - padding * 2) / 2; alignY = (this.getHeight() - textArrLen * lineHeightPx - padding * 2) / 2;
@ -399,6 +405,18 @@ export class Text extends Shape<TextConfig> {
metrics = _context.measureText(text); metrics = _context.measureText(text);
_context.restore(); _context.restore();
return { return {
// copy all text metrics data:
actualBoundingBoxAscent: metrics.actualBoundingBoxAscent,
actualBoundingBoxDescent: metrics.actualBoundingBoxDescent,
actualBoundingBoxLeft: metrics.actualBoundingBoxLeft,
actualBoundingBoxRight: metrics.actualBoundingBoxRight,
alphabeticBaseline: metrics.alphabeticBaseline,
emHeightAscent: metrics.emHeightAscent,
emHeightDescent: metrics.emHeightDescent,
fontBoundingBoxAscent: metrics.fontBoundingBoxAscent,
fontBoundingBoxDescent: metrics.fontBoundingBoxDescent,
hangingBaseline: metrics.hangingBaseline,
ideographicBaseline: metrics.ideographicBaseline,
width: metrics.width, width: metrics.width,
height: fontSize, height: fontSize,
}; };
@ -637,6 +655,7 @@ export class Text extends Shape<TextConfig> {
direction: GetSet<string, this>; direction: GetSet<string, this>;
fontFamily: GetSet<string, this>; fontFamily: GetSet<string, this>;
textBaseline: GetSet<string, this>;
fontSize: GetSet<number, this>; fontSize: GetSet<number, this>;
fontStyle: GetSet<string, this>; fontStyle: GetSet<string, this>;
fontVariant: GetSet<string, this>; fontVariant: GetSet<string, this>;
@ -703,7 +722,6 @@ Factory.overWriteSetter(Text, 'width', getNumberOrAutoValidator());
Factory.overWriteSetter(Text, 'height', getNumberOrAutoValidator()); Factory.overWriteSetter(Text, 'height', getNumberOrAutoValidator());
/** /**
* get/set direction * get/set direction
* @name Konva.Text#direction * @name Konva.Text#direction
@ -734,6 +752,8 @@ Factory.addGetterSetter(Text, 'direction', INHERIT);
*/ */
Factory.addGetterSetter(Text, 'fontFamily', 'Arial'); Factory.addGetterSetter(Text, 'fontFamily', 'Arial');
Factory.addGetterSetter(Text, 'textBaseline', MIDDLE);
/** /**
* get/set font size in pixels * get/set font size in pixels
* @name Konva.Text#fontSize * @name Konva.Text#fontSize

View File

@ -30,46 +30,77 @@
<script type="module"> <script type="module">
import Konva from '../src/index.ts'; import Konva from '../src/index.ts';
var stageWidth = window.innerWidth;
var stageHeight = window.innerHeight;
var stage = new Konva.Stage({ var stage = new Konva.Stage({
container: 'container', container: 'container',
width: window.innerHeight, width: stageWidth,
height: window.innerHeight, height: stageHeight,
}); });
var layer = new Konva.Layer(); var layer = new Konva.Layer();
stage.add(layer); stage.add(layer);
const circle = new Konva.Circle({ // Stage Background
x: 100, var background = new Konva.Rect({
y: 150, width: stageWidth,
radius: 50, height: stageHeight,
draggable: true, x: 0,
fillLinearGradientStartPoint: { x: -50, y: -50 }, y: 0,
fillLinearGradientEndPoint: { x: 50, y: 50 }, fill: 'red',
fillLinearGradientColorStops: [0, 'red', 1, 'yellow'],
}); });
layer.add(background);
layer.add(circle); // Text Item
var text = new Konva.Text({
const tr = new Konva.Transformer({ text: 'testtest',
nodes: [circle], x: 50,
flipEnabled: false, y: 25,
// width: 400,
// height: 200,
fontSize: 64,
// verticalAlign: 'middle',
align: 'center',
fontFamily: 'Times New Roman',
// textBaseline: 'alphabetic',
}); });
layer.add(tr); layer.add(text);
const dot = new Konva.Circle({ // Top line lining up perfect in MAC OSX CHROME, inline with top of text
x: 100, var topLine = new Konva.Line({
y: 100, points: [125, 103, 400, 103],
radius: 2, stroke: 'green',
fill: 'blue', strokeWidth: 1,
}); });
layer.add(topLine);
layer.add(dot); // Bottom line lining up perfect in MAC OSX CHROME, inline with bottom of text
var bottomLine = new Konva.Line({
circle.on('transform', () => { points: [125, 143, 400, 143],
dot.x(circle.x()); stroke: 'green',
dot.y(circle.y() - circle.radius() * circle.scaleY() - 50); strokeWidth: 1,
}); });
layer.add(bottomLine);
layer.draw();
// Get text bounding box
var textRect = text.getClientRect();
// Create overlay text
var overlayText = document.createElement('div');
overlayText.id = 'overlayText';
overlayText.style.position = 'absolute';
overlayText.style.left = textRect.x + 'px';
overlayText.style.top = textRect.y + 'px';
overlayText.style.width = textRect.width + 'px';
overlayText.style.height = textRect.height + 'px';
overlayText.style.lineHeight = textRect.height + 'px'; // Center vertically
overlayText.style.textAlign = 'center';
overlayText.style.fontSize = '64px';
overlayText.innerHTML = 'testtest';
document.getElementById('container').appendChild(overlayText);
</script> </script>
</body> </body>
</html> </html>