在Firefox中,Svg viewbox不会使用嵌套的svg返回正确的鼠标点

时间:2013-10-31 17:45:10

标签: svg

当我试图获得鼠标位置时,我对Firefox v25的问题很小。 当我使用2 svg嵌套时,FF不会返回正确的位置,但在Chrome和IE10中工作正常。

这是一个例子: http://jsfiddle.net/LwZFb/

<div class="position">
    <div>client position <span id="clientPosition"></span></div>
    <div>svg position <span id="svgPosition"></span></div>
</div>
<svg id="test1" version="1.1" viewBox="0 0 500 500" width="500px" height="500px">
<svg id="testSVG" preserveAspectRatio="none" version="1.1" viewBox="0 0 1000 1000" width="500px" height="500px">
    <rect fill="papayaWhip" x="250" y="250" width="500" height="500"/>
    <text x="225" y="240">250/250</text>
    <text x="725" y="240">750/250</text>
    <text x="225" y="775">250/750</text>
    <text x="725" y="775">750/750</text>
    <rect id="followMe" fill="peachPuff" stroke="crimson" width="20" height="20"/>
</svg>
</svg>

和获取位置的js代码:

var svgElement = document.getElementById('testSVG'),
followRectElement = document.getElementById('followMe'),
clientPositionElement = document.getElementById('clientPosition'),
svgPositionElement = document.getElementById('svgPosition');

window.addEventListener('mousemove', function(mouseEvent) {
    var svgPoint = svgElement.createSVGPoint();

    svgPoint.x = mouseEvent.clientX;
    svgPoint.y = mouseEvent.clientY;

    svgPoint = svgPoint.matrixTransform(svgElement.getScreenCTM().inverse());

    clientPositionElement.innerHTML = [ mouseEvent.clientX, mouseEvent.clientY ].join('/');
    svgPositionElement.innerHTML = [ svgPoint.x, svgPoint.y ].join('/');

    followRectElement.setAttribute('x', svgPoint.x - 10);
    followRectElement.setAttribute('y', svgPoint.y - 10);
});

1 个答案:

答案 0 :(得分:1)

啊,但Firefox确实提供了正确的位置,其他浏览器和您的算法都是问题。这就是问题界限......

svgPoint = svgPoint.matrixTransform(svgElement.getScreenCTM().inverse());

svgElement与svgPoint位于不同的坐标系统中,因为svgElement有一个viewBox和viewBox transforms only apply to descendants and not to the element itself不幸的是IE和Chrome不符合这里的SVG规范,这会引起很多混乱。

而不是上面的行,你可以改为写

svgPoint = svgPoint.matrixTransform(followRectElement.getScreenCTM().inverse());

因为followRectElement位于你想要的坐标系统中,这个解决方案可以跨浏览器工作。