如何让Firefox遵循用作裁剪路径的SVG rect的transform-origin属性
问题:Firefox中SVG裁剪路径的transform-origin属性不生效
缩放用作SVG图像裁剪路径的SVG矩形时,仅Firefox存在异常(Chrome、Safari表现正常,未测试Edge):Firefox不遵循rect的transform-origin CSS属性。
我制作了两段示例代码复现问题:
- 示例1:rect覆盖在图像上方,验证Firefox能正确响应rect的
transform-origin属性,也能正确返回bounding box,三款浏览器均正常工作。 - 示例2:将rect用作裁剪路径,展示Firefox的问题——既无法正确应用变换,也不能返回正确的bounding box。
实际项目需要将transform-origin设置为center,求解决缩放后rect正确变换的方法。
运行代码片段时请展开至全屏
完整代码
HTML
<head> <title>Firefox Problem: transform-origin and getBBox()</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script> </head> <body> <h1>Example 1: Rect Overlaying Image</h1> <svg class="example1" viewBox="0 0 2119 2191" preserveAspectRatio="none"> <image href="https://learn.robertvaessen.com/media/mandala.jpg"/> <rect x="530" y="547" width="1060" height="1095"/> </svg> <div class="example1"> <h2>Overlay Setup</h2> <fieldset> <legend align="center">Transform Origin</legend> <label> Center <input type="radio" name="example1TransformOrigin" value="center" checked/> </label> <label> Top Left <input type="radio" name="example1TransformOrigin" value="top left"/> </label> </fieldset> <label> Scaled <input type="checkbox"/> </label> <input type="button" value="Report"/> </div> <h1 class="example2" >Example 2: Rect Clipping Image</h1> <svg class="example2" viewBox="0 0 2119 2191" preserveAspectRatio="none"> <clipPath id="rect"> <rect x="530" y="547" width="1060" height="1095"/> </clipPath> <image href="https://learn.robertvaessen.com/media/mandala.jpg" clip-path="url(#rect)"></image> </svg> <div class="example2" > <h2>Clipping Setup</h2> <fieldset> <legend align="center">Transform Origin</legend> <label> Center <input type="radio" name="example2TransformOrigin" value="center" checked/> </label> <label> Top Left <input type="radio" name="example2TransformOrigin" value="top left"/> </label> </fieldset> <label> Scaled <input type="checkbox"/> </label> <input type="button" value="Report"/> </div> </body>
CSS
body { background-color: black; } h1 { position: fixed; left: 50%; translate: -50%; font: 25px Arial, sans-serif; color: white; text-align: center; } h1.example2 { top: 50vh; } h2 { font: 18px Arial, sans-serif; color: white; text-align: center; text-decoration: underline; } svg { position: fixed; left: 50%; translate: -50%; width: 200px; height: 200px; border: 1px solid white; } svg.example1 { top: 10vh; } svg.example2 { top: 60vh; } rect { fill: none; stroke: red; stroke-width: 20px; transform-box: fill-box; } div { display: flex; flex-direction: column; gap: 5px; align-items: center; position: fixed; left: 10vw; color: white; background-color: gray; border: 1px solid black; border-radius: 5px; padding: 8px; } div.example1 { top: 10vh; } div.example2 { top: 60vh; }
JavaScript
window.onload = function() { setupExample('example1') setupExample('example2') } function setupExample(name) { let rect = $(`svg.${name} rect`) let scaledCheckBox = $(`div.${name} input[type=checkbox]`) let transformOriginFieldset = $(`div.${name} > fieldset`) function setTransform() { if (scaledCheckBox[0].checked) { rect.attr('transform', 'scale(1.5)') } else { rect.removeAttr('transform') } } scaledCheckBox.on('change', setTransform) setTransform(); function setTransformOrigin() { let transformOrigin = document.querySelector(`div.${name} input[name=${name}TransformOrigin]:checked`).value rect.css('transform-origin', transformOrigin) } transformOriginFieldset.on('change', setTransformOrigin) setTransformOrigin() let reportButton = $(`div.${name} > input[type=button]`) reportButton.on('click', () => { let bb = rect[0].getBBox() alert(`Rect Bounding Box: ${bb.width} x ${bb.height} at ${bb.x}, ${bb.y}`) }) }
内容的提问来源于stack exchange,提问作者Verticon
相关产品推荐
相关产品推荐

