text-align="middle" _only_ in y-direction? - text

I can use text-align="middle" on a text element to center text. Actually this only works nice for the x-direction. For the y-direction I use the hack of Ian G in question Aligning text in SVG.
But what can I do, if a want to center a text in the y-direction, but want to left-align the text in x-direction?
For example, I have a rect-element and a text-element positioned right of it. The text should be vertically aligned to appear centered in relation to the rect. Therefore I use the text-align="middle" property. But I want to left-align the text in the x-direction (since I want to display it at the right of the rect). That doesn't work, since text-align always applies the both, x and y values.
Actually I am not really happy with the vertical alignment in that way and would prefer something else. But didn't find a better solution yet. (I can't use the dominant-baseline attribute, since I am using Batik, which doesn't support it.) I can't even calculate it myself, since in SVG I have no way to query the ascent/descent/baseline of a font.

The baseline-related attributes, as you have discovered, are not universally supported (yet).
One possible solution is to use a method similar to the old CSS trick for vertical centering.
Set the y coord of the text to the vertical centre of the object you want to center on. Then use dy with an em value to adjust the text verically.
<text x="0" y="100" font-family="Verdana" font-size="20pt" dy="0.35em">Some TEXT</text>
The amount of dy won't be 0.5em as you might think because the visual centre of the font won't be exactly half the em height. It will vary from font to font. But once you find a good dy value for a particular font, it should work for any font-size.
Demo here: http://jsfiddle.net/js88W/1/
Try changing the font-size value to confirm it stays centred.

Related

max-text-length solution for SVG text?

I'm trying to make some text fit into a specific width on my SVG, I noticed that the text-length attribute gets me almost there, but it has the problem of stretching the text in case it's too short.
Either spacingAdnGlyphs and spacing are not involved in the behavior I'm looking for, they define how to stretch the text. What I want is to prevent the stretching from happening at all if it's not required in order to make it fit its container. So a short text should not be altered.
<text
length-adjust="spacingAndGlyphs"
text-length="380"
>
Hello
</text>
Could anyone suggest a way to make my text preserve its original aspect ratio if it's not exceeding the width of my container?

How to clip vega-lite text inside a rect?

In a webpage created with node/webpack, vega-lite, and vegaEmbed, I have a layer with rect marks with short annotations inside them using text marks. I'd like to clip the text to its surrounding rect but haven't figured out a way to do this and hope someone can point me in the right direction.
I realize text has a limit property in pixel units. If I could determine the pixel units of my rect marks (I don't know how to do this), using limit seems like a reasonable approach.
Also, if I knew the pixel extents of my rectangle, I can then write code to align the text within the rect which would be desirable. Currently I just use the same x as the rect, with a dx offset.
I've read about background for text which is a similar problem, but not the same.

SVG Text-anchor top left

By default, the anchor for the text element in SVG is at the bottom left, but I want it to be at the top left, since I am also creating a rectangle to act as the background for the text, but it is displayed incorrectly since the text is higher than the rectangle (because rectangle anchor/offset is at the top left). Is there a way to fix this, so both text and rectangle can be drawn at same coordinates and be displayed in the same location.
The dominant-baseline property/attribute worked for me:
svg {
dominant-baseline: hanging;
}
The coordinates (x and y) you supply for text elements is used as the baseline of the text. This makes sense because if there is text with varying font sizes on the same line, you would want their baselines to line up.
There is no "automatic" way to do what you want. SVG elements are always absolutely positioned.
You will just have to move the text down a bit by making the y coordinate a bit larger.
Alternatively, you could add a dy attribute to shift the text down a bit. Or even use a transform attribute to do the same. But using either of those methods wouldn't really be simplifying the process for you.

Can you right-align an SVG rectangle?

I'm using Raphael to draw rectangles. Whoo-hoo!
Is there a way to right align contents of an SVG file?
Not just text, but shapes as well?
I can do the math and get the computed x value, but I'm looking for the lazy-simple solution.
Thank you.
There isn't. Unlike normal web pages where the window is resized and the content flows into it, when a Raphael paper is resized, there is no sort of flow, so aligning is irrelevant. Instead of setting align=right, you just set the right edge to be the same position you set the width of the paper to be. If you enlarge the paper, you can scale the contents with a single operation. Once you've set the position of the right edge, you've essentially set the align position. You don't need to re-set all edge values when the paper changes size, you just scale everything with one command. Hope that helps

stroke-width doesn't scale; aspect ratio problem?

I have one or more path elements inside a g element that I am scaling to fit inside a grid rectangle. The transform is applied to the g element. My transform works in that all the points end up at the right places, but I discovered that I have to adjust the stroke-width of the path to get a readable line.
The problem is that if the scale involves a large shift in the aspect ratio, I end up with some segments of the path being heavier weight than others, depending on their orientation.
Here is a typical transform that my code computed:
scale(0.1875, -0.010397820616798718) translate(-1149000, -96174)
In this case I end up changing the stroke-width from 9px to about 48px. Segments close to the horizontal end up thin, those close to the vertical are thick.
Is there any easy way to end with all the segments with the same rendered width?
Have you looked at setting the vector-effect attribute to non-scaling-stroke?
<line vector-effect="non-scaling-stroke" stroke="black" stroke-width="5"
x1="32" y1="50" x2="32" y2="350"/>
http://www.w3.org/TR/SVGTiny12/painting.html#NonScalingStroke
UPDATE
The best solution I can think of is to manually transform the coordinates of your path.
vector-effect="non-scaling-vector" is not consistently supported. My versions of Firefox and Safari do not support it, but my Chrome browser does.
In the SVG standard there is no way of specifying a transformation for the stroke independantly. (A stroke-transform attribute would be nice - like the windows GDI+ drawing system, where a Pen object has it's own local transformation).
Until this changes, the best solution I can think of is to manually work out the coordinates of your path - that is the svg has no transform elements; the coordinates are already transformed.

Resources