1 Вопрос: Как использовать JavaScript для поиска позиции (svg) ранее существовавших элементов в встроенном svg

вопрос создан в Thu, May 2, 2019 12:00 AM

Я пытаюсь использовать JavaScript для рисования линий между различными элементами SVG. Элементы svg находятся в ранее существующем svg-изображении (созданном с помощью inkScape), которое загружается встроенным.

Я зацикливаюсь на поиске правильных координат существующих элементов SVG относительно самого документа SVG для рисования линий.

См. следующий фрагмент, например. Я пытаюсь реализовать функцию FindSVGPosition.

р>

$(function() {
  $("[id^=sys_]").addClass("sysGroup");
  $(".sysGroup").click(function(e) {
    var sysElement = $(this);
    var id = $(sysElement).attr("id");
    var sysName = id.substr(4);
    var metaNameId = "meta_" + sysName;
    var metaElmnt = $("#" + metaNameId);
    if (metaElmnt != undefined) {
      //showCenter('system1');
      if ($(metaElmnt).is(":visible")) {
        $(metaElmnt).hide("fast");
      } else {
        var position = findDOMPosition(sysName);
        $(metaElmnt).css(
          "top",
          window.scrollY + position.height + position.y + 2
        );
        $(metaElmnt).css("left", window.scrollX + position.x);
        $(metaElmnt).show("fast");
      }
    }
  });

  function drawPath(fromSystemName, toSystemName) {
    var pathBetween = findPathBetween(fromSystemName, toSystemName);
    var newLine = document.createElementNS(
      "http://www.w3.org/2000/svg",
      "line"
    );
    newLine.setAttribute(
      "id",
      pathBetween.fromSystemName + "_" + pathBetween.toSystemName
    );
    newLine.setAttribute("x1", pathBetween.fromX);
    newLine.setAttribute("y1", pathBetween.fromY);
    newLine.setAttribute("x2", pathBetween.toX);
    newLine.setAttribute("y2", pathBetween.toY);
    newLine.setAttribute("stroke", "red");
    $("#svg8").append(newLine);
    return pathBetween;
  }

  function findPathBetween(fromSystemName, toSystemName) {
    var fromPosition = findSVGPosition(fromSystemName);
    var toPosition = findSVGPosition(toSystemName);
    if (fromPosition == null || toPosition == null) return null;

    //center to center
    var response = {
      fromSystem: fromSystemName,
      fromX: fromPosition.x + fromPosition.width / 2,
      fromY: fromPosition.top + fromPosition.height / 2,
      fromSide: "center",
      toSystem: toSystemName,
      toX: toPosition.x + toPosition.width / 2,
      toY: toPosition.top + toPosition.height / 2,
      toSide: "center"
    };
    return response;
  }

  function findSVGPosition(systemName) {
    //d.x, d.y, d.top, d.right, d.bottom, d.height
    
  }
  
  function findDOMPosition(systemName) {
    //d.x, d.y, d.top, d.right, d.bottom, d.height
    var systemElement = $("#sys_" + systemName);
    if (systemElement == null) return null;
    return $(systemElement)
      .get(0)
      .getBoundingClientRect();
  }
});
#systemDiagram{
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
.meta{
  width: 350px;
  font-size: smaller;
}
p, ul{
  margin-top: 0px;
}
.metaHeader{
  font-size: large;  
}
text:hover{
  cursor: default;
}
.sysGroup:hover{
    cursor: pointer;
}
.sysGroup text:hover{
  cursor: pointer;
}
#info-box, .meta {
  display: none;
  position: absolute;
  top: 0px;
  left: 0px;
  z-index: 1;
  background-color: #eaeded;
  border: 2px solid #239b56;
  border-radius: 5px;
  padding: 5px;
  font-family: arial;
}
<script src="https://code.jquery.com/jquery-2.2.4.min.js">
</script>
<div>
  <p>lorem ipsum, lorem ipsum, lorem ipsum - lorem other ipsum. lorem ipsum, lorem ipsum, lorem ipsum - lorem other ipsum. lorem ipsum, lorem ipsum, lorem ipsum - lorem other ipsum.</p>
  <p>lorem ipsum, lorem ipsum, lorem ipsum - lorem other ipsum. lorem ipsum, lorem ipsum, lorem ipsum - lorem other ipsum. lorem ipsum, lorem ipsum, lorem ipsum - lorem other ipsum.</p>  
  
</div>
<div id="info-box"></div>
<div class="meta" id="meta_system1">
  <div><span class="metaHeader">Description</span></div>
  <p>description</p>
</div>  
<div class="meta" id="meta_system2">
  <div>Something here for system2</div>
</div>
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="14in"
   height="8.5in"
   viewBox="0 0 355.6 215.9"
   version="1.1"
   id="svg8"
   inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
   sodipodi:docname="drawing.02.svg">
  <defs
     id="defs2" />
  <sodipodi:namedview
     id="base"
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1.0"
     inkscape:pageopacity="0.0"
     inkscape:pageshadow="2"
     inkscape:zoom="1.0404412"
     inkscape:cx="485.6749"
     inkscape:cy="543.80097"
     inkscape:document-units="mm"
     inkscape:current-layer="layer1"
     showgrid="false"
     inkscape:window-width="1920"
     inkscape:window-height="1018"
     inkscape:window-x="-8"
     inkscape:window-y="-8"
     inkscape:window-maximized="1"
     units="in" />
  <metadata
     id="metadata5">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:groupmode="layer"
     id="layer2"
     inkscape:label="systemGroups" />
  <g
     inkscape:groupmode="layer"
     id="layer3"
     inkscape:label="ancillary"
     style="display:none"
     sodipodi:insensitive="true">
    <rect
       style="display:inline;opacity:0.4;fill:#ffcc00;fill-opacity:1;stroke:none;stroke-width:0.23668619"
       id="rect175"
       width="115.25188"
       height="27.459745"
       x="127.27588"
       y="14.725033" />
  </g>
  <g
     inkscape:label="systems"
     inkscape:groupmode="layer"
     id="layer1"
     transform="translate(0,-81.1)"
     style="display:inline">
    <g
       id="sys_system1"
       transform="translate(15.595292,0.08990834)"
       inkscape:label="#g164">
      <rect
         style="fill:#000080;fill-opacity:1;stroke-width:0.1389997"
         y="102.51232"
         x="48.695206"
         height="12.662203"
         width="23.878363"
         id="rect47"
         inkscape:label="#rect4524-9" />
      <text
         id="text51"
         y="110.01817"
         x="51.767498"
         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
         xml:space="preserve"><tspan
           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
           y="110.01817"
           x="51.767498"
           id="tspan49"
           sodipodi:role="line">System1</tspan></text>
    </g>
    <rect
       style="fill:none;fill-opacity:1;stroke-width:0.26458332"
       id="rect95"
       width="177.46696"
       height="27.528765"
       x="10.156241"
       y="95.21151" />
    <rect
       style="fill:none;fill-opacity:1;stroke-width:0.26458332"
       id="rect97"
       width="133.36749"
       height="39.555889"
       x="19.777945"
       y="94.142426" />
    <g
       id="sys_system2"
       inkscape:label="#g90"
       transform="translate(-5.0449918)">
      <rect
         style="fill:#aa8800;fill-opacity:1;stroke-width:0.13352577"
         y="139.75128"
         x="70.257324"
         height="12.662203"
         width="22.034693"
         id="rect47-1"
         inkscape:label="#rect4524-9" />
      <text
         id="text51-2"
         y="147.25714"
         x="73.32962"
         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
         xml:space="preserve"><tspan
           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';fill:#000000;fill-opacity:1;stroke-width:0.26458332"
           y="147.25714"
           x="73.32962"
           id="tspan49-8"
           sodipodi:role="line">System2</tspan></text>
    </g>
  </g>
</svg>

Я могу найти координаты элементов svg относительно DOM и правильно разместить div под этими элементами.

Я могу нарисовать линию на svg, используя javascript при произвольном запуске & конечные точки.

Я не могу получить доступ к атрибутам svg (x, y, высота, ширина) существующих элементов svg относительно изображения svg.

Большинство примеров, которые я могу найти, используют contentDocument элемента svg. Но в моем случае, что бы я ни пробовал - contentDocument имеет значение null.

Поскольку я не запускаю это действие при загрузке страницы, я уверен, что svg должен быть полностью загружен в dom при запуске кода.

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

    
0
1 ответ                              1                         
  1. Во-первых, вы все усложняете для себя из-за всех атрибутов transform для элементов в SVG. Моя первая рекомендация - избавиться от них всех.

    Самый простой способ сделать это в Inkscape - это разгруппировать, а затем перегруппировать объекты.

  2. Если вы это сделаете, ваша функция проста:

    function findSVGPosition(systemName) {
      return document.getElementById(systemName).getBBox();
    }
    

    Функция getBBox() возвращает ограничительную рамку элемента SVG. Но ограничивающий прямоугольник не учитывает преобразования элемента или его родительских элементов. Границы не будут полезны, если есть преобразования. Вот почему мы избавились от них на шаге № 1.

  3. Далее исправьте опечатки в findPathBetween(): .top должен .y.

  4. Наконец, вам нужно вызвать функцию drawPath().

    drawPath('sys_system1', 'sys_system2');
    
  5. Но линия сверху коробок. Таким образом, вы, вероятно, захотите сделать .prepend() вместо .append(). Таким образом, строка находится перед - и, следовательно, под - полями.

    $("#svg8").prepend(newLine);
    

Тогда вы в конечном итоге с этим.

р>

function drawPath(fromSystemName, toSystemName) {
    var pathBetween = findPathBetween(fromSystemName, toSystemName);
    var newLine = document.createElementNS(
      "http://www.w3.org/2000/svg",
      "line"
    );
    newLine.setAttribute(
      "id",
      pathBetween.fromSystemName + "_" + pathBetween.toSystemName
    );
    newLine.setAttribute("x1", pathBetween.fromX);
    newLine.setAttribute("y1", pathBetween.fromY);
    newLine.setAttribute("x2", pathBetween.toX);
    newLine.setAttribute("y2", pathBetween.toY);
    newLine.setAttribute("stroke", "red");
    $("#svg8").prepend(newLine);
    return pathBetween;
  }

  function findPathBetween(fromSystemName, toSystemName) {
    var fromPosition = findSVGPosition(fromSystemName);
    var toPosition = findSVGPosition(toSystemName);
    if (fromPosition == null || toPosition == null) return null;

    //center to center
    var response = {
      fromSystem: fromSystemName,
      fromX: fromPosition.x + fromPosition.width / 2,
      fromY: fromPosition.y + fromPosition.height / 2,
      fromSide: "center",
      toSystem: toSystemName,
      toX: toPosition.x + toPosition.width / 2,
      toY: toPosition.y + toPosition.height / 2,
      toSide: "center"
    };
    return response;
  }

  function findSVGPosition(systemName) {
    return document.getElementById(systemName).getBBox();
  }
  
  
  
  drawPath('sys_system1', 'sys_system2');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="14in"
   height="8.5in"
   viewBox="0 0 355.6 215.9"
   version="1.1"
   id="svg8"
   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
   sodipodi:docname="line.svg">
  <defs
     id="defs2" />
  <sodipodi:namedview
     id="base"
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1.0"
     inkscape:pageopacity="0.0"
     inkscape:pageshadow="2"
     inkscape:zoom="1.0404412"
     inkscape:cx="166.09894"
     inkscape:cy="543.80097"
     inkscape:document-units="mm"
     inkscape:current-layer="svg8"
     showgrid="false"
     inkscape:window-width="2560"
     inkscape:window-height="1378"
     inkscape:window-x="1592"
     inkscape:window-y="-8"
     inkscape:window-maximized="1"
     units="in" />
  <metadata
     id="metadata5">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title />
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:groupmode="layer"
     id="layer2"
     inkscape:label="systemGroups"
     style="display:inline" />
  <g
     inkscape:groupmode="layer"
     id="layer3"
     inkscape:label="ancillary"
     style="display:none"
     sodipodi:insensitive="true">
    <rect
       style="display:inline;opacity:0.4;fill:#ffcc00;fill-opacity:1;stroke:none;stroke-width:0.23668619"
       id="rect175"
       width="115.25188"
       height="27.459745"
       x="127.27588"
       y="14.725033" />
  </g>
  <g
     id="g864"
     inkscape:label="systems">
    <g
       id="sys_system1">
      <rect
         style="fill:#000080;fill-opacity:1;stroke-width:0.1389997"
         y="21.502226"
         x="64.290497"
         height="12.662203"
         width="23.878363"
         id="rect47"
         inkscape:label="#rect4524-9" />
      <text
         id="text51"
         y="29.008078"
         x="67.362793"
         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
         xml:space="preserve"><tspan
           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
           y="29.008078"
           x="67.362793"
           id="tspan49"
           sodipodi:role="line">System1</tspan></text>
    </g>
    <rect
       style="fill:none;fill-opacity:1;stroke-width:0.26458332"
       id="rect95"
       width="177.46696"
       height="27.528765"
       x="10.156241"
       y="14.111509" />
    <rect
       style="fill:none;fill-opacity:1;stroke-width:0.26458332"
       id="rect97"
       width="133.36749"
       height="39.555889"
       x="19.777945"
       y="13.042425" />
    <g
       id="sys_system2">
      <rect
         style="fill:#aa8800;fill-opacity:1;stroke-width:0.13352577"
         y="58.651283"
         x="65.212334"
         height="12.662203"
         width="22.034693"
         id="rect47-1"
         inkscape:label="#rect4524-9" />
      <text
         id="text51-2"
         y="66.157143"
         x="68.28463"
         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
         xml:space="preserve"><tspan
           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';fill:#000000;fill-opacity:1;stroke-width:0.26458332"
           y="66.157143"
           x="68.28463"
           id="tspan49-8"
           sodipodi:role="line">System2</tspan></text>
    </g>
  </g>
