Lindell
Lindell

Reputation: 741

Measure not yet created SVG text in javascript

I'm trying to create a function that will measure how big a text element will be in a SVG element. The code examples I found at Stack Overflow does not work and gives a width of zero. If I delay the measurement I can get the text, but not right away. How is this solved?

var messureSVGtext = function(text, svg, options){
   var text = document.createElementNS(svgns, 'text');
   text.style.fontFamily = options.font;

   text.setAttribute("style",
        "font-family:" + options.font + ";" +
        "font-size:" + options.fontSize + "px;"
   );

   var textNode = document.createTextNode(text);

   text.appendChild(textNode);

   svg.appendChild(text);

   // This does not work
   console.log(text.clientWidth);
      
   //This does
   setTimeout(function(){
      console.log(text.clientWidth);
   }, 100);
}

Upvotes: 3

Views: 84

Answers (1)

user4244405
user4244405

Reputation:

You can get the "computed style" of an element and then check the width & height from that.

Give the element an id attribute and after it is appended to the DOM, try this:

var elem1 = document.getElementById("text_elem");
var style = window.getComputedStyle(elem1, null);

console.log(style.width, style.height);


Working example

SVG

<svg
    xmlns="http://www.w3.org/2000/svg"
    version="1.1"
    width="640"
    height="480"
    viewBox="0 0 640 480"
    style="display:block">

    <text id="svg_text" x="20" y="50" style="font-family:Arial; font-size:36px; fill:#BADA55">Hello World!</text>

</svg>


JavaScript

function getCompStyle(oid, cbf)
{
    var obj, stl, itv;

    obj = document.getElementById(oid);
    itv = setInterval(function()
    {
        stl = window.getComputedStyle(obj, null);

        if (stl && (stl.width.indexOf('0') != 0))
        {
            clearInterval(itv);
            cbf(stl);
        }
    },0);

}

getCompStyle('svg_text', function(style)
{
    console.log(style.width);
});

To use the example, place the SVG in your HTML <body> and the JavaScript in a <script> tag below the SVG - also in the <body>.

Upvotes: 1

Related Questions