我正在嘗試計算轉換后的 SVG 元素的邊界框,為此我使用 getBoundingClientRect() 并將 x 和 y 值映射到 SVG 坐標。但是,當形狀具有曲線和旋轉時,此功能似乎會在 Chrome 和 Edge 中產生錯誤的輸出。另一方面,Firefox 能夠產生預期的結果。
這是一個
你會用這樣的東西(或多或少無用的代碼只是為了說明)實作相同的效果:
<script type="text/javascript">
const svg = document.getElementById('svg');
let svgElem = document.getElementById('svgElem');
const bBox = svgElem.getBBox(); // MDN: The returned value is a SVGRect object, which defines the bounding box. This value is irrespective of any transformation attribute applied to it or the parent elements
console.dir(bBox);
const boundingClientRect = svgElem.getBoundingClientRect();
console.dir(boundingClientRect);
// create a rect without transforms
const rect1 = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
rect1.setAttribute('x', bBox.x);
rect1.setAttribute('y', bBox.y);
rect1.setAttribute('width', bBox.width);
rect1.setAttribute('height', bBox.height);
rect1.setAttribute('fill', '#00ff0040');
svg.appendChild(rect1);
const ctm = svgElem.getCTM();
const topLeftX = ctm.a * bBox.x ctm.c * bBox.y ctm.e;
const topLeftY = ctm.b * bBox.x ctm.d * bBox.y ctm.f;
const topRightX = ctm.a * (bBox.x bBox.width) ctm.c * bBox.y ctm.e;
const topRightY = ctm.b * (bBox.x bBox.width) ctm.d * bBox.y ctm.f;
const bottomLeftX = ctm.a * bBox.x ctm.c * (bBox.y bBox.height) ctm.e;
const bottomLeftY = ctm.b * bBox.x ctm.d * (bBox.y bBox.height) ctm.f;
const bottomRightX = ctm.a * (bBox.x bBox.width) ctm.c * (bBox.y bBox.height) ctm.e;
const bottomRightY = ctm.b * (bBox.x bBox.width) ctm.d * (bBox.y bBox.height) ctm.f;
const x = Math.min(topLeftX, topRightX, bottomLeftX, bottomRightX);
const y = Math.min(topLeftY, topRightY, bottomLeftY, bottomRightY);
const width = Math.max(topLeftX, topRightX, bottomLeftX, bottomRightX) - x;
const height = Math.max(topLeftY, topRightY, bottomLeftY, bottomRightY) - y;
const rect2 = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
rect2.setAttribute('x', x);
rect2.setAttribute('y', y);
rect2.setAttribute('width', width);
rect2.setAttribute('height', height);
rect2.setAttribute('fill', '#ff000040');
svg.appendChild(rect2);
</script>
或者您可以查看 Firefox/Chromium 的開發人員工具以查看差異(只是說放置一個組也不起作用)。
也許 SVG 版本 2 會在未來

所以這可能是獲得“真實”邊界框的一種變通方法。
至于 getBoundingClientRect:MDN 說:“回傳的值是一個 DOMRect 物件,它是包含整個元素的最小矩形,包括其填充和邊框寬度。”
恕我直言,Chromium 的實作中有一個錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/402337.html
標籤:
上一篇:具有清晰邊緣的SVG影像元素