</svg>

Обновление - лучшая версия

Вот лучшая версия, в которой не требуется перенастраивать все преобразования в Inkscape.

В этой версии мы выбираем наши конечные точки линии, а затем используем

function drawPath(fromSystemName, toSystemName) {
    var pathBetween = findPathBetween(fromSystemName, toSystemName);
    var newLine = document.createElementNS(
      "http://www.w3.org/2000/svg",
      "line"
    );
    newLine.setAttribute(
      "id",
      pathBetween.fromSystemName + "_" + pathBetween.toSystemName
    );
    newLine.setAttribute("x1", pathBetween.fromX);
    newLine.setAttribute("y1", pathBetween.fromY);
    newLine.setAttribute("x2", pathBetween.toX);
    newLine.setAttribute("y2", pathBetween.toY);
    newLine.setAttribute("stroke", "red");
    $("#svg8").prepend(newLine);
    return pathBetween;
  }

  function findPathBetween(fromSystemName, toSystemName) {
    var fromPosition = findSVGPosition(fromSystemName);
    var toPosition = findSVGPosition(toSystemName);
    if (fromPosition == null || toPosition == null) return null;

    //center to center
    var response = {
      fromSystem: fromSystemName,
      fromX: fromPosition.x + fromPosition.width / 2,
      fromY: fromPosition.y + fromPosition.height / 2,
      fromSide: "center",
      toSystem: toSystemName,
      toX: toPosition.x + toPosition.width / 2,
      toY: toPosition.y + toPosition.height / 2,
      toSide: "center"
    };
    return response;
  }

  function findSVGPosition(systemName) {
    return document.getElementById(systemName).getBBox();
  }
  
  
  
  drawPath('sys_system1', 'sys_system2');
, чтобы найти общее преобразование от элемента к странице.

