2017-08-17 87 views
6

我想設置對JavaFX中相機移動的限制,使其在移動時不允許用戶以只能看到子內容的方式移動。目前,我的移動代碼看起來如下,並沒有檢查,以防止這種情況,我試圖通過檢查其座標限制相機的移動,並近似,如果它會或不會顯示subscene的內容,但那有問題在那這純粹是一種近似和縮放。 TLDR,該問題涉及1檢測攝像機何時離開它的內容,以及2如果它導致攝像機遠離內容,則防止發生變換。將相機綁定到內容Javafx

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

您允許在內容上進行什麼樣的轉換? –

+0

@JoseMartinez我允許大多數形式的轉換,但我只想尋找約束條件來適用於沿照相機沿X軸和Y軸移動,而沒有應用除Z軸轉換之外的其他轉換 –

回答

0

這很常見:移動和移動之後檢查您是否超出範圍......在這種情況下,返回到場景......這通常會感覺很自然,因爲當您嘗試在手機上平移圖像時..它並不僅僅阻擋:看起來它是阻力,當你結束你的手勢時,它會返回...這是最簡單的事情要做

1

相機有一個視口,你可以想象它是一個可移動的疊加層以上的內容(一些背景顯示在沒有內容放置的區域)。爲了簡單起見,我將從內容轉換(例如縮放)中分離滾動(即移動視口)。

enter image description here

基於該心理模型,可以定義可滾動邊界成爲你內容的邊界以及當前視口的(在大於視口較小的內容的情況下例如)一個可能是空的部分。每次滾動操作(增加/減少當前視口內的空白空間)或內容操作(轉換和邊界更改)後,需要重新計算可滾動邊界。如果將滾動限制爲可滾動邊界,則可以確保視口內的空白空間不會因滾動操作而增加。

您可以創建一個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中通過觸摸板滾動。然後,當交互完成時,您可以轉換回來而不是捕捉,以便再次將視口限制爲內容。

+0

'unionBounds'在@Override方法中的示例中引用? –

+0

這是您必須實施的方法,這就是爲什麼我在那裏放置一些TODO。您還應該驗證您真正需要計算可滾動邊界的依賴關係。 – Matthias