antv x6让拖拽控件工具箱悬浮在画布上,工具箱区域鼠标按下不生成节点
项目需求是让工具箱悬浮在画布
上,而我们拖拽控件生成节点是Mousedown鼠标按下
时就触发的,所以每次我们按下鼠标(拖拽或者单击)都会生成节点,这也就导致我们在工具箱单击时会在工具箱下边生成节点
写了好多方法,比如mousedown加时间戳同时开启dnd.start拖拽,等到生成节点的时候在validateNode里使用时间间隔判断啊,又或者在mousedown的时候记录一个标志,在Mouseup的时候清除一个标志,延迟多少毫秒再判断标志是否还在,如果还在,证明是拖拽事件再触发dnd.start,但是这两种方法都试了,都有些问题,最后,大佬提示,可以用如下方法实现:
继承Dnd
,重写isInsideValidArea
方法,把方法改成只要拖拽的节点不离开工具箱区域,就不会在画布上生成节点
dnd类的源码
源码里只定义了验证鼠标是否在可拖拽区域中的方法(自己分析的,反正大概就这么个意思吧哈哈哈哈,如有不对还请各位大佬温柔指正~)
protected isInsideValidArea(p: Point.PointLike) {
let targetRect: Rectangle
const targetGraph = this.targetGraph
const targetScroller = this.targetScroller
if (targetScroller) { // 判断是否支持滚动
if (targetScroller.options.autoResize) { // 如果支持滚动判断是否是否自动扩充/缩小画布
targetRect = this.getDropArea(targetScroller.container)
} else {
const outter = this.getDropArea(targetScroller.container)
targetRect = this.getDropArea(targetGraph.container).intersectsWithRect( // 返回画布区域与滚动区域相交的区域
outter,
)!
}
} else {
targetRect = this.getDropArea(targetGraph.container)
}
return targetRect && targetRect.containsPoint(p) // 返回是否有可拖拽区域与当前鼠标(代表节点)是否在此区域中,如果有就生成节点
}
protected getDropArea(elem: Element) { // 返回可拖拽区域的x、y坐标与宽高
const $elem = this.$(elem)
const offset = $elem.offset()!
const scrollTop =
document.body.scrollTop || document.documentElement.scrollTop
const scrollLeft =
document.body.scrollLeft || document.documentElement.scrollLeft
return Rectangle.create({
x:
offset.left + parseInt($elem.css('border-left-width'), 10) - scrollLeft,
y: offset.top + parseInt($elem.css('border-top-width'), 10) - scrollTop,
width: $elem.innerWidth()!,
height: $elem.innerHeight()!,
})
}
intersectsWithRect方法: 返回画布区域与滚动区域相交的区域
containersPoint: 判断 鼠标当前 的xy轴是否在区域中
所以我们只需要写个方法判断一下当前鼠标是否还在拖拽区域中
,如果在就不生成节点即可。
我们在这个方法里边加一最重要的一句
// 如果还未拖出当前区域,就不在画布上生成节点
return !dragRect.containsPoint(p) && super.isInsideValidArea(p);
然后在在线编辑工具里有这个继承方法,我们直接复制粘贴 即可
试了下果然好用啊!