简体   繁体   English

如何更改SVG的高度和宽度 <text> ,如果大于svg的高度和宽度 <rect> 在JavaScript中?

[英]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> 

UPDATE UPDATE

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM