svg - 当视图框为负时鼠标事件的svg问题
问题描述
我使用 SVG 来绘制地图。但是当视图框为负值时 - 鼠标事件不起作用。请查看以下小提琴:
<svg
id="svg" class="mapNavSVG"
width="100%"
viewBox="27.7333333 -43.2233334 0.2183334 0.0566667"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
xlink="http://www.w3.org/1999/xlink"
ev="http://www.w3.org/2001/xml-events"
shape-rendering="geometricPrecision"
>
<rect x="27.7333333" y="-43.2233334" width="0.2183334" height="0.0566667" style="fill:#0059b3;" />
<rect onClick="alert('Test!');" x="27.9408" y="-43.1944975" width="0.006" height="0.006" style="fill:yellow;" />
</svg>
值是真实的 GPS 坐标。正如你所看到的——当点击黄色矩形时——什么也没发生。
先感谢您。
更新:08.01.2018 在这里发表一些评论和额外的研究后,我发现这个问题的原因是小的实数(非整数)。在 chrome 中问题已修复,但在 64 版中仍然存在 firefox 问题,即使bugzilla 中有问题日志。缩放地图中的所有 SVG 元素对我来说太难了,因为我是从 GIS 软件中获取它们的。感谢大家的帮助。
解决方案
这些是与浏览器相关的计算错误。在以下代码段中,我设置了 px 宽度和高度<svg>
以获得可比较的结果。.getBoundingClientRect()
黄色矩形报告的宽度在从 返回和从 计算时应该匹配.getBBox()
,乘以从 的比例值.getScreenCTM()
:
var rect = document.querySelector('rect:last-child');
var size = rect.getBBox().width;
console.log('local width:', size);
var scale = rect.getScreenCTM().a;
console.log('screen scale:', scale, 'screen width:', size*scale);
console.log('bounding rect width', rect.getBoundingClientRect().width);
<svg
id="svg" class="mapNavSVG"
width="500px" height="100px"
viewBox="27.7333333 -43.2233334 0.2183334 0.0566667"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
xlink="http://www.w3.org/1999/xlink"
ev="http://www.w3.org/2001/xml-events"
shape-rendering="geometricPrecision"
>
<rect x="27.7333333" y="-43.2233334" width="0.2183334" height="0.0566667" style="fill:#0059b3;" />
<rect x="27.9408" y="-43.1944975" width="0.006" height="0.006" style="fill:yellow;" />
</svg>
在 Chromium 71/Debian 中,结果(或多或少)匹配:10.588px 到 10.589px。
在 Firefox 60esr/Debian 和 Firefox 64/Windows 中,它们没有:10.589px 到 29.416px 的边界矩形(也在开发工具中报告)。
Edge 和 IE11 计算 10.655px,但边界矩形的值为(原文如此!)1775.275px。至少鼠标事件捕获似乎正确地获取了该区域。
你能从中学到什么?非常小的数字会在某些浏览器上导致大的错误。从网站上的其他问题和以前的经验来看,我认为不要将元素的大小设置为低于 1px 的大小。如果你用 1000 缩放每个数字,错误就会消失:
<svg
id="svg" class="mapNavSVG"
width="100%"
viewBox="27733.3333 -43223.3334 218.3334 56.6667"
preserveAspectRatio="xMidYMid meet"
xmlns="http://www.w3.org/2000/svg"
xlink="http://www.w3.org/1999/xlink"
ev="http://www.w3.org/2001/xml-events"
shape-rendering="geometricPrecision"
>
<rect x="27733.3333" y="-43223.3334" width="218.3334" height="56.6667" style="fill:#0059b3;" />
<rect onClick="alert('Test!');" x="27940.8" y="-43194.4975" width="6" height="6" style="fill:yellow;" />
</svg>
推荐阅读
- bit-framework - 如何在配置 json 文件中嵌套配置并使用位读取它?
- .net - list.Clear() 与 new List<>() - ASP.NET Core - Entity Framework Core - 延迟加载
- grep - 大输出的 grep、求和和平均值
- vba - 为什么输入 Worksheets("Sheet1"). 后没有出现 Intellisense?
- linux - 如何使用 awk 工具对齐 csv 文件中的列
- react-native - 不变违规:元素类型无效:预期为字符串(用于内置组件)
- mysql - 如何正确更改表默认值
- vb.net - 使用 Visual Basic 在 .txt 文件中搜索文本
- gradle - Kotlin DSL:将 versions.gradle.kts 导入另一个 build.gradle.kts
- javascript - 沿最佳圆周分布 n 组圆