我已经使用拉斐尔路径创建了一个多边形。可以拖动多边形的顶点以将其拉伸以更改多边形的形状/大小。
测试正在运行here
现在,我要实现的是,如果我在边缘上双击,它将创建一个新的顶点。这样它就可以作为拖动点。
任何人都可以帮助我确定路径中点的位置:
var p = r.path("M100,300L100,100L250,300z");
并且如果在200,250上发生鼠标事件,那么如何识别路径数组中的新位置应该适合新的point命令?
var p = r.path("M100,300L200,250L100,100L250,300z");
要么
var p = r.path("M100,300L100,100L200,250L250,300z");
最佳答案
我的实现略有不同,但是如果太多的话,您总是可以对其进行调整(实际上,只要在纸上的任意位置单击鼠标,我都会在多边形中插入新点)。
一些自定义Raphael方法Raphael.el.MakeDraggable
:添加处理程序以拖动任何元素(即点或多边形)Raphael.el.InsertPoint
:在多边形中插入给定点(参数)
我的观点
由Paper.circle()
制成
可以用鼠标拖动
var oPaper = Raphael('#paper', '100%', '100%');
var oPoint = oPaper.circle(nX, nY, nRadius);
oPoint.MakeDraggable();
我的多边形
由
Paper.path()
制成用
oPolygon.data()
绑定到包含其点的集合可以用鼠标拖动
var oPaper = Raphael('#paper', '100%', '100%');
var oPolygon = oPaper.path(sPath);
oPolygon.InsertPoint(oPoint);
数学
为了将新创建的点插入到多边形的路径中,我遵循了以下两个步骤:
在多边形的每一边上循环并获取到该边和该点的距离
从较低的距离开始,假设应该在两个点之间插入新创建的点
获取新点的距离
这两个步骤很容易理解,但是很难实现(尤其是第一步)。这是详细的第一步。假设您要遍历多边形的每一侧(一侧等于2点),我们需要以所有距离填充一个数组,以便获得最低的距离。
C +-------+ A + M
\ | The shortest / The shortest
\ | distance is [MG] / distance is [MA]
\ G +--------+ M C +----+ A
\ | \ |
\ | \ |
\ | \ |
\| \|
+ B + B
遍历侧面的函数将点二乘二,再加上3点的新创建点,但让我们为第一次迭代编写它(例如)
所以oA和oB是多边形侧面的2个点,而oM是新创建的点
挖掘数学,您应该能够获得oG的坐标,即oA和oB所形成的直线上oM的转换点
一旦有了oG的坐标,就有2种情况:
oG在oA和oB之间
oM在oA和oB制成的一面的前面
所以返回的距离就是oM和oG之间的距离
oG在oA和oB所组成的部分之外
oM不在oA和oB的侧面
因此,返回的距离就是oM与oA或oB之间的距离,只需返回它们中的最小值2
现在您有1个距离,在多边形的每侧重复一次即可得到其他
现在,包含距离的数组应包含oM与多边形边之间的所有距离。我们需要找到较低的值(可以有多个具有相同值的值)。因此,在其上循环并构建另一个包含最低距离索引的数组。
确定哪一方是正确的
一旦有了这个新数组,请检查其长度:
长度为1:表示您的oM点在侧面的前面。您有了边的索引,继续并将点插入到多边形的数据中
长度为2:表示您的oM点不在侧面前方。您有2个索引,将它们视为点索引,有2个点构成了边,与上面相同,现在您可以将点插入到多边形的数据中
长度为3+(我相信您不需要):特殊情况,例如圆形(具有很多点)和类似正方形的多边形,可以将点插入到正中央
一些更多的东西
// Don't forget to bind points to their polygon
oPolygon.data('points', oPoints); // oPoints is a Raphael set containing the points
// There are different approaches, mine was to bind the other way as well
oPoint.data('polygon', oPolygon);
关于javascript - 确定拉斐尔路径上的点的位置,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18363660/