Как найти размер SVG программно? - PullRequest
0 голосов
/ 03 мая 2018

У меня есть несколько файлов SVG разных компонентов. Каждый из этих компонентов может содержать или не содержать «порт», который я хочу игнорировать при определении размера svg. Например, вот 2 вида SVG, которые у меня есть:

<svg width="263" height="203" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <g class="component">
        <polygon points="41.5,201.5 241.5,201.5 241.5,1.5 41.5,1.5" fill="#FFFFFF" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polyline points="41.5,41.5 67.5,77.5 97.5,77.5" fill-opacity="0" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polyline points="41.5,161.5 67.5,129.5 99.5,129.5" fill-opacity="0" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polygon points="191.5,101.5 191.3,97.2 190.8,92.9 189.8,88.7 188.6,84.6 186.9,80.6 185.0,76.8 182.7,73.2 180.1,69.7 177.2,66.5 174.1,63.6 170.7,60.9 167.1,58.6 163.3,56.5 159.4,54.8 155.3,53.4 151.1,52.4 146.9,51.8 142.6,51.5 138.3,51.6 134.0,52.1 129.8,52.9 125.6,54.1 121.6,55.6 117.8,57.5 114.1,59.7 110.6,62.2 107.3,65.0 104.3,68.1 101.6,71.4 99.1,75.0 97.0,78.7 95.2,82.6 93.8,86.7 92.7,90.8 91.9,95.1 91.5,99.3 91.5,103.7 91.9,107.9 92.7,112.2 93.8,116.3 95.2,120.4 97.0,124.3 99.1,128.0 101.6,131.6 104.3,134.9 107.3,138.0 110.6,140.8 114.1,143.3 117.8,145.5 121.6,147.4 125.6,148.9 129.8,150.1 134.0,150.9 138.3,151.4 142.6,151.5 146.9,151.2 151.1,150.6 155.3,149.6 159.4,148.2 163.3,146.5 167.1,144.4 170.7,142.1 174.1,139.4 177.2,136.5 180.1,133.3 182.7,129.8 185.0,126.2 186.9,122.4 188.6,118.4 189.8,114.3 190.8,110.1 191.3,105.8" fill-opacity="0" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polyline points="191.5,101.5 241.5,101.5" fill-opacity="0" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <text x="141.5" y="133.8" text-anchor="middle" fill="#000000" font-size="90.3px" font-family="sans-serif">+</text>
        <text x="94.0" y="48.7" text-anchor="middle" fill="#000000" font-size="53.1px" font-family="sans-serif">1</text>
        <text x="94.0" y="192.7" text-anchor="middle" fill="#000000" font-size="53.1px" font-family="sans-serif">1</text>
        <g id="u1" class="port">
            <polygon points="1.5,21.5 41.5,41.5 1.5,61.5" fill="#00007F" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        </g>
        <g id="u2" class="port">
            <polygon points="1.5,141.5 41.5,161.5 1.5,181.5" fill="#00007F" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        </g>
        <g id="y" class="port">
            <polygon points="241.5,91.5 261.5,101.5 241.5,111.5" fill="#FFFFFF" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        </g>
    </g>
</svg>

