Shahid
Shahid

Reputation: 105

How to position a text element to a specific position and resizable in SVG?

I am creating a rect element based on input values from textbox(getting Height,Width,X and Y from textbox).

When rect is created and appended in parent g element. I am creating a text element showing the newly created rect number.I positioned this text to top left corner of rect.

This is my piece of code(not entire only relevant to question).It is called on onclick event of button.

  //Creating <rect> 
   Rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
   Rect.setAttributeNS(null, "id", "rectId");
   Rect.setAttributeNS(null, "x", x);   //getting x from textbox
   Rect.setAttributeNS(null, "width", width);   //getting width from 
    textbox
   Rect.setAttributeNS(null, "y", y);   //getting y from textbox
   Rect.setAttributeNS(null, "height", height);  //getting height from 
   textbox
   Rect.setAttributeNS(null, "fill", "none");
   grp.appendChild(Rect);


   //Creating <text> for Rect Num
   RectNo = document.createElementNS('http://www.w3.org/2000/svg', 'text');
   RectNo.setAttributeNS(null, "id", "textNo");
   numTxt = document.createTextNode("RectNum_"+(any number));
   RectNo.appendChild(numTxt);
   grp.appendChild(RectNo);

   scale = (width - (width-13)) / width; //(width of rect)
   posX = x+1;  //(x of rect)
   posY = y+3;  //(y of rect)

   RectNo.setAttribute("transform", "translate(" + posX + "," + posY + ") 
   scale(" + scale + ")");

Created rect can be of any size,so for scaling the text element, I tried above code of transform. But somehow it is not working.What I need is that no matter how big or small the rect size is, the RectNo text should appear in the top left-corner of rect and should get adjusted(resize height and width) according to the rect size.

Upvotes: 0

Views: 273

Answers (1)

enxaneta
enxaneta

Reputation: 33044

First I get the width of the text:let txtW = RectNo.getComputedTextLength();

Next I'm calculating the scale: scale = (width-13) / txtW;

I gather that you need a 13 units gap at the end of the text.

Also in the CSS I'm using text{dominant-baseline:hanging}, otherwise you'll get the text half outside the rect. I hope it helps.

let x=10,y=10,width=100,height=50,any_number = 3;

//Creating <rect> 
   Rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
   Rect.setAttributeNS(null, "id", "rectId");
   Rect.setAttributeNS(null, "x", x);   //getting x from textbox
   Rect.setAttributeNS(null, "width", width);   //getting width from textbox
   Rect.setAttributeNS(null, "y", y);   //getting y from textbox
   Rect.setAttributeNS(null, "height", height);  //getting height from textbox
   Rect.setAttributeNS(null, "fill", "#d9d9d9");
   grp.appendChild(Rect);


   //Creating <text> for Rect Num
   RectNo = document.createElementNS('http://www.w3.org/2000/svg', 'text');
   RectNo.setAttributeNS(null, "id", "textNo");
   numTxt = document.createTextNode("RectNum_"+ (Math.random()*100));
   RectNo.appendChild(numTxt);
   
   grp.appendChild(RectNo);

   let txtW = RectNo.getComputedTextLength();

   scale = (width-13) / txtW; 
   posX = x+1;  //(x of rect)
   posY = y+3;  //(y of rect)

   RectNo.setAttribute("transform", "translate(" + posX + "," + posY + ")"+"scale(" + scale + ")");
svg{border:1px solid}
text{dominant-baseline:hanging}
<svg viewBox="0 0 200 100">
  <g id="grp"></g>
</svg>

Upvotes: 0

Related Questions