SVG - как рассчитать координаты x и y после изменения масштаба? - PullRequest
0 голосов
/ 21 февраля 2019

У меня есть такой SVG:

<svg
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  width="630"
  height="430"
>
  <rect
    rx="0"
    ry="0"
    width="100%"
    height="100%"
    fill="rgba(92, 95, 108, 1.0)"
  />
    <line x1="0" y1="176" x2="630" y2="176" style="stroke:rgb(255,0,0);stroke-width:2" />
      <g
        transform="scale(0.2) translate(1300.370746612549 818.9994964599609)"
        style="outline: black solid 2px;"
      >
        <path
          fill="rgba(198, 199, 205, 1.0)"
          d="M414.578,62.68L93.932,122.853c-22.91,4.448-33.326,15.876-33.326,35.457v221.359    c0,19.581,6.1,39.759,32.654,35.457l154.561-29.073l-9.639,63.268l110.875-82.335l65.695-12.019    c23.564-4.135,36.643-15.875,36.643-35.457V98.137C451.395,78.556,434.16,62.68,414.578,62.68z M354.711,235.385    c-5.002,53.956-55.426,97.697-112.623,97.697c-57.203,0-99.508-43.741-94.506-97.697c5.004-53.969,55.428-97.711,112.623-97.711    C317.408,137.674,359.721,181.416,354.711,235.385z M215.049,282.888c-3.109-20.511-6.363-56.128-9.063-76.632    c-1.416-10.769,4.857-14.876,15.098-12.905c28.838,5.537,82.398,16.59,82.398,16.59c11.623,1.416,17.576,11.9,6.578,20.643    c-19.873,15.793-56.912,48.904-78.846,61.547C224.207,296.168,216.229,290.638,215.049,282.888z"
        />
      </g>
</svg>

Как видите, существует групповой элемент со шкалой 0.2.Также эта группа «касается» линии.Это отлично.Однако после изменения масштаба на 0.25 элемент группы неожиданно перемещается в другое место.

<svg
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  width="630"
  height="430"
>
  <rect
    rx="0"
    ry="0"
    width="100%"
    height="100%"
    fill="rgba(92, 95, 108, 1.0)"
  />
    <line x1="0" y1="176" x2="630" y2="176" style="stroke:rgb(255,0,0);stroke-width:2" />
      <g
        transform="scale(0.25) translate(1300.370746612549 818.9994964599609)"
        style="outline: black solid 2px;"
      >
        <path
          fill="rgba(198, 199, 205, 1.0)"
          d="M414.578,62.68L93.932,122.853c-22.91,4.448-33.326,15.876-33.326,35.457v221.359    c0,19.581,6.1,39.759,32.654,35.457l154.561-29.073l-9.639,63.268l110.875-82.335l65.695-12.019    c23.564-4.135,36.643-15.875,36.643-35.457V98.137C451.395,78.556,434.16,62.68,414.578,62.68z M354.711,235.385    c-5.002,53.956-55.426,97.697-112.623,97.697c-57.203,0-99.508-43.741-94.506-97.697c5.004-53.969,55.428-97.711,112.623-97.711    C317.408,137.674,359.721,181.416,354.711,235.385z M215.049,282.888c-3.109-20.511-6.363-56.128-9.063-76.632    c-1.416-10.769,4.857-14.876,15.098-12.905c28.838,5.537,82.398,16.59,82.398,16.59c11.623,1.416,17.576,11.9,6.578,20.643    c-19.873,15.793-56.912,48.904-78.846,61.547C224.207,296.168,216.229,290.638,215.049,282.888z"
        />
      </g>
</svg>

Мой вопрос: как обновить координаты x и y, чтобы группа все еще касалась линии?

Ответы [ 2 ]

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

Это мое решение: я помещаю путь внутрь элемента g и масштабирую путь.Я использую theg.getBBox() значения, чтобы изменить x и y элемента <use>.

let bb = testg.getBBox()
let x = 315 - bb.x - bb.width/2;
let y = 176 - bb.y;
theUse.setAttributeNS(null,"x", x);
theUse.setAttributeNS(null,"y", y);

