How to change the height and width of svg ,if it is greater than the height and width of svg in javascript?
up vote
0
down vote
favorite
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" transform="matrix(0.7912 0 0 1 111.325 414.395)" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
I want to adjust the text inside a rect.Some text are greater in width than the width of rect itself.I want to adjust the text so that it properly fits inside the rect.
javascript svg
add a comment |
up vote
0
down vote
favorite
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" transform="matrix(0.7912 0 0 1 111.325 414.395)" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
I want to adjust the text inside a rect.Some text are greater in width than the width of rect itself.I want to adjust the text so that it properly fits inside the rect.
javascript svg
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" transform="matrix(0.7912 0 0 1 111.325 414.395)" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
I want to adjust the text inside a rect.Some text are greater in width than the width of rect itself.I want to adjust the text so that it properly fits inside the rect.
javascript svg
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" transform="matrix(0.7912 0 0 1 111.325 414.395)" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
I want to adjust the text inside a rect.Some text are greater in width than the width of rect itself.I want to adjust the text so that it properly fits inside the rect.
javascript svg
javascript svg
edited Nov 11 at 7:50
asked Nov 11 at 7:45
Shahid
268
268
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
up vote
2
down vote
The transform
on the <text>
element complicates things a little.
What I would do is remove the transform, then measure the size of the text. Then you can give it a new transform that scales it appropriately and positions it in the correct place.
adjustText("svg_106", "svg_110");
function adjustText(rectId, textId)
{
var rectElem = document.getElementById(rectId);
var textElem = document.getElementById(textId);
// Get the rectangle bounds
var rectBBox = rectElem.getBBox();
// Clear the text position and transform so we can measure the text bounds properly
textElem.setAttribute("x", "0");
textElem.setAttribute("y", "0");
textElem.removeAttribute("transform");
var textBBox = textElem.getBBox();
// Calculate an adjusted position and scale for the text
var padding = 5; // How much horizontal padding between the text and the rectangle sides
var scale = (rectBBox.width - 2 * padding) / textBBox.width;
var textX = rectBBox.x + padding;
var textY = rectBBox.y + (rectBBox.height / 2) - scale * (textBBox.y + textBBox.height / 2);
// Add a new transform attribute to the text to position it in the new place with the new scale
textElem.setAttribute("transform", "translate("+textX+","+textY+") scale("+scale+")");
}
.newClass {
fill: grey;
}
<svg viewBox="0 300 500 200">
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" transform="matrix(0.7912 0 0 1 111.325 414.395)" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
</svg>
This should work as long as your SVG looks like the example you posted. If things are a bit different from that, this may not work correctly. For example, if the<rect>
has atransform
, then this code will need to be modified.
– Paul LeBeau
Nov 12 at 14:07
Font-size of text gets too smaller.Is there a way that font-size remains constant and we can add a breakline and show the remaining text on nextline
– Shahid
Nov 13 at 7:22
SVG doesn't support multi-line text natively. You would need to break the text up into separate<text>
or<tspan>
elements. You would need to use some javascript code to do that. For example see this question or a library like this one.
– Paul LeBeau
Nov 13 at 11:54
add a comment |
up vote
1
down vote
You don't need javascript for this. I'm putting the text in a <symbol>
and adapt the symbol to the size of the rect. However you may use javascript to calculate the viewBox for the <symbol>
element.
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 100 50">
<symbol id="test" viewBox="0 0 260 19">
<g id="g">
<text class="newText" id="svg_110" dominant-baseline="hanging" >This is a very long text text text text text</text>
</g>
</symbol>
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<use xlink:href="#test" style="pointer-events: inherit;" x="133.2" y="384.5" width="76.2" height="38.1" />
</g>
</svg>
In this example I'm showing how to calculate the value for the <symbol>
viewBox
attribute using javascript.
let bbText = svg_110.getBBox();
test.setAttributeNS(null, "viewBox", `${bbText.x} ${bbText.y} ${bbText.width} ${bbText.height}`)
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 100 50">
<symbol id="test">
<text class="newText" id="svg_110" dominant-baseline="hanging" > This is a very long text text text text text </text>
</symbol>
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<use xlink:href="#test" style="pointer-events: inherit;" x="133.2" y="384.5" width="76.2" height="38.1" />
</g>
</svg>
UPDATE
The OP is commenting that she/he isn't able to change the SVG but can add elements dynamically. In the next example I'm creating the <symbol>
and the <use>
elements dynamically. Please reed the comments in my code.
const SVG_NS = 'http://www.w3.org/2000/svg';
const SVG_XLINK = "http://www.w3.org/1999/xlink";
let theText = document.querySelector("#svg_110");
let theRect = document.querySelector("#svg_106");
// create a new symbol element
let symbol = document.createElementNS(SVG_NS, 'symbol');
symbol.setAttributeNS(null, "id", "theSymbol");
newGroup.appendChild(symbol);
// get the size of the bounding box for the text
let bbText = theText.getBBox();
// set the attribute viewBox for the symbol
symbol.setAttributeNS(null, "viewBox", `${bbText.x} ${bbText.y} ${bbText.width} ${bbText.height}`)
// clone the text and append it to the symbol
let txt=theText.cloneNode(true);
symbol.appendChild(txt);
// remove the text
theText.parentNode.removeChild(theText);
// create a use element
let use = document.createElementNS(SVG_NS, 'use');
// the use element is using the symbol
use.setAttributeNS(SVG_XLINK, 'xlink:href', '#theSymbol');
// also is using the rect's attributes
use.setAttributeNS(null, 'x', theRect.getAttribute("x"));
use.setAttributeNS(null, 'y', theRect.getAttribute("y"));
use.setAttributeNS(null, 'width', theRect.getAttribute("width"));
use.setAttributeNS(null, 'height', theRect.getAttribute("height"));
newGroup.appendChild(use);
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 150 100">
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
</svg>
My SVG is quite big and it is of default format as above,I cant add <symbol> all i can do is to resize the text or add <tspan> dynamically if text is longer
– Shahid
Nov 12 at 5:07
@Shahid I've updated my answer with an extra example where I'm using JS to create thesymbol
and theuse
elements. Please take a look
– enxaneta
Nov 12 at 8:59
add a comment |
up vote
0
down vote
Just do this in JavaScript:
var rect = document.getElementById("svg_106");
var text = document.getElementById("svg_110");
var aRect = rect.getBoundingClientRect();
var bRect = text.getBoundingClientRect();
if (aRect.top + aRect.height) < (bRect.top)) ||
(aRect.top > (bRect.top + bRect.height)) ||
((aRect.left + aRect.width) < bRect.left) ||
(aRect.left > (bRect.left + bRect.width) {
//Do stuff
}
getBoundingClientRect() change their values every time the scrolling position changes.So will i get the perfect value
– Shahid
Nov 12 at 5:12
No problem! If my answer helped you, can you please mark it as accepted?
– Jack Bashford
Nov 12 at 5:13
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
The transform
on the <text>
element complicates things a little.
What I would do is remove the transform, then measure the size of the text. Then you can give it a new transform that scales it appropriately and positions it in the correct place.
adjustText("svg_106", "svg_110");
function adjustText(rectId, textId)
{
var rectElem = document.getElementById(rectId);
var textElem = document.getElementById(textId);
// Get the rectangle bounds
var rectBBox = rectElem.getBBox();
// Clear the text position and transform so we can measure the text bounds properly
textElem.setAttribute("x", "0");
textElem.setAttribute("y", "0");
textElem.removeAttribute("transform");
var textBBox = textElem.getBBox();
// Calculate an adjusted position and scale for the text
var padding = 5; // How much horizontal padding between the text and the rectangle sides
var scale = (rectBBox.width - 2 * padding) / textBBox.width;
var textX = rectBBox.x + padding;
var textY = rectBBox.y + (rectBBox.height / 2) - scale * (textBBox.y + textBBox.height / 2);
// Add a new transform attribute to the text to position it in the new place with the new scale
textElem.setAttribute("transform", "translate("+textX+","+textY+") scale("+scale+")");
}
.newClass {
fill: grey;
}
<svg viewBox="0 300 500 200">
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" transform="matrix(0.7912 0 0 1 111.325 414.395)" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
</svg>
This should work as long as your SVG looks like the example you posted. If things are a bit different from that, this may not work correctly. For example, if the<rect>
has atransform
, then this code will need to be modified.
– Paul LeBeau
Nov 12 at 14:07
Font-size of text gets too smaller.Is there a way that font-size remains constant and we can add a breakline and show the remaining text on nextline
– Shahid
Nov 13 at 7:22
SVG doesn't support multi-line text natively. You would need to break the text up into separate<text>
or<tspan>
elements. You would need to use some javascript code to do that. For example see this question or a library like this one.
– Paul LeBeau
Nov 13 at 11:54
add a comment |
up vote
2
down vote
The transform
on the <text>
element complicates things a little.
What I would do is remove the transform, then measure the size of the text. Then you can give it a new transform that scales it appropriately and positions it in the correct place.
adjustText("svg_106", "svg_110");
function adjustText(rectId, textId)
{
var rectElem = document.getElementById(rectId);
var textElem = document.getElementById(textId);
// Get the rectangle bounds
var rectBBox = rectElem.getBBox();
// Clear the text position and transform so we can measure the text bounds properly
textElem.setAttribute("x", "0");
textElem.setAttribute("y", "0");
textElem.removeAttribute("transform");
var textBBox = textElem.getBBox();
// Calculate an adjusted position and scale for the text
var padding = 5; // How much horizontal padding between the text and the rectangle sides
var scale = (rectBBox.width - 2 * padding) / textBBox.width;
var textX = rectBBox.x + padding;
var textY = rectBBox.y + (rectBBox.height / 2) - scale * (textBBox.y + textBBox.height / 2);
// Add a new transform attribute to the text to position it in the new place with the new scale
textElem.setAttribute("transform", "translate("+textX+","+textY+") scale("+scale+")");
}
.newClass {
fill: grey;
}
<svg viewBox="0 300 500 200">
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" transform="matrix(0.7912 0 0 1 111.325 414.395)" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
</svg>
This should work as long as your SVG looks like the example you posted. If things are a bit different from that, this may not work correctly. For example, if the<rect>
has atransform
, then this code will need to be modified.
– Paul LeBeau
Nov 12 at 14:07
Font-size of text gets too smaller.Is there a way that font-size remains constant and we can add a breakline and show the remaining text on nextline
– Shahid
Nov 13 at 7:22
SVG doesn't support multi-line text natively. You would need to break the text up into separate<text>
or<tspan>
elements. You would need to use some javascript code to do that. For example see this question or a library like this one.
– Paul LeBeau
Nov 13 at 11:54
add a comment |
up vote
2
down vote
up vote
2
down vote
The transform
on the <text>
element complicates things a little.
What I would do is remove the transform, then measure the size of the text. Then you can give it a new transform that scales it appropriately and positions it in the correct place.
adjustText("svg_106", "svg_110");
function adjustText(rectId, textId)
{
var rectElem = document.getElementById(rectId);
var textElem = document.getElementById(textId);
// Get the rectangle bounds
var rectBBox = rectElem.getBBox();
// Clear the text position and transform so we can measure the text bounds properly
textElem.setAttribute("x", "0");
textElem.setAttribute("y", "0");
textElem.removeAttribute("transform");
var textBBox = textElem.getBBox();
// Calculate an adjusted position and scale for the text
var padding = 5; // How much horizontal padding between the text and the rectangle sides
var scale = (rectBBox.width - 2 * padding) / textBBox.width;
var textX = rectBBox.x + padding;
var textY = rectBBox.y + (rectBBox.height / 2) - scale * (textBBox.y + textBBox.height / 2);
// Add a new transform attribute to the text to position it in the new place with the new scale
textElem.setAttribute("transform", "translate("+textX+","+textY+") scale("+scale+")");
}
.newClass {
fill: grey;
}
<svg viewBox="0 300 500 200">
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" transform="matrix(0.7912 0 0 1 111.325 414.395)" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
</svg>
The transform
on the <text>
element complicates things a little.
What I would do is remove the transform, then measure the size of the text. Then you can give it a new transform that scales it appropriately and positions it in the correct place.
adjustText("svg_106", "svg_110");
function adjustText(rectId, textId)
{
var rectElem = document.getElementById(rectId);
var textElem = document.getElementById(textId);
// Get the rectangle bounds
var rectBBox = rectElem.getBBox();
// Clear the text position and transform so we can measure the text bounds properly
textElem.setAttribute("x", "0");
textElem.setAttribute("y", "0");
textElem.removeAttribute("transform");
var textBBox = textElem.getBBox();
// Calculate an adjusted position and scale for the text
var padding = 5; // How much horizontal padding between the text and the rectangle sides
var scale = (rectBBox.width - 2 * padding) / textBBox.width;
var textX = rectBBox.x + padding;
var textY = rectBBox.y + (rectBBox.height / 2) - scale * (textBBox.y + textBBox.height / 2);
// Add a new transform attribute to the text to position it in the new place with the new scale
textElem.setAttribute("transform", "translate("+textX+","+textY+") scale("+scale+")");
}
.newClass {
fill: grey;
}
<svg viewBox="0 300 500 200">
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" transform="matrix(0.7912 0 0 1 111.325 414.395)" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
</svg>
adjustText("svg_106", "svg_110");
function adjustText(rectId, textId)
{
var rectElem = document.getElementById(rectId);
var textElem = document.getElementById(textId);
// Get the rectangle bounds
var rectBBox = rectElem.getBBox();
// Clear the text position and transform so we can measure the text bounds properly
textElem.setAttribute("x", "0");
textElem.setAttribute("y", "0");
textElem.removeAttribute("transform");
var textBBox = textElem.getBBox();
// Calculate an adjusted position and scale for the text
var padding = 5; // How much horizontal padding between the text and the rectangle sides
var scale = (rectBBox.width - 2 * padding) / textBBox.width;
var textX = rectBBox.x + padding;
var textY = rectBBox.y + (rectBBox.height / 2) - scale * (textBBox.y + textBBox.height / 2);
// Add a new transform attribute to the text to position it in the new place with the new scale
textElem.setAttribute("transform", "translate("+textX+","+textY+") scale("+scale+")");
}
.newClass {
fill: grey;
}
<svg viewBox="0 300 500 200">
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" transform="matrix(0.7912 0 0 1 111.325 414.395)" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
</svg>
adjustText("svg_106", "svg_110");
function adjustText(rectId, textId)
{
var rectElem = document.getElementById(rectId);
var textElem = document.getElementById(textId);
// Get the rectangle bounds
var rectBBox = rectElem.getBBox();
// Clear the text position and transform so we can measure the text bounds properly
textElem.setAttribute("x", "0");
textElem.setAttribute("y", "0");
textElem.removeAttribute("transform");
var textBBox = textElem.getBBox();
// Calculate an adjusted position and scale for the text
var padding = 5; // How much horizontal padding between the text and the rectangle sides
var scale = (rectBBox.width - 2 * padding) / textBBox.width;
var textX = rectBBox.x + padding;
var textY = rectBBox.y + (rectBBox.height / 2) - scale * (textBBox.y + textBBox.height / 2);
// Add a new transform attribute to the text to position it in the new place with the new scale
textElem.setAttribute("transform", "translate("+textX+","+textY+") scale("+scale+")");
}
.newClass {
fill: grey;
}
<svg viewBox="0 300 500 200">
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" transform="matrix(0.7912 0 0 1 111.325 414.395)" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
</svg>
answered Nov 12 at 14:05
Paul LeBeau
53.6k56492
53.6k56492
This should work as long as your SVG looks like the example you posted. If things are a bit different from that, this may not work correctly. For example, if the<rect>
has atransform
, then this code will need to be modified.
– Paul LeBeau
Nov 12 at 14:07
Font-size of text gets too smaller.Is there a way that font-size remains constant and we can add a breakline and show the remaining text on nextline
– Shahid
Nov 13 at 7:22
SVG doesn't support multi-line text natively. You would need to break the text up into separate<text>
or<tspan>
elements. You would need to use some javascript code to do that. For example see this question or a library like this one.
– Paul LeBeau
Nov 13 at 11:54
add a comment |
This should work as long as your SVG looks like the example you posted. If things are a bit different from that, this may not work correctly. For example, if the<rect>
has atransform
, then this code will need to be modified.
– Paul LeBeau
Nov 12 at 14:07
Font-size of text gets too smaller.Is there a way that font-size remains constant and we can add a breakline and show the remaining text on nextline
– Shahid
Nov 13 at 7:22
SVG doesn't support multi-line text natively. You would need to break the text up into separate<text>
or<tspan>
elements. You would need to use some javascript code to do that. For example see this question or a library like this one.
– Paul LeBeau
Nov 13 at 11:54
This should work as long as your SVG looks like the example you posted. If things are a bit different from that, this may not work correctly. For example, if the
<rect>
has a transform
, then this code will need to be modified.– Paul LeBeau
Nov 12 at 14:07
This should work as long as your SVG looks like the example you posted. If things are a bit different from that, this may not work correctly. For example, if the
<rect>
has a transform
, then this code will need to be modified.– Paul LeBeau
Nov 12 at 14:07
Font-size of text gets too smaller.Is there a way that font-size remains constant and we can add a breakline and show the remaining text on nextline
– Shahid
Nov 13 at 7:22
Font-size of text gets too smaller.Is there a way that font-size remains constant and we can add a breakline and show the remaining text on nextline
– Shahid
Nov 13 at 7:22
SVG doesn't support multi-line text natively. You would need to break the text up into separate
<text>
or <tspan>
elements. You would need to use some javascript code to do that. For example see this question or a library like this one.– Paul LeBeau
Nov 13 at 11:54
SVG doesn't support multi-line text natively. You would need to break the text up into separate
<text>
or <tspan>
elements. You would need to use some javascript code to do that. For example see this question or a library like this one.– Paul LeBeau
Nov 13 at 11:54
add a comment |
up vote
1
down vote
You don't need javascript for this. I'm putting the text in a <symbol>
and adapt the symbol to the size of the rect. However you may use javascript to calculate the viewBox for the <symbol>
element.
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 100 50">
<symbol id="test" viewBox="0 0 260 19">
<g id="g">
<text class="newText" id="svg_110" dominant-baseline="hanging" >This is a very long text text text text text</text>
</g>
</symbol>
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<use xlink:href="#test" style="pointer-events: inherit;" x="133.2" y="384.5" width="76.2" height="38.1" />
</g>
</svg>
In this example I'm showing how to calculate the value for the <symbol>
viewBox
attribute using javascript.
let bbText = svg_110.getBBox();
test.setAttributeNS(null, "viewBox", `${bbText.x} ${bbText.y} ${bbText.width} ${bbText.height}`)
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 100 50">
<symbol id="test">
<text class="newText" id="svg_110" dominant-baseline="hanging" > This is a very long text text text text text </text>
</symbol>
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<use xlink:href="#test" style="pointer-events: inherit;" x="133.2" y="384.5" width="76.2" height="38.1" />
</g>
</svg>
UPDATE
The OP is commenting that she/he isn't able to change the SVG but can add elements dynamically. In the next example I'm creating the <symbol>
and the <use>
elements dynamically. Please reed the comments in my code.
const SVG_NS = 'http://www.w3.org/2000/svg';
const SVG_XLINK = "http://www.w3.org/1999/xlink";
let theText = document.querySelector("#svg_110");
let theRect = document.querySelector("#svg_106");
// create a new symbol element
let symbol = document.createElementNS(SVG_NS, 'symbol');
symbol.setAttributeNS(null, "id", "theSymbol");
newGroup.appendChild(symbol);
// get the size of the bounding box for the text
let bbText = theText.getBBox();
// set the attribute viewBox for the symbol
symbol.setAttributeNS(null, "viewBox", `${bbText.x} ${bbText.y} ${bbText.width} ${bbText.height}`)
// clone the text and append it to the symbol
let txt=theText.cloneNode(true);
symbol.appendChild(txt);
// remove the text
theText.parentNode.removeChild(theText);
// create a use element
let use = document.createElementNS(SVG_NS, 'use');
// the use element is using the symbol
use.setAttributeNS(SVG_XLINK, 'xlink:href', '#theSymbol');
// also is using the rect's attributes
use.setAttributeNS(null, 'x', theRect.getAttribute("x"));
use.setAttributeNS(null, 'y', theRect.getAttribute("y"));
use.setAttributeNS(null, 'width', theRect.getAttribute("width"));
use.setAttributeNS(null, 'height', theRect.getAttribute("height"));
newGroup.appendChild(use);
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 150 100">
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
</svg>
My SVG is quite big and it is of default format as above,I cant add <symbol> all i can do is to resize the text or add <tspan> dynamically if text is longer
– Shahid
Nov 12 at 5:07
@Shahid I've updated my answer with an extra example where I'm using JS to create thesymbol
and theuse
elements. Please take a look
– enxaneta
Nov 12 at 8:59
add a comment |
up vote
1
down vote
You don't need javascript for this. I'm putting the text in a <symbol>
and adapt the symbol to the size of the rect. However you may use javascript to calculate the viewBox for the <symbol>
element.
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 100 50">
<symbol id="test" viewBox="0 0 260 19">
<g id="g">
<text class="newText" id="svg_110" dominant-baseline="hanging" >This is a very long text text text text text</text>
</g>
</symbol>
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<use xlink:href="#test" style="pointer-events: inherit;" x="133.2" y="384.5" width="76.2" height="38.1" />
</g>
</svg>
In this example I'm showing how to calculate the value for the <symbol>
viewBox
attribute using javascript.
let bbText = svg_110.getBBox();
test.setAttributeNS(null, "viewBox", `${bbText.x} ${bbText.y} ${bbText.width} ${bbText.height}`)
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 100 50">
<symbol id="test">
<text class="newText" id="svg_110" dominant-baseline="hanging" > This is a very long text text text text text </text>
</symbol>
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<use xlink:href="#test" style="pointer-events: inherit;" x="133.2" y="384.5" width="76.2" height="38.1" />
</g>
</svg>
UPDATE
The OP is commenting that she/he isn't able to change the SVG but can add elements dynamically. In the next example I'm creating the <symbol>
and the <use>
elements dynamically. Please reed the comments in my code.
const SVG_NS = 'http://www.w3.org/2000/svg';
const SVG_XLINK = "http://www.w3.org/1999/xlink";
let theText = document.querySelector("#svg_110");
let theRect = document.querySelector("#svg_106");
// create a new symbol element
let symbol = document.createElementNS(SVG_NS, 'symbol');
symbol.setAttributeNS(null, "id", "theSymbol");
newGroup.appendChild(symbol);
// get the size of the bounding box for the text
let bbText = theText.getBBox();
// set the attribute viewBox for the symbol
symbol.setAttributeNS(null, "viewBox", `${bbText.x} ${bbText.y} ${bbText.width} ${bbText.height}`)
// clone the text and append it to the symbol
let txt=theText.cloneNode(true);
symbol.appendChild(txt);
// remove the text
theText.parentNode.removeChild(theText);
// create a use element
let use = document.createElementNS(SVG_NS, 'use');
// the use element is using the symbol
use.setAttributeNS(SVG_XLINK, 'xlink:href', '#theSymbol');
// also is using the rect's attributes
use.setAttributeNS(null, 'x', theRect.getAttribute("x"));
use.setAttributeNS(null, 'y', theRect.getAttribute("y"));
use.setAttributeNS(null, 'width', theRect.getAttribute("width"));
use.setAttributeNS(null, 'height', theRect.getAttribute("height"));
newGroup.appendChild(use);
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 150 100">
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
</svg>
My SVG is quite big and it is of default format as above,I cant add <symbol> all i can do is to resize the text or add <tspan> dynamically if text is longer
– Shahid
Nov 12 at 5:07
@Shahid I've updated my answer with an extra example where I'm using JS to create thesymbol
and theuse
elements. Please take a look
– enxaneta
Nov 12 at 8:59
add a comment |
up vote
1
down vote
up vote
1
down vote
You don't need javascript for this. I'm putting the text in a <symbol>
and adapt the symbol to the size of the rect. However you may use javascript to calculate the viewBox for the <symbol>
element.
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 100 50">
<symbol id="test" viewBox="0 0 260 19">
<g id="g">
<text class="newText" id="svg_110" dominant-baseline="hanging" >This is a very long text text text text text</text>
</g>
</symbol>
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<use xlink:href="#test" style="pointer-events: inherit;" x="133.2" y="384.5" width="76.2" height="38.1" />
</g>
</svg>
In this example I'm showing how to calculate the value for the <symbol>
viewBox
attribute using javascript.
let bbText = svg_110.getBBox();
test.setAttributeNS(null, "viewBox", `${bbText.x} ${bbText.y} ${bbText.width} ${bbText.height}`)
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 100 50">
<symbol id="test">
<text class="newText" id="svg_110" dominant-baseline="hanging" > This is a very long text text text text text </text>
</symbol>
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<use xlink:href="#test" style="pointer-events: inherit;" x="133.2" y="384.5" width="76.2" height="38.1" />
</g>
</svg>
UPDATE
The OP is commenting that she/he isn't able to change the SVG but can add elements dynamically. In the next example I'm creating the <symbol>
and the <use>
elements dynamically. Please reed the comments in my code.
const SVG_NS = 'http://www.w3.org/2000/svg';
const SVG_XLINK = "http://www.w3.org/1999/xlink";
let theText = document.querySelector("#svg_110");
let theRect = document.querySelector("#svg_106");
// create a new symbol element
let symbol = document.createElementNS(SVG_NS, 'symbol');
symbol.setAttributeNS(null, "id", "theSymbol");
newGroup.appendChild(symbol);
// get the size of the bounding box for the text
let bbText = theText.getBBox();
// set the attribute viewBox for the symbol
symbol.setAttributeNS(null, "viewBox", `${bbText.x} ${bbText.y} ${bbText.width} ${bbText.height}`)
// clone the text and append it to the symbol
let txt=theText.cloneNode(true);
symbol.appendChild(txt);
// remove the text
theText.parentNode.removeChild(theText);
// create a use element
let use = document.createElementNS(SVG_NS, 'use');
// the use element is using the symbol
use.setAttributeNS(SVG_XLINK, 'xlink:href', '#theSymbol');
// also is using the rect's attributes
use.setAttributeNS(null, 'x', theRect.getAttribute("x"));
use.setAttributeNS(null, 'y', theRect.getAttribute("y"));
use.setAttributeNS(null, 'width', theRect.getAttribute("width"));
use.setAttributeNS(null, 'height', theRect.getAttribute("height"));
newGroup.appendChild(use);
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 150 100">
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
</svg>
You don't need javascript for this. I'm putting the text in a <symbol>
and adapt the symbol to the size of the rect. However you may use javascript to calculate the viewBox for the <symbol>
element.
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 100 50">
<symbol id="test" viewBox="0 0 260 19">
<g id="g">
<text class="newText" id="svg_110" dominant-baseline="hanging" >This is a very long text text text text text</text>
</g>
</symbol>
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<use xlink:href="#test" style="pointer-events: inherit;" x="133.2" y="384.5" width="76.2" height="38.1" />
</g>
</svg>
In this example I'm showing how to calculate the value for the <symbol>
viewBox
attribute using javascript.
let bbText = svg_110.getBBox();
test.setAttributeNS(null, "viewBox", `${bbText.x} ${bbText.y} ${bbText.width} ${bbText.height}`)
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 100 50">
<symbol id="test">
<text class="newText" id="svg_110" dominant-baseline="hanging" > This is a very long text text text text text </text>
</symbol>
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<use xlink:href="#test" style="pointer-events: inherit;" x="133.2" y="384.5" width="76.2" height="38.1" />
</g>
</svg>
UPDATE
The OP is commenting that she/he isn't able to change the SVG but can add elements dynamically. In the next example I'm creating the <symbol>
and the <use>
elements dynamically. Please reed the comments in my code.
const SVG_NS = 'http://www.w3.org/2000/svg';
const SVG_XLINK = "http://www.w3.org/1999/xlink";
let theText = document.querySelector("#svg_110");
let theRect = document.querySelector("#svg_106");
// create a new symbol element
let symbol = document.createElementNS(SVG_NS, 'symbol');
symbol.setAttributeNS(null, "id", "theSymbol");
newGroup.appendChild(symbol);
// get the size of the bounding box for the text
let bbText = theText.getBBox();
// set the attribute viewBox for the symbol
symbol.setAttributeNS(null, "viewBox", `${bbText.x} ${bbText.y} ${bbText.width} ${bbText.height}`)
// clone the text and append it to the symbol
let txt=theText.cloneNode(true);
symbol.appendChild(txt);
// remove the text
theText.parentNode.removeChild(theText);
// create a use element
let use = document.createElementNS(SVG_NS, 'use');
// the use element is using the symbol
use.setAttributeNS(SVG_XLINK, 'xlink:href', '#theSymbol');
// also is using the rect's attributes
use.setAttributeNS(null, 'x', theRect.getAttribute("x"));
use.setAttributeNS(null, 'y', theRect.getAttribute("y"));
use.setAttributeNS(null, 'width', theRect.getAttribute("width"));
use.setAttributeNS(null, 'height', theRect.getAttribute("height"));
newGroup.appendChild(use);
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 150 100">
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
</svg>
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 100 50">
<symbol id="test" viewBox="0 0 260 19">
<g id="g">
<text class="newText" id="svg_110" dominant-baseline="hanging" >This is a very long text text text text text</text>
</g>
</symbol>
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<use xlink:href="#test" style="pointer-events: inherit;" x="133.2" y="384.5" width="76.2" height="38.1" />
</g>
</svg>
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 100 50">
<symbol id="test" viewBox="0 0 260 19">
<g id="g">
<text class="newText" id="svg_110" dominant-baseline="hanging" >This is a very long text text text text text</text>
</g>
</symbol>
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<use xlink:href="#test" style="pointer-events: inherit;" x="133.2" y="384.5" width="76.2" height="38.1" />
</g>
</svg>
let bbText = svg_110.getBBox();
test.setAttributeNS(null, "viewBox", `${bbText.x} ${bbText.y} ${bbText.width} ${bbText.height}`)
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 100 50">
<symbol id="test">
<text class="newText" id="svg_110" dominant-baseline="hanging" > This is a very long text text text text text </text>
</symbol>
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<use xlink:href="#test" style="pointer-events: inherit;" x="133.2" y="384.5" width="76.2" height="38.1" />
</g>
</svg>
let bbText = svg_110.getBBox();
test.setAttributeNS(null, "viewBox", `${bbText.x} ${bbText.y} ${bbText.width} ${bbText.height}`)
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 100 50">
<symbol id="test">
<text class="newText" id="svg_110" dominant-baseline="hanging" > This is a very long text text text text text </text>
</symbol>
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<use xlink:href="#test" style="pointer-events: inherit;" x="133.2" y="384.5" width="76.2" height="38.1" />
</g>
</svg>
const SVG_NS = 'http://www.w3.org/2000/svg';
const SVG_XLINK = "http://www.w3.org/1999/xlink";
let theText = document.querySelector("#svg_110");
let theRect = document.querySelector("#svg_106");
// create a new symbol element
let symbol = document.createElementNS(SVG_NS, 'symbol');
symbol.setAttributeNS(null, "id", "theSymbol");
newGroup.appendChild(symbol);
// get the size of the bounding box for the text
let bbText = theText.getBBox();
// set the attribute viewBox for the symbol
symbol.setAttributeNS(null, "viewBox", `${bbText.x} ${bbText.y} ${bbText.width} ${bbText.height}`)
// clone the text and append it to the symbol
let txt=theText.cloneNode(true);
symbol.appendChild(txt);
// remove the text
theText.parentNode.removeChild(theText);
// create a use element
let use = document.createElementNS(SVG_NS, 'use');
// the use element is using the symbol
use.setAttributeNS(SVG_XLINK, 'xlink:href', '#theSymbol');
// also is using the rect's attributes
use.setAttributeNS(null, 'x', theRect.getAttribute("x"));
use.setAttributeNS(null, 'y', theRect.getAttribute("y"));
use.setAttributeNS(null, 'width', theRect.getAttribute("width"));
use.setAttributeNS(null, 'height', theRect.getAttribute("height"));
newGroup.appendChild(use);
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 150 100">
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
</svg>
const SVG_NS = 'http://www.w3.org/2000/svg';
const SVG_XLINK = "http://www.w3.org/1999/xlink";
let theText = document.querySelector("#svg_110");
let theRect = document.querySelector("#svg_106");
// create a new symbol element
let symbol = document.createElementNS(SVG_NS, 'symbol');
symbol.setAttributeNS(null, "id", "theSymbol");
newGroup.appendChild(symbol);
// get the size of the bounding box for the text
let bbText = theText.getBBox();
// set the attribute viewBox for the symbol
symbol.setAttributeNS(null, "viewBox", `${bbText.x} ${bbText.y} ${bbText.width} ${bbText.height}`)
// clone the text and append it to the symbol
let txt=theText.cloneNode(true);
symbol.appendChild(txt);
// remove the text
theText.parentNode.removeChild(theText);
// create a use element
let use = document.createElementNS(SVG_NS, 'use');
// the use element is using the symbol
use.setAttributeNS(SVG_XLINK, 'xlink:href', '#theSymbol');
// also is using the rect's attributes
use.setAttributeNS(null, 'x', theRect.getAttribute("x"));
use.setAttributeNS(null, 'y', theRect.getAttribute("y"));
use.setAttributeNS(null, 'width', theRect.getAttribute("width"));
use.setAttributeNS(null, 'height', theRect.getAttribute("height"));
newGroup.appendChild(use);
svg{border:1px solid}
.newClass{stroke:black; fill:none;}
text{fill:black;}
<svg viewBox="130 380 150 100">
<g id="newGroup" >
<rect class="newClass" id="svg_106" x="133.2" y="384.5" width="76.2" height="38.1" />
<text class="newText" id="svg_110" style="pointer-events: inherit;" x="31.5976" y="-12">This is a very long text text text text text</text>
</g>
</svg>
edited Nov 12 at 8:57
answered Nov 11 at 9:20
enxaneta
4,1172413
4,1172413
My SVG is quite big and it is of default format as above,I cant add <symbol> all i can do is to resize the text or add <tspan> dynamically if text is longer
– Shahid
Nov 12 at 5:07
@Shahid I've updated my answer with an extra example where I'm using JS to create thesymbol
and theuse
elements. Please take a look
– enxaneta
Nov 12 at 8:59
add a comment |
My SVG is quite big and it is of default format as above,I cant add <symbol> all i can do is to resize the text or add <tspan> dynamically if text is longer
– Shahid
Nov 12 at 5:07
@Shahid I've updated my answer with an extra example where I'm using JS to create thesymbol
and theuse
elements. Please take a look
– enxaneta
Nov 12 at 8:59
My SVG is quite big and it is of default format as above,I cant add <symbol> all i can do is to resize the text or add <tspan> dynamically if text is longer
– Shahid
Nov 12 at 5:07
My SVG is quite big and it is of default format as above,I cant add <symbol> all i can do is to resize the text or add <tspan> dynamically if text is longer
– Shahid
Nov 12 at 5:07
@Shahid I've updated my answer with an extra example where I'm using JS to create the
symbol
and the use
elements. Please take a look– enxaneta
Nov 12 at 8:59
@Shahid I've updated my answer with an extra example where I'm using JS to create the
symbol
and the use
elements. Please take a look– enxaneta
Nov 12 at 8:59
add a comment |
up vote
0
down vote
Just do this in JavaScript:
var rect = document.getElementById("svg_106");
var text = document.getElementById("svg_110");
var aRect = rect.getBoundingClientRect();
var bRect = text.getBoundingClientRect();
if (aRect.top + aRect.height) < (bRect.top)) ||
(aRect.top > (bRect.top + bRect.height)) ||
((aRect.left + aRect.width) < bRect.left) ||
(aRect.left > (bRect.left + bRect.width) {
//Do stuff
}
getBoundingClientRect() change their values every time the scrolling position changes.So will i get the perfect value
– Shahid
Nov 12 at 5:12
No problem! If my answer helped you, can you please mark it as accepted?
– Jack Bashford
Nov 12 at 5:13
add a comment |
up vote
0
down vote
Just do this in JavaScript:
var rect = document.getElementById("svg_106");
var text = document.getElementById("svg_110");
var aRect = rect.getBoundingClientRect();
var bRect = text.getBoundingClientRect();
if (aRect.top + aRect.height) < (bRect.top)) ||
(aRect.top > (bRect.top + bRect.height)) ||
((aRect.left + aRect.width) < bRect.left) ||
(aRect.left > (bRect.left + bRect.width) {
//Do stuff
}
getBoundingClientRect() change their values every time the scrolling position changes.So will i get the perfect value
– Shahid
Nov 12 at 5:12
No problem! If my answer helped you, can you please mark it as accepted?
– Jack Bashford
Nov 12 at 5:13
add a comment |
up vote
0
down vote
up vote
0
down vote
Just do this in JavaScript:
var rect = document.getElementById("svg_106");
var text = document.getElementById("svg_110");
var aRect = rect.getBoundingClientRect();
var bRect = text.getBoundingClientRect();
if (aRect.top + aRect.height) < (bRect.top)) ||
(aRect.top > (bRect.top + bRect.height)) ||
((aRect.left + aRect.width) < bRect.left) ||
(aRect.left > (bRect.left + bRect.width) {
//Do stuff
}
Just do this in JavaScript:
var rect = document.getElementById("svg_106");
var text = document.getElementById("svg_110");
var aRect = rect.getBoundingClientRect();
var bRect = text.getBoundingClientRect();
if (aRect.top + aRect.height) < (bRect.top)) ||
(aRect.top > (bRect.top + bRect.height)) ||
((aRect.left + aRect.width) < bRect.left) ||
(aRect.left > (bRect.left + bRect.width) {
//Do stuff
}
answered Nov 11 at 8:58
Jack Bashford
3,34131030
3,34131030
getBoundingClientRect() change their values every time the scrolling position changes.So will i get the perfect value
– Shahid
Nov 12 at 5:12
No problem! If my answer helped you, can you please mark it as accepted?
– Jack Bashford
Nov 12 at 5:13
add a comment |
getBoundingClientRect() change their values every time the scrolling position changes.So will i get the perfect value
– Shahid
Nov 12 at 5:12
No problem! If my answer helped you, can you please mark it as accepted?
– Jack Bashford
Nov 12 at 5:13
getBoundingClientRect() change their values every time the scrolling position changes.So will i get the perfect value
– Shahid
Nov 12 at 5:12
getBoundingClientRect() change their values every time the scrolling position changes.So will i get the perfect value
– Shahid
Nov 12 at 5:12
No problem! If my answer helped you, can you please mark it as accepted?
– Jack Bashford
Nov 12 at 5:13
No problem! If my answer helped you, can you please mark it as accepted?
– Jack Bashford
Nov 12 at 5:13
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246789%2fhow-to-change-the-height-and-width-of-svg-text-if-it-is-greater-than-the-heigh%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown