I have an svg element and I need to compute the real size of the element.
For example consider this:
<g>
<path d="M 0 0 L 20 0" symbol-local-id="42a57c74-adcf-480a-b193-572a1c50a7a1" fill="none" stroke="#666666" stroke-width="3" stroke-miterlimit="10" stroke-linecap="flat" pointer-events="all"/>
</g>
The expected size should be width:20px and height:3px
The SVG can be much more complicated than this, so I need to compute it dynamically.
I can't use getBBox() nor getBoundingClientRect() because they compute size without considering stroke.
So I tried to render it in a canvas and count the number of pixels to get the real size, but things don't work I continue to get height 1px.
This is the algorithm to compute the size:
const rasterSVGAndGetRealSize = function (svgEl, renderedCallback) {
svgEl.removeAttribute('viewBox');
svgEl.removeAttribute('width');
svgEl.removeAttribute('height');
svgEl.style.backgroundColor = 'rgba(255, 255, 255, 1)';
const style = document.createElement('style');
style.innerHTML = 'path, text, rect, ellipse { fill: rgba(0,0,0,1) !important; stroke: rgba(0,0,0,1)!important}';
svgEl.insertBefore(style, svgEl.firstChild);
const serialized = new XMLSerializer().serializeToString(svgEl);
const uri = 'data:image/svg+xml;base64,' + window.btoa(serialized);
// load svg image into canvas
const image = new Image();
image.onload = function () {
const canvas = document.createElement('canvas');
const w = image.naturalWidth;
const h = image.naturalHeight;
canvas.width = w;
canvas.height = h;
const context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
const imageData = context.getImageData(0, 0, w, h);
const data = imageData.data;
let left = w;
let top = h;
let right = 0;
let bottom = 0;
for (let r = 0; r < h; r++) {
for (let c = 0; c < w; c++) {
const pixel = w * r + c;
const red = data[4 * pixel];
const green = data[4 * pixel + 1];
const blue = data[4 * pixel + 2];
const alpha = data[4 * pixel + 3];
if (red !== 255 || green !== 255 || blue !== 255) {
if (c < left) {
left = c;
}
if (r < top) {
top = r;
}
if (c > right) {
right = c;
}
if (r > bottom) {
bottom = r;
}
}
}
}
renderedCallback({ left: left, top: top, right: right, bottom: bottom, width: right - left + 1, height: bottom - top + 1 });
//canvas.setAttribute('id', 'imageTest');
//document.body.appendChild(canvas);
}
image.src = uri;
};
What is wrong? Do you know another solution to compute the real size of the SVG?
Check this fiddle: https://jsfiddle.net/orbintsoft/jo17fkgr/5/
question from:
https://stackoverflow.com/questions/65830123/compute-real-size-of-svg-considering-stroke-and-transformations