theRange.addEventListener("input", ()=>{
  thePath.setAttributeNS(null, "transform", `scale(${parseInt(theRange.value)/100})`)
  let bb = testg.getBBox()
  let x = 315 - bb.x - bb.width/2;
  let y = 176 - bb.y;
  theUse.setAttributeNS(null,"x", x);
  theUse.setAttributeNS(null,"y", y);
})
<input id="theRange" type="range" value ="25" /><svg
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  width="630"
  height="430"
>
  
  <defs>   
    <g id="testg">
    <path id="thePath" transform="scale(.45)"
          fill="rgba(198, 199, 205, 1.0)"
          d="M414.578,62.68L93.932,122.853c-22.91,4.448-33.326,15.876-33.326,35.457v221.359    c0,19.581,6.1,39.759,32.654,35.457l154.561-29.073l-9.639,63.268l110.875-82.335l65.695-12.019    c23.564-4.135,36.643-15.875,36.643-35.457V98.137C451.395,78.556,434.16,62.68,414.578,62.68z M354.711,235.385    c-5.002,53.956-55.426,97.697-112.623,97.697c-57.203,0-99.508-43.741-94.506-97.697c5.004-53.969,55.428-97.711,112.623-97.711    C317.408,137.674,359.721,181.416,354.711,235.385z M215.049,282.888c-3.109-20.511-6.363-56.128-9.063-76.632    c-1.416-10.769,4.857-14.876,15.098-12.905c28.838,5.537,82.398,16.59,82.398,16.59c11.623,1.416,17.576,11.9,6.578,20.643    c-19.873,15.793-56.912,48.904-78.846,61.547C224.207,296.168,216.229,290.638,215.049,282.888z"
          /></g>
  </defs>
  <rect
    rx="0"
    ry="0"
    width="100%"
    height="100%"
    fill="rgba(92, 95, 108, 1.0)"
  />
    <line x1="0" y1="176" x2="630" y2="176" style="stroke:rgb(255,0,0);stroke-width:2" />
<line x1="315" y1="0" x2="315" y2="100%" style="stroke:rgb(255,0,0);stroke-width:2" />
       <use id="theUse" xlink:href="#testg"  y="161" />

</svg>
0 голосов
/ 21 февраля 2019
  1. временно удалить атрибут преобразования полностью
  2. выяснить, левый верхний угол элемента пути
  3. переместить путь так, чтобы его левый верхний угол находился в (0, 0)
  4. определяет атрибут преобразования, который переводит группу в место, где вы хотите, чтобы верхний левый угол постоянно находился
  5. вправо ватрибут трансформации, определите масштаб по вашему выбору.

<svg
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  width="630"
  height="430"
>
  <rect
    rx="0"
    ry="0"
    width="100%"
    height="100%"
    fill="rgba(92, 95, 108, 1.0)"
  />
    <line x1="0" y1="176" x2="630" y2="176" style="stroke:rgb(255,0,0);stroke-width:2" />
      <g
        transform="translate(260 176) scale(0.25)"
        style="outline: black solid 2px;"
      >
        <path transform="translate(-60.6, -62.7)"
          fill="rgba(198, 199, 205, 1.0)"
          d="M414.578,62.68L93.932,122.853c-22.91,4.448-33.326,15.876-33.326,35.457v221.359    c0,19.581,6.1,39.759,32.654,35.457l154.561-29.073l-9.639,63.268l110.875-82.335l65.695-12.019    c23.564-4.135,36.643-15.875,36.643-35.457V98.137C451.395,78.556,434.16,62.68,414.578,62.68z M354.711,235.385    c-5.002,53.956-55.426,97.697-112.623,97.697c-57.203,0-99.508-43.741-94.506-97.697c5.004-53.969,55.428-97.711,112.623-97.711    C317.408,137.674,359.721,181.416,354.711,235.385z M215.049,282.888c-3.109-20.511-6.363-56.128-9.063-76.632    c-1.416-10.769,4.857-14.876,15.098-12.905c28.838,5.537,82.398,16.59,82.398,16.59c11.623,1.416,17.576,11.9,6.578,20.643    c-19.873,15.793-56.912,48.904-78.846,61.547C224.207,296.168,216.229,290.638,215.049,282.888z"
        />
      </g>
</svg>

Итак, как узнать верхний левый угол элемента пути?Загрузите его в браузер и в командной строке Javascript выполните

document.querySelector('path').getBBox()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...