<svg width="223" height="203" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <g class="component">
        <polygon points="1.5,201.5 201.5,201.5 201.5,1.5 1.5,1.5" fill="#FFFFFF" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polyline points="21.5,33.5 21.5,181.5" fill-opacity="0" stroke="#C0C0C0" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polygon points="21.5,11.5 13.5,33.5 29.5,33.5" fill="#C0C0C0" stroke="#C0C0C0" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polyline points="11.5,101.5 169.5,101.5" fill-opacity="0" stroke="#C0C0C0" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polygon points="191.5,101.5 169.5,93.5 169.5,109.5" fill="#C0C0C0" stroke="#C0C0C0" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polyline points="21.5,101.5 27.2,84.4 30.7,73.8 33.8,65.0 36.4,57.8 36.4,57.8 38.2,53.3 39.9,49.1 41.6,45.2 43.2,41.8 43.2,41.8 44.5,39.2 45.7,36.8 46.9,34.7 48.1,32.7 49.2,31.0 49.2,31.0 50.7,29.1 52.1,27.4 53.5,25.9 54.9,24.6 54.9,24.6 56.8,23.4 58.6,22.5 60.5,22.0 60.5,22.0 62.4,22.0 64.2,22.5 66.1,23.3 66.1,23.3 67.5,24.2 68.9,25.4 70.3,26.7 71.8,28.4 71.8,28.4 72.9,29.8 74.0,31.4 75.2,33.1 76.3,35.0 77.4,37.0 77.4,37.0 78.8,39.7 80.3,42.7 81.8,46.1 83.4,49.8 83.4,49.8 85.6,55.3 88.0,61.6 90.6,68.8 90.6,68.8 93.8,78.1 98.0,90.6 103.1,106.3 103.1,106.3 108.2,121.8 112.3,133.7 115.2,142.0 115.2,142.0 117.0,146.7 118.7,151.0 120.4,155.0 122.0,158.7 122.0,158.7 123.3,161.4 124.5,163.9 125.7,166.2 126.9,168.3 128.0,170.2 128.0,170.2 129.4,172.3 130.8,174.2 132.2,175.8 133.6,177.2 133.6,177.2 135.5,178.8 137.4,180.0 139.3,180.7 139.3,180.7 141.2,181.0 143.0,180.9 144.9,180.3 144.9,180.3 146.8,179.3 148.7,177.9 150.6,176.0 150.6,176.0 152.0,174.4 153.4,172.6 154.8,170.5 156.2,168.2 156.2,168.2 157.3,166.2 158.5,164.0 159.7,161.5 160.9,158.9 162.2,156.0 162.2,156.0 164.4,150.7 166.8,144.5 169.4,137.5 169.4,137.5 172.1,129.9 174.8,122.0 177.5,113.9 181.5,101.5" fill-opacity="0" stroke="#000000" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <g id="y" class="port">
            <polygon points="201.5,91.5 221.5,101.5 201.5,111.5" fill="#FFFFFF" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        </g>
    </g>
</svg>

После загрузки svg в мой HTML, есть ли способ рассчитать размер каждого из этих изображений svg, игнорируя при этом любые объекты "port", которые могут содержаться в каждом файле? Свойства ширины и высоты, определенные в теге svg, указывают размер всего изображения, но я хочу знать размер изображения без портов. Также хотелось бы узнать, каково смещение от верхнего левого угла размера изображения без портов. т. е. если на левой стороне нет порта, то смещение будет равно 0, если на левой стороне будет порт, то смещение будет равно ширине, занятой портом на левой стороне.

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Если вы выполнили небольшую предварительную обработку и организовали компоненты svg в две группы - «body» и «ports» - вы можете сделать что-то вроде этого:

// For each SVG, call the getBBoxWithoutPort() function.
document.querySelectorAll('svg').forEach(function(svg) {
  console.log(getBBoxWithoutPort(svg));
});

