使用d3.js拖动元素时滚动 [英] scroll while dragging element with d3.js
问题描述
我正在svg元素上使用d3的拖动行为,可能需要将其拖放到可见区域之外.我在两个div内设置了溢出,将其设置为自动以启用滚动.我只能在某些浏览器上使用此功能,但不能在所有浏览器上使用.
I am using d3's drag behavior on an svg element that might need to be dropped outside of the visible area. I have it setup within two divs with overflow set to auto to enable scrolling. I have this only working with some browsers but not all.
问题在于,在某些浏览器中,拖动时可以滚动,但在其他浏览器中,拖动时窗口将不滚动.到目前为止,我一直无法找到一种使这项工作始终如一的方法.
The issue is that in some browsers, you will be able to scroll while dragging, but in others the window will not scroll while dragging. I have as of yet been unable to find a way to make this work consistently.
有关工作示例,请参见小提琴: http://jsfiddle.net/glanotte/qd5Td/1/
for a working example see the fiddle: http://jsfiddle.net/glanotte/qd5Td/1/
这在以下方面按预期工作:
This is working as expected on:
chrome-Mac/Windows Safari-Mac
chrome - mac/windows safari - mac
但不能继续工作
Firefox-Mac/Windows IE-Windows
Firefox - mac/windows IE - windows
html:
<div id="outerFrame">
<div id="innerFrame">
<svg width="600" height="600">
</svg>
</div>
</div>
css:
#outerFrame{
width: 300px;
height: 300px;
border: 1px solid red;
overflow: auto;
}
#innerFrame{
width: 600px;
height: 600px;
background-color: lightgrey;
}
javascript:
javascript:
var drag = d3.behavior.drag()
.on("dragstart", dragstart)
.on("drag", dragmove)
.on("dragend", dragend);
function dragstart() {
d3.select(this).style("border", "1px solid red");
}
function dragmove(d) {
var coordinates = d3.mouse(d3.select("svg").node());
d3.select(this).attr({
x: coordinates[0] - 50,
y: coordinates[1] - 25
})
}
function dragend() {
d3.select(this).style("border", null);
}
d3.select("svg")
.append("rect")
.attr({x: 100, y: 100, width: 100, height: 50})
.call(drag);
推荐答案
很遗憾,您遇到了错误已被之前由mbostock和标记为WONT-FIX .
You have unfortunately struck upon a bug in Firefox which has been noticed before by mbostock and marked as WONT-FIX.
根据错误报告中的建议,您可以使其正常运行,但只能通过手动滚动容器来完成: http://jsfiddle.net/62CYD/
As per suggestion in the bug report, you can make it work, but only by scrolling the container manually: http://jsfiddle.net/62CYD/
实施非常简单,可以通过以下方式进行改进:
The implementation is pretty simple and can be improved by:
- 使用动画
- 考虑滚动条的宽度,考虑当前的鼠标位置,以避免被拖动的项目卡住并平滑滚动.
- 即使拖动停止,也可以使用
setTimeout
继续滚动
- Using animations
- Taking into account width of scroll bars, like done in
DOMUtilityService
inng-grid
. - Taking current mouse position into account to avoid snapping of the dragged item and smoother scrolling.
- Use
setTimeout
to continue scrolling even if dragging stops
function dragmove(d) {
var svg = d3.select("svg").node(),
$parent = $('#outerFrame'),
w = $parent.width(), h = $parent.height(),
sL = $parent.scrollLeft(), sT = $parent.scrollTop();
var coordinates = d3.mouse(svg),
x = coordinates[0],
y = coordinates[1];
if (x > w + sL) {
$parent.scrollLeft(x - w);
} else if (x < sL) {
$parent.scrollLeft(x);
}
if (y > h + sT) {
$parent.scrollTop(y - h);
} else if (y < sT) {
$parent.scrollTop(y);
}
d3.select(this).attr({
x: x - 50,
y: y - 25
})
}
这篇关于使用d3.js拖动元素时滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!