我有一个有点复杂的问题。我正在尝试通过 svg 渲染网格,然后将事件侦听器添加到网格中。目前我正在通过渲染网格<pattern>
元素。我对渲染网格的其他途径持开放态度,但它需要可扩展/高性能,因为该网格很容易成为数十个或数千个正方形。将其视为平面图或蓝图。
我想要的是:我希望能够附加一个事件监听器网格的每个方格.
我做了什么:我查阅了 svg 文档,尝试了很多不同的东西(如 onclick 处理程序、svg 属性(如指针事件...等)),但没有运气。我可能可以让它与鼠标客户端坐标一起工作,但是如果可能的话,我想避免使用这种方法,因为这个 svg 将具有缩放和平移功能..这可能会使转换坐标变得很痛苦。
基本 svg 代码(针对这个问题进行了简化):
<svg viewBox="0 0 100 100">
<g className="view-control">
<defs>
<pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse">
<path d="M 10 0 L 0 0 0 10" fill="none" stroke="gray" strokeWidth="0.5"/>
</pattern>
</defs>
<rect width="100%" height="100%" fill="url(#grid)" />
</g>
</svg>
小提琴来玩 https://jsfiddle.net/tp530748/
我不确定您对“鼠标客户端坐标”的反对是什么,但它做起来非常简单,并且满足您的要求。
-
将单击处理程序添加到网格矩形。我在这个演示中使用了点击处理程序。但如果您想将其基于悬停,则可以使用 mousemove 事件。
<rect width="200%" height="200%" fill="url(#grid)" onClick={(e) => handleClick(e)}/>
function handleClick(e) {
var pos = getSVGPosition(e);
createRectAt(pos);
}
-
将鼠标坐标转换为 svg 坐标的函数如下所示:
function getSVGPosition(e) {
var svg = e.nativeEvent.target.ownerSVGElement;
var pt = svg.createSVGPoint();
pt.x = e.nativeEvent.clientX;
pt.y = e.nativeEvent.clientY;
pt = pt.matrixTransform(svg.getScreenCTM().inverse());
return {svg: svg, x: pt.x, y: pt.y};
}
-
然后为了演示的目的,我在相关网格位置创建了一个正方形
function createRectAt(pos) {
var rect = document.createElementNS(pos.svg.namespaceURI, "rect");
rect.setAttribute("x", Math.floor(pos.x / 10) * 10);
rect.setAttribute("y", Math.floor(pos.y / 10) * 10);
rect.setAttribute("width", 10);
rect.setAttribute("height", 10);
rect.setAttribute("fill", "green");
pos.svg.appendChild(rect);
}
https://jsfiddle.net/tp530748/31/ https://jsfiddle.net/tp530748/31/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)