function getBBoxWithoutPort(el) {
  // get a reference to the body group
  var body = el.querySelector('.body');
  // Return its size
  return body.getBBox();
}
<svg width="263" height="203" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <g class="component">
        <g class="body">
            <polygon points="41.5,201.5 241.5,201.5 241.5,1.5 41.5,1.5" fill="#FFFFFF" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
            <polyline points="41.5,41.5 67.5,77.5 97.5,77.5" fill-opacity="0" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
            <polyline points="41.5,161.5 67.5,129.5 99.5,129.5" fill-opacity="0" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
            <polygon points="191.5,101.5 191.3,97.2 190.8,92.9 189.8,88.7 188.6,84.6 186.9,80.6 185.0,76.8 182.7,73.2 180.1,69.7 177.2,66.5 174.1,63.6 170.7,60.9 167.1,58.6 163.3,56.5 159.4,54.8 155.3,53.4 151.1,52.4 146.9,51.8 142.6,51.5 138.3,51.6 134.0,52.1 129.8,52.9 125.6,54.1 121.6,55.6 117.8,57.5 114.1,59.7 110.6,62.2 107.3,65.0 104.3,68.1 101.6,71.4 99.1,75.0 97.0,78.7 95.2,82.6 93.8,86.7 92.7,90.8 91.9,95.1 91.5,99.3 91.5,103.7 91.9,107.9 92.7,112.2 93.8,116.3 95.2,120.4 97.0,124.3 99.1,128.0 101.6,131.6 104.3,134.9 107.3,138.0 110.6,140.8 114.1,143.3 117.8,145.5 121.6,147.4 125.6,148.9 129.8,150.1 134.0,150.9 138.3,151.4 142.6,151.5 146.9,151.2 151.1,150.6 155.3,149.6 159.4,148.2 163.3,146.5 167.1,144.4 170.7,142.1 174.1,139.4 177.2,136.5 180.1,133.3 182.7,129.8 185.0,126.2 186.9,122.4 188.6,118.4 189.8,114.3 190.8,110.1 191.3,105.8" fill-opacity="0" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
            <polyline points="191.5,101.5 241.5,101.5" fill-opacity="0" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
            <text x="141.5" y="133.8" text-anchor="middle" fill="#000000" font-size="90.3px" font-family="sans-serif">+</text>
            <text x="94.0" y="48.7" text-anchor="middle" fill="#000000" font-size="53.1px" font-family="sans-serif">1</text>
            <text x="94.0" y="192.7" text-anchor="middle" fill="#000000" font-size="53.1px" font-family="sans-serif">1</text>
        </g>
        <g class="ports">
            <g id="u1" class="port">
                <polygon points="1.5,21.5 41.5,41.5 1.5,61.5" fill="#00007F" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
            </g>
            <g id="u2" class="port">
                <polygon points="1.5,141.5 41.5,161.5 1.5,181.5" fill="#00007F" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
            </g>
            <g id="y" class="port">
                <polygon points="241.5,91.5 261.5,101.5 241.5,111.5" fill="#FFFFFF" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
            </g>
        </g>
    </g>
</svg>

<svg width="223" height="203" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <g class="component">
        <g class="body">
            <polygon points="1.5,201.5 201.5,201.5 201.5,1.5 1.5,1.5" fill="#FFFFFF" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
            <polyline points="21.5,33.5 21.5,181.5" fill-opacity="0" stroke="#C0C0C0" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
            <polygon points="21.5,11.5 13.5,33.5 29.5,33.5" fill="#C0C0C0" stroke="#C0C0C0" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
            <polyline points="11.5,101.5 169.5,101.5" fill-opacity="0" stroke="#C0C0C0" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
            <polygon points="191.5,101.5 169.5,93.5 169.5,109.5" fill="#C0C0C0" stroke="#C0C0C0" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
            <polyline points="21.5,101.5 27.2,84.4 30.7,73.8 33.8,65.0 36.4,57.8 36.4,57.8 38.2,53.3 39.9,49.1 41.6,45.2 43.2,41.8 43.2,41.8 44.5,39.2 45.7,36.8 46.9,34.7 48.1,32.7 49.2,31.0 49.2,31.0 50.7,29.1 52.1,27.4 53.5,25.9 54.9,24.6 54.9,24.6 56.8,23.4 58.6,22.5 60.5,22.0 60.5,22.0 62.4,22.0 64.2,22.5 66.1,23.3 66.1,23.3 67.5,24.2 68.9,25.4 70.3,26.7 71.8,28.4 71.8,28.4 72.9,29.8 74.0,31.4 75.2,33.1 76.3,35.0 77.4,37.0 77.4,37.0 78.8,39.7 80.3,42.7 81.8,46.1 83.4,49.8 83.4,49.8 85.6,55.3 88.0,61.6 90.6,68.8 90.6,68.8 93.8,78.1 98.0,90.6 103.1,106.3 103.1,106.3 108.2,121.8 112.3,133.7 115.2,142.0 115.2,142.0 117.0,146.7 118.7,151.0 120.4,155.0 122.0,158.7 122.0,158.7 123.3,161.4 124.5,163.9 125.7,166.2 126.9,168.3 128.0,170.2 128.0,170.2 129.4,172.3 130.8,174.2 132.2,175.8 133.6,177.2 133.6,177.2 135.5,178.8 137.4,180.0 139.3,180.7 139.3,180.7 141.2,181.0 143.0,180.9 144.9,180.3 144.9,180.3 146.8,179.3 148.7,177.9 150.6,176.0 150.6,176.0 152.0,174.4 153.4,172.6 154.8,170.5 156.2,168.2 156.2,168.2 157.3,166.2 158.5,164.0 159.7,161.5 160.9,158.9 162.2,156.0 162.2,156.0 164.4,150.7 166.8,144.5 169.4,137.5 169.4,137.5 172.1,129.9 174.8,122.0 177.5,113.9 181.5,101.5" fill-opacity="0" stroke="#000000" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        </g>
        <g class="ports">
            <g id="y" class="port">
                <polygon points="201.5,91.5 221.5,101.5 201.5,111.5" fill="#FFFFFF" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
            </g>
        </g>
    </g>
