Положение текста внутри нескольких полигонов SVG - PullRequest
0 голосов
/ 16 февраля 2019

Это часть карты, где мне нужно несколько полигонов с несколькими многострочными текстами в каждом.Возможно ли это без ручного позиционирования каждого текстового элемента?

<svg xmlns="http://www.w3.org/2000/svg" id="estate-masterplan" width="3010" height="1897">
  <g fill="#D8D8D8" fill-rule="evenodd" transform="translate(-0.000000, 0.000000)">
    <rect width="3010" height="1897"/>
    <polygon stroke="#000" points="339 1265.26 351.666 1240.334 390.334 1227.223 408.334 1278.111 365 1294.111 346.556 1286.778"/>
    <text font-size="15" dy="0">
      <tspan x="0" dy=".6em">tspan line 1</tspan>
      <tspan x="0" dy="1.2em">tspan line 2</tspan>
      <tspan x="0" dy="1.2em">tspan line 3</tspan>
    </text>
    <polygon stroke="#000" points="390.334 1227.223 445.444 1209.89 463.307 1265.26 408.334 1278.111"/>
    <text font-size="15" dy="0">
      <tspan x="0" dy=".6em">tspan line 1</tspan>
      <tspan x="0" dy="1.2em">tspan line 2</tspan>
      <tspan x="0" dy="1.2em">tspan line 3</tspan>
    </text>
    <polygon stroke="#000" points="445.444 1209.89 502.777 1199 509 1258.334 493.765 1258.334 463.307 1265.26"/>
    <text font-size="15" dy="0">
      <tspan x="0" dy=".6em">tspan line 1</tspan>
      <tspan x="0" dy="1.2em">tspan line 2</tspan>
      <tspan x="0" dy="1.2em">tspan line 3</tspan>
    </text>
  </g>
</svg>

Ответы [ 2 ]

0 голосов
/ 16 февраля 2019

Я изменил ваш svg, в основном, реорганизовав элементы.Размер estate_masterplan отличается, но вы можете изменить его на то, что вы хотите.

Я использую javascript для вычисления позиции каждого <tspan>.пожалуйста, прочитайте комментарии в коде.Надеюсь, это поможет.

let estate_masterplan = document.querySelector("#estate_masterplan")
// all the groups
let gs = Array.from(estate_masterplan.querySelectorAll("g"));
// all the polygons
let ps = Array.from(estate_masterplan.querySelectorAll("polygon"));

// for each group
gs.forEach((g,i) =>{
  let bb = ps[i].getBBox();// calculate the bounding box
 
  // the center
  let c = {x: bb.x + bb.width/2,
           y: bb.y + bb.height/2}
  
  let t = g.querySelector("text");// the text
  t.setAttributeNS(null, "x", c.x )
  t.setAttributeNS(null, "y", c.y )
  let ts = t.querySelectorAll("tspan")// the tspan-s
  let ts1l = ts[0].getComputedTextLength();// the first span length
 
  ts[1].setAttributeNS(null, "dx", -ts1l )
  ts[2].setAttributeNS(null, "dx", -ts1l )
})
svg{border:1px solid}
text{font-size:9px;dominant-baseline:middle; text-anchor:middle;}

polygon{ fill:#D8D8D8;stroke:black;}
<svg id="estate_masterplan" viewBox="300 1190 270 120">
  <g>
    <polygon points="339 1265.26 351.666 1240.334 390.334 1227.223 408.334 1278.111 365 1294.111 346.556 1286.778"/>
    <text><tspan dy="-9">tspan line 1</tspan><tspan dy="11">tspan line 2</tspan><tspan dy="11">tspan line 3</tspan>
    </text>
  </g>
  
  <g>
    <polygon  points="390.334 1227.223 445.444 1209.89 463.307 1265.26 408.334 1278.111"/>
    <text><tspan dy="-9">tspan line 1</tspan><tspan  dy="11">tspan line 2</tspan><tspan dy="11">tspan line 3</tspan>
    </text>
  </g>
  
  <g>  
    <polygon points="445.444 1209.89 502.777 1199 509 1258.334 493.765 1258.334 463.307 1265.26"/>
    <text><tspan dy="-9">tspan line 1</tspan><tspan  dy="11">tspan line 2</tspan><tspan dy="11">tspan line 3</tspan>
    </text>
   </g>

</svg>
0 голосов
/ 16 февраля 2019

Короткий ответ - нет.У SVG нет автоматического макета, как у HTML.Вы должны расположить текст самостоятельно.

Вы можете использовать Javascript, чтобы вычислить центр ваших многоугольников и расположить текст таким образом.Кроме того, если вы находитесь в браузере, вы можете использовать элемент <foreignObject> для встраивания некоторого HTML в SVG.Но в противном случае вы сами решаете, куда направить каждый фрагмент текста.

...