[英]How to change the height and width of svg <text>,if it is greater than the height and width of svg <rect> in javascript?
<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. 我想调整rect内部的文本,有些文本的宽度大于rect本身的宽度。我想调整文本以使其适合rect内部。
The transform
on the <text>
element complicates things a little. <text>
元素上的transform
使事情有些复杂。
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>
You don't need javascript for this. 您不需要javascript。 I'm putting the text in a
<symbol>
and adapt the symbol to the size of the rect. 我将文本放在
<symbol>
,并使符号适应rect的大小。 However you may use javascript to calculate the viewBox for the <symbol>
element. 但是,您可以使用javascript计算
<symbol>
元素的viewBox。
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. 在此示例中,我演示了如何使用javascript计算
<symbol>
viewBox
属性的值。
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>
The OP is commenting that she/he isn't able to change the SVG but can add elements dynamically. OP表示她/他无法更改SVG,但可以动态添加元素。 In the next example I'm creating the
<symbol>
and the <use>
elements dynamically. 在下一个示例中,我将动态创建
<symbol>
和<use>
元素。 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>
Just do this in JavaScript: 只需在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
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.