</svg>
0 голосов
/ 03 мая 2018

Вы можете

  • перебрать элементы SVG,
  • удаляйте своих детей, которых вы не хотите,
  • получить BBX svg,
  • повторно добавить удаленные элементы там, где они были.

Реализация ES6 потребует переноса или полного переписывания для браузеров ES5.

console.log(
  [...document.querySelectorAll('svg')]
    .map(getBBoxWithoutPort)
);

function getBBoxWithoutPort(el) {
  // grab all the .port elements and store in an Array
  const ports = [...el.querySelectorAll('.port')];
  ports.forEach(p => {
    // store their parentNode and nextSibling
    p._parent = p.parentNode;
    p._next = p.nextElementSibling;
    // remove it from the DOM
    p.remove();
  });
  // now get the size of the parent SVG node
  const size = el.getBBox();
  ports.forEach(p => {
    // re-append your removed elements
    p._parent.insertBefore(p, (p._next && p._next.parentNode) ? p._next : null);
    // clean
    delete p._parent;
    delete p._next;
  });
  return size;
}
<svg width="263" height="203" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <g class="component">
        <polygon points="41.5,201.5 241.5,201.5 241.5,1.5 41.5,1.5" fill="#FFFFFF" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polyline points="41.5,41.5 67.5,77.5 97.5,77.5" fill-opacity="0" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polyline points="41.5,161.5 67.5,129.5 99.5,129.5" fill-opacity="0" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polygon points="191.5,101.5 191.3,97.2 190.8,92.9 189.8,88.7 188.6,84.6 186.9,80.6 185.0,76.8 182.7,73.2 180.1,69.7 177.2,66.5 174.1,63.6 170.7,60.9 167.1,58.6 163.3,56.5 159.4,54.8 155.3,53.4 151.1,52.4 146.9,51.8 142.6,51.5 138.3,51.6 134.0,52.1 129.8,52.9 125.6,54.1 121.6,55.6 117.8,57.5 114.1,59.7 110.6,62.2 107.3,65.0 104.3,68.1 101.6,71.4 99.1,75.0 97.0,78.7 95.2,82.6 93.8,86.7 92.7,90.8 91.9,95.1 91.5,99.3 91.5,103.7 91.9,107.9 92.7,112.2 93.8,116.3 95.2,120.4 97.0,124.3 99.1,128.0 101.6,131.6 104.3,134.9 107.3,138.0 110.6,140.8 114.1,143.3 117.8,145.5 121.6,147.4 125.6,148.9 129.8,150.1 134.0,150.9 138.3,151.4 142.6,151.5 146.9,151.2 151.1,150.6 155.3,149.6 159.4,148.2 163.3,146.5 167.1,144.4 170.7,142.1 174.1,139.4 177.2,136.5 180.1,133.3 182.7,129.8 185.0,126.2 186.9,122.4 188.6,118.4 189.8,114.3 190.8,110.1 191.3,105.8" fill-opacity="0" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polyline points="191.5,101.5 241.5,101.5" fill-opacity="0" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <text x="141.5" y="133.8" text-anchor="middle" fill="#000000" font-size="90.3px" font-family="sans-serif">+</text>
        <text x="94.0" y="48.7" text-anchor="middle" fill="#000000" font-size="53.1px" font-family="sans-serif">1</text>
        <text x="94.0" y="192.7" text-anchor="middle" fill="#000000" font-size="53.1px" font-family="sans-serif">1</text>
        <g id="u1" class="port">
            <polygon points="1.5,21.5 41.5,41.5 1.5,61.5" fill="#00007F" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        </g>
        <g id="u2" class="port">
            <polygon points="1.5,141.5 41.5,161.5 1.5,181.5" fill="#00007F" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        </g>
        <g id="y" class="port">
            <polygon points="241.5,91.5 261.5,101.5 241.5,111.5" fill="#FFFFFF" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        </g>
    </g>
