我试图在JavaFX中对摄像机的移动设置限制,这样当它移动时,它不允许用户以只有子场内容可见的方式移动。目前,我的移动代码看起来如下,并没有检查来防止这种情况,我已经尝试通过检查其坐标并近似它是否将显示子场景的内容来限制相机的移动,但是那里有问题它只是一个近似值和缩放时。 TLDR,问题涉及1当摄像机远离其内容时检测到,2防止转换发生,如果它会导致摄像机远离内容。
mapView.addEventFilter(MouseEvent.MOUSE_PRESSED, e->{
startX = e.getX();
startY = e.getY();
});
mapView.addEventFilter(MouseEvent.MOUSE_DRAGGED, e -> {
camera.setTranslateX(camera.getTranslateX() + (startX - e.getX()));
camera.setTranslateY(camera.getTranslateY() + (startY - e.getY()));
});
如果相关,则mapView是一个MeshView。
如果您希望我澄清任何内容或需要进一步的信息,我会提供。感谢您的帮助和美好的一天。
答案 0 :(得分:1)
相机有一个视口,您可以将其视为内容上方的可移动覆盖(某些背景显示在未放置内容的区域)。为简单起见,我将滚动(即移动视口)与内容转换(例如缩放)分开。
基于此心理模型,您可以将可滚动边界定义为内容的边界以及当前视口的可能空白部分(例如,在内容小于视口的情况下)。在每次滚动操作(增加/减少当前视口中的空白空间)或内容操作(转换和边界更改)之后,需要重新计算可滚动边界。如果将滚动限制为可滚动边界,则可以确保视口中的空白空间永远不会通过滚动操作增加。
您可以创建绑定到内容的ObjectBinding scrollableBounds' bounds-in-local和local-to-parent-transform属性,以及视口边界。然后,您可以创建绑定到绑定的scollableBoundsProperty。滚动时可以访问该属性以在应用之前限制转换,从而防止视口内的空白空间增加。
ObjectBinding<Bounds> scrollableBoundsBinding = new ObjectBinding<>() {
{
// TODO: bind to dependencies: viewport bounds and content bounds
// TODO: (transformed to the same coordinate system)
bind(camera.boundsInParentProperty(),
contentPane.boundsInLocalProperty(),
contentPane.localToParentTransformProperty());
}
@Override protected Bounds computeValue() {
// TODO: compute union of viewport and content bounds
return unionBounds(viewportBounds, contentBounds);
}
};
ObjectProperty<Bounds> scrollableBoundsProperty = new SimpleObjectProperty<>(
scrollableBoundsBinding);
// ...
// on mouse drag:
// dx, dy: relative mouse movement
// tx, ty: current scrolling
// mintx, maxtx, minty, maxty: translation range
// (taken from scrollable bounds and viewport size)
if (dx < 0) { tx = max(mintx, tx + dx); }
else { tx = min(maxtx, tx + dx); }
if (dy < 0) { ty = max(minty, ty + dy); }
else { ty = min(maxty, ty + dy); }
当内容完全适合视口时,您可能希望进一步限制滚动,例如将内容放在左上角。在这种情况下,您还可以限制最小缩放级别,以便内容显示得尽可能大。
关于可用性的注意事项:正如另一个答案已经指出的那样,您可能需要考虑允许稍微拖动内容,可能效率越低,尝试从内容滚动的距离越远,与行为相似在Safari中通过触摸板滚动。然后,当交互完成后,您可以转换回而不是捕捉,以便再次将视口限制为内容。
答案 1 :(得分:0)
这很常见:只需移动并在移动后检查您是否超出界限......在这种情况下返回场景......这通常会让您感觉很自然,就像您尝试在手机上平移图像一样。它不只是阻止:看起来它正在制造阻力,当你结束你的手势时它会回来......这是最简单的事情