Svg.js: How is position of text determined

Created on 12 Jun 2017  路  11Comments  路  Source: svgdotjs/svg.js

If I place a text element it seems to be placed down quite a bit and I cannot figure out a) why it does so and b) how to get the measurement I need to move it to the very top.

See this fiddle - http://jsfiddle.net/cyberwombat/Lmu56awz/339/ - why is the text ~40px down?

````
var draw = SVG('drawing').size(700, 700)
var text = draw.text('Hello world')

text.font({
family: 'Helvetica',
size: 104
})
// draw bbox
var b = text.rbox(draw)
draw.rect(b.width, b.height).move(b.x, b.y).fill('none').stroke({
width: 1
})
````

screen shot 2017-06-12 at 11 08 52 am

Thanks

question

All 11 comments

Because you changed the fontsize without changing the position.
Text in svg kinda sucks because it is placed by its baseline. svg.js _tries_ to position it by its upper left edge (like any other shape). We use bbox() to calculate the actual position and move the text so that it will be at the right place. However, when you change fontsize, it does not fit anymore. So to recalculate the position a simple move(0,0) after font would be sufficient

Diving into it I see now that browsers position text quite differently. Safari correctly (or within <1px) positions text on the Y axis but Chrome ads about 7-10% of the font size which results in dramatic shifts in larger fonts.

Attached are two images - the right text is CSS places font and the left is SVG.js using text().move(0,0)

screen shot 2017-07-11 at 2 17 18 pm
screen shot 2017-07-11 at 2 17 37 pm

You can see that the SVG y attribute for the text element is different.

Do you know why this is? I understand that browsers are iffy but is there a fix I can use?

Check the bbox() method in both browsers. If they return different results for text height there is nothing we can do about it.

There is a small pixel difference. - the shot is before I apply any font size (blue is safari). Then the difference gets multiplied tenfold as the font size increases.
screen shot 2017-07-12 at 8 22 17 am
screen shot 2017-07-12 at 8 22 13 am
After font sizing and 0,0 move the boxes heights are quite different. Is this what is used to calculate the <text y="-40" attribute?
screen shot 2017-07-12 at 8 48 38 am
screen shot 2017-07-12 at 8 48 28 am

What I am seeing when I compare the svg text and the regular html/css text in chrome is that the bboxes are the same (besides the x shift). So the svg bbox after transform is correct but the rendered svg is not taking that into account correctly it seems else I assume I would get the same positioning as the css text?

Yes bbox is used to position the text at its upper left edge. And when browser vendors cannot decide which implementation they wanna take I cant do anything about it

I understand. So what I am doing now is this. I have a premade SVG using the same font and size. I use plain JS to get the bbox which tells me how offset Y is and I then adjust my svg object accordingly. Its awkward for sure but does imply that the data is there. Not sure what the better approach is yet but sharing that in case it tickles your brain :)

Update maybe nevermind.. this trick may not be font consistent. Grrrr.

The formulat for positioning is like this:

newY + oldY - bbox().y

This way it moves the text to a position where bbox().y is 0 (which should be then the upper edge of the text)

This can be tamed in 3.0 where text can be moved by baseline, too

@Fuzzyma - you mention positioning by baseline in v3.0 - can you provide a reference to how to utilise this?
Thanks

Just set y directly with attr:

text.attr('y', 50)
Was this page helpful?
0 / 5 - 0 ratings

Related issues

mixn picture mixn  路  9Comments

Zythyr picture Zythyr  路  4Comments

Salitehkat picture Salitehkat  路  4Comments

Fuzzyma picture Fuzzyma  路  8Comments

mroloux picture mroloux  路  8Comments