Mahendra Birla
Mahendra Birla

Reputation: 1

SVG text element text fit in circle border

when i create dynamically svg text circle is working fine in number.but i am using small letter (example:- ffffffiiiisasdasdas) text circle create half but i need full circle and Shape should be react according to content which we are placing ..
please check image following 1.http://tinypic.com/view.php?pic=15fll6b&s=8 2.http://tinypic.com/view.php?pic=fe1181&s=8

following code use

<svg width="845" height="350" viewBox="0 0 845 350"       clip-rule="nonzero"     >
    <g 
        data-ng-attr-fill="{{addText.color}}" 
        data-ng-attr-width="{{addText.w}}"
        data-ng-attr-height="{{addText.h}}"
        data-ng-attr-transform="{{rotate(addText)}}"
        strok  <defs>

        <path stroke-width = "3"
              fill="userSpaceOnUse"
              data-ng-attr-id="temp-{{addText.id}}"
              data-ng-attr-d="{{makeBox1(addText, true)}}" />
        </defs>
        <text ng-if="addText.text"  glyph-orientation-vertical="90" lengthAdjust="spacingAndGlyphs" "
              data-ng-attr-text-anchor="{{addText.text.anchor}}"
              data-ng-attr-font-family="{{addText.text.font}}"
              data-ng-attr-font-style="{{addText.text.italic ? 'italic' : 'none'}}"
              data-ng-attr-font-weight="{{addText.text.bold ? 'bold' : 'normal'}}"
              data-ng-attr-font-size="{{addText.text.size}}"
              data-ng-attr-x="{{arcMid(addText)}}"
              letter-spacing="2";
              style="text-align:justify"
              kerning="8">

            <textPath data-ng-xlink-href="#temp-{{addText.id}}"  method = "stretch"
                      writing-mode="lr-tb"  clip-rule="nonzero"  xlink:href="">
                {{addText.text.text}}</textPath>
        </text>
        <path fill="none" stroke="#EEE" data-ng-attr-d="{{makeBox1(addText,true)}}"  />
    </g>
</svg>

javascript

$scope.makeBox1 = function makeBox1(item, temp) {

    if (item.c == 1) {


        var ma = $('#txtsearch').val();
        var legth = ma.length;

        console.log(legth + "m");
        if (item.r == 0) {
            item.r = item.h / 2;
        }
        var x1 = item.x + item.w / 2,
            y1 = item.y + (item.h),
            x2 = x1 + 1,
            r = item.r;
        if (temp) {
            x1 = 270 + item.w / 2;
            y1 = 30 + (item.h);
            x2 = x1 + 1;
        }

        item.r = ((((((legth) * item.text.size * 5) / (legth / 0.9))) * legth * .02) + (legth * 0.09));
        if (item.r > 137) {

            item.r = 137;
        }
        x1 = 424.5;
        y1 = 293;
        r = item.r;
        x2 = 425.5;
        var y2 = 293




        return "M " + x1 + " " + y1 + " " +
               "A " + r + " " + r + " 0 1 1 " + x2 + " " + y2;
    }  
    }

Upvotes: 0

Views: 498

Answers (1)

Paul LeBeau
Paul LeBeau

Reputation: 101800

It's working for numbers because they always have a fixed width - or almost always. That is because you typically want numbers to align in columns - in invoices for instance.

Your complicated equation for calculating the circle radius is based on the font size. The formula has obviously been tweaked so it works well with the width of numerals in the font you are using. But it won't work with general non-numeric text. Or probably with numerals in a different font.

It is going to be hard to get this to work perfectly in every case, because different browsers may implement their <textPath> elements differently.

The best you can do is to measure the text length, and then calculate the radius from that, by dividing by (2*PI).

You can get the length of the text in a <text> element by calling getComputedTextLength() on the element.

var msg="ffffffiiiisasdasdas";

// Get SVG
var  mysvg = document.getElementById("mysvg");

// Get text length
var tmp = document.createElementNS("http://www.w3.org/2000/svg", "text");
tmp.textContent = msg;
mysvg.appendChild(tmp);
var  len = tmp.getComputedTextLength();
mysvg.removeChild(tmp);
//alert("len = "+len);

// Make the circle path for the msg to sit on
var  x1 = 424.5,
     y1 = 293,
     x2 = 425.5,
     y2 = 293;
var  r = len / (2 * Math.PI);
var circ = document.createElementNS("http://www.w3.org/2000/svg", "path");
circ.setAttribute("id", "circ");
circ.setAttribute("d", "M " + x1 + " " + y1 + " " +
                       "A " + r + " " + r + " 0 1 1 " + x2 + " " + y2);
mysvg.appendChild(circ);

// Make the textPath element
var  tp1 = document.createElementNS("http://www.w3.org/2000/svg", "text");
mysvg.appendChild(tp1);
var  tp2= document.createElementNS("http://www.w3.org/2000/svg", "textPath");
tp2.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#circ");
tp2.textContent = msg;
tp1.appendChild(tp2);
svg text {
    font-family: sans-serif;
    font-size: 20px;
}

#circ {
    fill: none;
    stroke: black;
}
<svg id="mysvg" width="845" height="350" viewBox="0 0 845 350">
</svg>

Upvotes: 2

Related Questions