</svg>

<svg width="223" height="203" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <g class="component">
        <polygon points="1.5,201.5 201.5,201.5 201.5,1.5 1.5,1.5" fill="#FFFFFF" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polyline points="21.5,33.5 21.5,181.5" fill-opacity="0" stroke="#C0C0C0" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polygon points="21.5,11.5 13.5,33.5 29.5,33.5" fill="#C0C0C0" stroke="#C0C0C0" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polyline points="11.5,101.5 169.5,101.5" fill-opacity="0" stroke="#C0C0C0" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polygon points="191.5,101.5 169.5,93.5 169.5,109.5" fill="#C0C0C0" stroke="#C0C0C0" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <polyline points="21.5,101.5 27.2,84.4 30.7,73.8 33.8,65.0 36.4,57.8 36.4,57.8 38.2,53.3 39.9,49.1 41.6,45.2 43.2,41.8 43.2,41.8 44.5,39.2 45.7,36.8 46.9,34.7 48.1,32.7 49.2,31.0 49.2,31.0 50.7,29.1 52.1,27.4 53.5,25.9 54.9,24.6 54.9,24.6 56.8,23.4 58.6,22.5 60.5,22.0 60.5,22.0 62.4,22.0 64.2,22.5 66.1,23.3 66.1,23.3 67.5,24.2 68.9,25.4 70.3,26.7 71.8,28.4 71.8,28.4 72.9,29.8 74.0,31.4 75.2,33.1 76.3,35.0 77.4,37.0 77.4,37.0 78.8,39.7 80.3,42.7 81.8,46.1 83.4,49.8 83.4,49.8 85.6,55.3 88.0,61.6 90.6,68.8 90.6,68.8 93.8,78.1 98.0,90.6 103.1,106.3 103.1,106.3 108.2,121.8 112.3,133.7 115.2,142.0 115.2,142.0 117.0,146.7 118.7,151.0 120.4,155.0 122.0,158.7 122.0,158.7 123.3,161.4 124.5,163.9 125.7,166.2 126.9,168.3 128.0,170.2 128.0,170.2 129.4,172.3 130.8,174.2 132.2,175.8 133.6,177.2 133.6,177.2 135.5,178.8 137.4,180.0 139.3,180.7 139.3,180.7 141.2,181.0 143.0,180.9 144.9,180.3 144.9,180.3 146.8,179.3 148.7,177.9 150.6,176.0 150.6,176.0 152.0,174.4 153.4,172.6 154.8,170.5 156.2,168.2 156.2,168.2 157.3,166.2 158.5,164.0 159.7,161.5 160.9,158.9 162.2,156.0 162.2,156.0 164.4,150.7 166.8,144.5 169.4,137.5 169.4,137.5 172.1,129.9 174.8,122.0 177.5,113.9 181.5,101.5" fill-opacity="0" stroke="#000000" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        <g id="y" class="port">
            <polygon points="201.5,91.5 221.5,101.5 201.5,111.5" fill="#FFFFFF" stroke="#00007F" stroke-width="1.0" stroke-linecap="round" stroke-linejoin="round" />
        </g>
    </g>
</svg>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...