Get Height of SVG String - text

I'm trying to get the height of an SVG string. I'm getting the width with getComputedTextLength(), which works well, but there doesn't seem to be any equivalent for height.
getBBox() is not an option. It is no longer supported in Firefox, at least not for text, apparently because it is part of SVG 2.0.

For any Element you can use getBoundingClientRect(). have a look here for documentation. In some Browsers the returned rect does not have a height property, but by simple subtracting rect.bottom - rect.top you got it.
Please not that getBoundingClientRect() will return values in absolute space, whereby getBBox() returns values in user space of the element, what can be confusing if it has applied transformations.

getBBox() should work fine for text elements on Firefox.
Here's a demo to prove it.
This worked fine for me in FF 32.

Related

Firefox :animate SVG radius only works with percentages

I am trying to animate the SVG2 Geometry Property r, the radius property of a Circle Element.
I read that the property can be used as CSS property in browsers supporting SVG2 (see Resizing SVG Circle Radius Using CSS Animation).
Now I notice that animating r does only seem to work in Firefox if I express values as percentages. If I use absolute values, the circle is not being animated, see minimum reproduction CodeSandbox.
Does Firefox lack SVG2 support here?
As pointed out, stating lengths in pixel does the job.
The spec indeed says that absolute lenths must be given in physical units.
Omiting them will Chrome use px as fallback unit, while Firefox won't.

SVG lengthAdjust only for shrinking but not for stretching

Is there a nice and easy way to to have the functionality of lengthAdjust (together with textLength) for shrinking text if necessary (if too wide) but never attempting to stretch it?
Two possible solutions for a SVG generated through JS come to my mind:
Count characters (or rather grapheme clusters) and based on that (together with some heuristics unless a fixed-width size font is used) determine whether to set textLength or not.
First do it without textLength set and then determine using getBBox() whether the text needs some shrinking in which case textLength will be set.
Both solutions are IMHO quite ugly (and possibly buggy from my recollections of past encounters with getBBox()). Is there maybe some nicer solution I missed?
Have a look at this: https://stackoverflow.com/a/39886640/1925631
Essentially, make a path which spans the exact coordinates where you want to spread your text on a path. Measure this path. Then, measure how many pixels your text requires, with a font-size of 1px (and other desired font-features). Now adjust the font-size to fill your desired percentage of the available path advance width. Adjust start-offset and text-anchor. Now finally calculate your author specified textLength and choose a lengthAdjust value to get exact alignment on low precision / non-conformant renderers.
Finally, if you need to support viewers without text on a path rendering support, you can use a conformant viewer with javascript support to create a backwards compatible/fallback version. Render the content and use the SVG DOM api to fetch the x, y and rotate values for each character/glyph, now create a new SVG DOM representation with those attributes specified. You might need javascript to calculate absolute width and height for the root svg element as well, and a correctly specified viewBox, and cascade/resolve/convert all css selectors/rules/properties to inline attributes. But this way you can get cross-platform, cross-browser/viewer rendering of text, with a single compilation step per immutable source file version.
I've also made a gist to ease the last step, of resolving the css and removing all classNames, while preserving the rendered end-result: https://gist.github.com/msand/4b37d3ce04246f83cb28fdbfe4716ecc
This is for the purpose of a single universal svg + javascript codebase, and web+ios+android software development (based on react + react-native + react-native-svg)

svg elements - scroll to/ centering

I've an svg dynamically created on a page. As things "happen" (user clicks) the svg expands and collapses certain elements. It may fit in the viewport, it may not. In the case that its too big to fit on a page, the user must scroll to where s(he) wants to go/see. Now this is fine, however I have a requirement that the last element "selected" becomes the center of the page/viewport. i.e. If they click on an item, thats what they need to see without scrolling.
Could anybody tell me the best way to attack this. I've googled around but can't find what I'm looking for (though I'm not long at all this so I might have been searching the wrong stuff).
Is there a way to do this purely programmatically with javascript? Or am I obliged to pass by CSS to get the solution I want. Any tips/links/advice much appreciated.
thanks and have a nice day
G
I had a similar thing and I used the viewBox property to handle this. You could also use a wrapping <g> element, which you translate. However, from my point of view the basic approach is the same and you basically need to do two things:
keep track of the x and y offset and the dimensions of the viewport. (Using the viewBox will give you that »for free«)
Compute the center of the Element. Therefore I used the getBoundingClientRect()method which yields the AABB of of the Element in absolute coordinate space, relative to top-left edge of the whole page.
With these things, all that remains is to calculate the vector from the viewport center to the object's center.
Here you can find the reference of the viewBox and here a nice tutorial about it, because it can be a bit confusing at the beginning.
Another pro for the »viewBox« approach is: There is no dependency on special DOM elements, it just works on the root <svg> element. I once implemented both methods, I started out using a wrapping <g> element, what worked fine but gave me some performance issues. So I decided to change and use the viewBox, with the result, that the performance in Firefox grow, but slowed down in Chromium.
Edit
Here you can find a little fiddle, that outlines the approach. But be aware of the following: getBoundingClientRect() yields the position of the Element on the whole Page, so if your <svg> is not positioned at (0,0) (top: 0px; left: 0px), than that will include the offset of the svg itself. The offset of the viewBox must not include this offset, so you need to cancel that out somehow. For sake of simplicity I just used the client Bounding Rect of the SVG, what works because there are no transformations applied.

IE10 SVG implementation refusing to antialias <rect> elements?

I've been working on a charting library using d3 and SVG to display a series of rectangles. The dataset governs the number of rectangles to be displayed in a given area, and in most cases, the math doesn't work out cleanly, meaning the rectangles don't start and end on whole numbers. Firefox, Chrome and Safari all address this contingency by antialiasing the rectangles. IE seems to just round to the nearest pixel value, and refuses to antialias any rect elements. I've tried changing shape-rendering and the like, to no avail.
Here's a side-by-side comparison of the same data in IE10 and the most recent Chrome release:
IE10:
Chrome:
Is anyone aware of a fix for this that doesn't involve changing the structure of the SVG markup? Setting CSS properties or tag attributes is preferable to changing the elements themselves. Barring that, has anyone seen any Microsoft documentation explaining the rationale for this decision? I haven't been able to turn up any thus far.
IE doesn't seem to care about the shape-rendering property, but I've found that you can force it to anti-alias shapes by specifying a tiny rotate transformation:
svg {
transform: rotate(.00001deg); /* hack to force anti-aliasing in IE */
}
Tested on IE11.

How to Scale SVG rectagle to fit the svg text element

So here is the problem:
I am trying to create dynamic buttons that have text. The text will be generated dynamically so the svg object doesn't know the size of the text. There are two things that I am looking to do and I hope that SVG will do this
First I want the left and right edge of the svg element to stay the same even if I scale the element horizontally
The problem is that I have to set a width on the svg otherwise it doesn't show up when I display the page. Also on the Home and blog buttons you can see that the edge is compressed. I want the edge to stay the same no matter how much text is in the element.
Also I can't seem to set the scale or width properly even with a javascript .getComputedTextLength()
Any help or a point in the right direction would be very helpful
Buttons that are sized to their text content is functionality that can be adressed with Raphael's getBBox()
The use of this js library means that you are implicitly using SVG or VML and this functionality is more easily addressed by referencing this JavaScript library
To see the getBBox() function in action you could visit the Autobox example here:
http://www.irunmywebsite.com/raphael/additionalhelp.php?v=2

Resources