如何使纸张可拖动
How to make a paper draggable
如果纸张对于其中显示的 div 来说太大,我想让纸张可以拖动。
我尝试了论文 blank:pointerdown 和 pointerup 事件,但无法仅跟随鼠标移动。我还尝试通过 jquery 使纸张元素可拖动,但似乎无济于事...
有什么办法吗?
我建议如下:
- 为纸张
blank:pointerdown event
注册一个处理程序,它将启动纸张拖动(存储一个标志,您将在 mousemove
处理程序中使用该标志来识别纸张在 "panning"状态)。
- 将大纸放入装有CSS
overflow: auto
的<div>
容器中。这个<div>
将是你对大论文的小window。
- 为文档正文
mousemove
事件注册一个处理程序(因为您很可能希望即使鼠标光标离开纸张区域也能拖动纸张?)。在此处理程序中,您将设置 <div>
容器的 scrollLeft
和 scrollTop
属性,使纸张 "panning"。要调整 scrollLeft
和 scrollTop
属性,您将使用事件对象的 clientX
和 clientY
属性以及您之前存储在 [=] 中的相同属性23=] 处理程序。 (换句话说,你需要那些来找到从最后一个 mousemove
/blank:pointerdown
开始的平移偏移量)。
- 为文档主体 mouseup 注册一个处理程序,并在该处理程序中,清除您在步骤 1 中设置的纸张拖动标志。
我知道这是一个有点老的话题,但我坚持了一段时间,发现了一个使用 SVG 平移和缩放库的巧妙解决方案。 Git hub link here
EDIT - 我在这里创建了以下步骤(加上一些额外的)的 plunker:
SVG panning with Jointjs
创建论文后的第一步是初始化 SVG 平移和缩放:
panAndZoom = svgPanZoom(targetElement.childNodes[0],
{
viewportSelector: targetElement.childNodes[0].childNodes[0],
fit: false,
zoomScaleSensitivity: 0.4,
panEnabled: false
});
其中targetElement是jointjs论文进入的div。 Jointjs 将在其中创建一个 SVG 元素(因此是 childNodes[0]),并且在该元素中第一个元素是视口标签(因此是视口选择器中的 childNodes[0].childNodes[0])。在这个阶段平移被禁用,因为在我的用例中它会干扰在纸上拖放元素。相反,我所做的是保留对 panAndZoom 对象的引用,然后在 blank:pointerdown 和 blank:pointerup 事件上打开和关闭平移:
paper.on('blank:pointerdown', function (evt, x, y) {
panAndZoom.enablePan();
});
paper.on('cell:pointerup blank:pointerup', function(cellView, event) {
panAndZoom.disablePan();
});
我想这只是解决问题的另一种方法,但我发现它更容易一些,而且它还可以缩放并且可以调整灵敏度等。
这可以通过结合 JointJS 事件和文档事件来实现。图形显示封装在 div
:
<div id='diagram'></div>
然后为 JointJS 添加事件处理程序,首先是我们存储拖动开始位置的 pointerdown
事件:
paper.on('blank:pointerdown',
function(event, x, y) {
dragStartPosition = { x: x, y: y};
}
);
然后当我们删除存储位置的变量时拖动结束(pointerup)(它也作为标志是否有正在进行的活动拖动):
paper.on('cell:pointerup blank:pointerup', function(cellView, x, y) {
delete dragStartPosition;
});
由于JointJS没有公开"paper pointer move"事件,我们需要使用mousemove
文档事件。例如,JQuery:
$("#diagram")
.mousemove(function(event) {
if (dragStartPosition)
paper.translate(
event.offsetX - dragStartPosition.x,
event.offsetY - dragStartPosition.y);
});
我们获取拖动开始坐标和当前指针位置,并使用 paper.translate()
调用更新纸张位置。
警告:如果缩放纸张(使用paper.scale()
),则还必须缩放拖动的起始位置:
var scale = V(paper.viewport).scale();
dragStartPosition = { x: x * scale.sx, y: y * scale.sy};
然后对 paper.translate()
的调用将更新到正确的位置。
如果纸张对于其中显示的 div 来说太大,我想让纸张可以拖动。
我尝试了论文 blank:pointerdown 和 pointerup 事件,但无法仅跟随鼠标移动。我还尝试通过 jquery 使纸张元素可拖动,但似乎无济于事...
有什么办法吗?
我建议如下:
- 为纸张
blank:pointerdown event
注册一个处理程序,它将启动纸张拖动(存储一个标志,您将在mousemove
处理程序中使用该标志来识别纸张在 "panning"状态)。 - 将大纸放入装有CSS
overflow: auto
的<div>
容器中。这个<div>
将是你对大论文的小window。 - 为文档正文
mousemove
事件注册一个处理程序(因为您很可能希望即使鼠标光标离开纸张区域也能拖动纸张?)。在此处理程序中,您将设置<div>
容器的scrollLeft
和scrollTop
属性,使纸张 "panning"。要调整scrollLeft
和scrollTop
属性,您将使用事件对象的clientX
和clientY
属性以及您之前存储在 [=] 中的相同属性23=] 处理程序。 (换句话说,你需要那些来找到从最后一个mousemove
/blank:pointerdown
开始的平移偏移量)。 - 为文档主体 mouseup 注册一个处理程序,并在该处理程序中,清除您在步骤 1 中设置的纸张拖动标志。
我知道这是一个有点老的话题,但我坚持了一段时间,发现了一个使用 SVG 平移和缩放库的巧妙解决方案。 Git hub link here
EDIT - 我在这里创建了以下步骤(加上一些额外的)的 plunker: SVG panning with Jointjs
创建论文后的第一步是初始化 SVG 平移和缩放:
panAndZoom = svgPanZoom(targetElement.childNodes[0],
{
viewportSelector: targetElement.childNodes[0].childNodes[0],
fit: false,
zoomScaleSensitivity: 0.4,
panEnabled: false
});
其中targetElement是jointjs论文进入的div。 Jointjs 将在其中创建一个 SVG 元素(因此是 childNodes[0]),并且在该元素中第一个元素是视口标签(因此是视口选择器中的 childNodes[0].childNodes[0])。在这个阶段平移被禁用,因为在我的用例中它会干扰在纸上拖放元素。相反,我所做的是保留对 panAndZoom 对象的引用,然后在 blank:pointerdown 和 blank:pointerup 事件上打开和关闭平移:
paper.on('blank:pointerdown', function (evt, x, y) {
panAndZoom.enablePan();
});
paper.on('cell:pointerup blank:pointerup', function(cellView, event) {
panAndZoom.disablePan();
});
我想这只是解决问题的另一种方法,但我发现它更容易一些,而且它还可以缩放并且可以调整灵敏度等。
这可以通过结合 JointJS 事件和文档事件来实现。图形显示封装在 div
:
<div id='diagram'></div>
然后为 JointJS 添加事件处理程序,首先是我们存储拖动开始位置的 pointerdown
事件:
paper.on('blank:pointerdown',
function(event, x, y) {
dragStartPosition = { x: x, y: y};
}
);
然后当我们删除存储位置的变量时拖动结束(pointerup)(它也作为标志是否有正在进行的活动拖动):
paper.on('cell:pointerup blank:pointerup', function(cellView, x, y) {
delete dragStartPosition;
});
由于JointJS没有公开"paper pointer move"事件,我们需要使用mousemove
文档事件。例如,JQuery:
$("#diagram")
.mousemove(function(event) {
if (dragStartPosition)
paper.translate(
event.offsetX - dragStartPosition.x,
event.offsetY - dragStartPosition.y);
});
我们获取拖动开始坐标和当前指针位置,并使用 paper.translate()
调用更新纸张位置。
警告:如果缩放纸张(使用paper.scale()
),则还必须缩放拖动的起始位置:
var scale = V(paper.viewport).scale();
dragStartPosition = { x: x * scale.sx, y: y * scale.sy};
然后对 paper.translate()
的调用将更新到正确的位置。