我有一个复杂的问题。我试图通过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>
答案 0 :(得分:1)
我不确定您对“鼠标客户端坐标”有何异议,但这很简单,是否可以满足您的要求。
将单击处理程序添加到网格矩形。我在此演示中使用了点击处理程序。但是,如果要基于悬停,则可以改用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);
}
答案 1 :(得分:0)
如果将网格设置为<pattern>
,则将无法在模式上注册任何鼠标事件。模式命中框将覆盖整个<rect>
我建议您根据<svg>
的大小,viewBox和网格的间距自己计算正方形的坐标。将任何鼠标事件附加到SVG元素