Небольшое осложнение заключается в том, что

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="14in"
   height="8.5in"
   viewBox="0 0 355.6 215.9"
   version="1.1"
   id="svg8"
   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
   sodipodi:docname="line.svg">
  <defs
     id="defs2" />
  <sodipodi:namedview
     id="base"
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1.0"
     inkscape:pageopacity="0.0"
     inkscape:pageshadow="2"
     inkscape:zoom="1.0404412"
     inkscape:cx="166.09894"
     inkscape:cy="543.80097"
     inkscape:document-units="mm"
     inkscape:current-layer="svg8"
     showgrid="false"
     inkscape:window-width="2560"
     inkscape:window-height="1378"
     inkscape:window-x="1592"
     inkscape:window-y="-8"
     inkscape:window-maximized="1"
     units="in" />
  <metadata
     id="metadata5">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title />
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:groupmode="layer"
     id="layer2"
     inkscape:label="systemGroups"
     style="display:inline" />
  <g
     inkscape:groupmode="layer"
     id="layer3"
     inkscape:label="ancillary"
     style="display:none"
     sodipodi:insensitive="true">
    <rect
       style="display:inline;opacity:0.4;fill:#ffcc00;fill-opacity:1;stroke:none;stroke-width:0.23668619"
       id="rect175"
       width="115.25188"
       height="27.459745"
       x="127.27588"
       y="14.725033" />
  </g>
  <g
     id="g864"
     inkscape:label="systems">
    <g
       id="sys_system1">
      <rect
         style="fill:#000080;fill-opacity:1;stroke-width:0.1389997"
         y="21.502226"
         x="64.290497"
         height="12.662203"
         width="23.878363"
         id="rect47"
         inkscape:label="#rect4524-9" />
      <text
         id="text51"
         y="29.008078"
         x="67.362793"
         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
         xml:space="preserve"><tspan
           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
           y="29.008078"
           x="67.362793"
           id="tspan49"
           sodipodi:role="line">System1</tspan></text>
    </g>
    <rect
       style="fill:none;fill-opacity:1;stroke-width:0.26458332"
       id="rect95"
       width="177.46696"
       height="27.528765"
       x="10.156241"
       y="14.111509" />
    <rect
       style="fill:none;fill-opacity:1;stroke-width:0.26458332"
       id="rect97"
       width="133.36749"
       height="39.555889"
       x="19.777945"
       y="13.042425" />
    <g
       id="sys_system2">
      <rect
         style="fill:#aa8800;fill-opacity:1;stroke-width:0.13352577"
         y="58.651283"
         x="65.212334"
         height="12.662203"
         width="22.034693"
         id="rect47-1"
         inkscape:label="#rect4524-9" />
      <text
         id="text51-2"
         y="66.157143"
         x="68.28463"
         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;line-height:1.25;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
         xml:space="preserve"><tspan
           style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333311px;font-family:'Segoe UI';-inkscape-font-specification:'Segoe UI';fill:#000000;fill-opacity:1;stroke-width:0.26458332"
           y="66.157143"
           x="68.28463"
           id="tspan49-8"
           sodipodi:role="line">System2</tspan></text>
    </g>
  </g>
</svg>
включает в себя все преобразования. Включая преобразование, вызванное масштабированием getCTM(). Но мы не хотим, чтобы преобразование включало этот последний шаг. Итак, чтобы исправить это, мы вызываем getCTM() для корневого элемента viewBox, а затем используем его для отмены части преобразования getCTM.

р>

<svg>
    
3
2019-05-08 16: 17: 25Z
  1. Пол Лебо: Большое спасибо за определение преобразований. Я не добавил эти преобразования намеренно. Очевидно, они являются побочным продуктом того, как inkscape сохраняет файлы. Я также попробовал getBBox (), но он не работал с преобразованиями на месте, поэтому эти преобразования определенно являются виновником. Благодаря вашему пониманию я смог отследить другие обсуждения переполнения стека по этой проблеме, а также тему форума inkscape: forum.inkscapecommunity.com/… А>
    2019-05-03 14: 38: 24Z
  2. Похоже, не существует простого способа решения проблемы преобразования, кроме разгруппирования /перегруппировки каждой группы, что в моем конкретном приложении вызовет значительные трудности приклад.
    2019-05-03 14: 42: 07Z
  3. Ох. Это боль. К сожалению, разгруппировка и перегруппировка также сбрасывает идентификатор группы и метку inkscpe. Что еще хуже. Проверьте, есть ли плагин для Inkscape, который это делает.
    2019-05-03 15: 53: 41Z
  4. Раньше я был немного ленив, потому что думал, что вам нужно исправить только один SVG. Однако теперь я обновил свой ответ решением, которое работает, даже если присутствуют преобразования.
    2019-05-03 17: 03: 51Z
  5. Эй, Пол, у меня наконец-то появилась возможность взглянуть на ваше улучшенное решение, и когда я загружаю фрагмент кода, он выдает ошибку (ниже). Я действительно надеюсь, что это сработает так, как вы описали, для меня это будет огромной экономией. "message": "Ошибка типа: elem.ownerSVGElement.getCTM (...) имеет значение null", "имя файла": " stacksnippets. net /js "," lineno ": 196," colno ": 34
    2019-05-08 13: 54: 34Z
viewBox
источник размещен Вот