Как изменить высоту и ширину svg <text>, если она больше, чем высота и ширина svg <rect>в javascript? - PullRequest
0 голосов
/ 11 ноября 2018
    <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>

Я хочу настроить текст внутри прямоугольника. Некоторый текст имеет большую ширину, чем ширина самого прямоугольника. Я хочу настроить текст так, чтобы он правильно помещался внутри прямоугольника.

Ответы [ 3 ]

0 голосов
/ 11 ноября 2018

Вам не нужен JavaScript для этого. Я помещаю текст в <symbol> и адаптирую символ к размеру прямоугольника. Однако вы можете использовать javascript для вычисления viewBox для элемента <symbol>.

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>

В этом примере я показываю, как вычислить значение для атрибута <symbol> viewBox, используя 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

ОП комментирует, что она / он не может изменить SVG, но может динамически добавлять элементы. В следующем примере я создаю элементы <symbol> и <use> динамически. Пожалуйста, прочтите комментарии в моем коде.

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>
0 голосов
/ 12 ноября 2018

transform на элементе <text> немного усложняет.

Что я хотел бы сделать, это удалить преобразование, а затем измерить размер текста. Затем вы можете дать ему новое преобразование, которое масштабирует его соответствующим образом и размещает в правильном месте.

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>
0 голосов
/ 11 ноября 2018

Просто сделайте это в 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...