2017-08-17 5 views
6

私は、移動すると、サブセンテンのコンテンツだけが見えるように移動することを許可しないように、JavaFXにおけるカメラの移動に関する制限を設定しようとしています。現在のところ、私の移動コードは以下のように見えますが、これを防ぐためのチェックはありません。カメラの動きを制限して、サブセンテンの内容を表示するかどうかを調べることでカメラの動きを制限しようとしましたが、それは純粋に近似であり、ズームするときである。 TLDRの問題は、カメラがコンテンツから離れるときを検出することと、カメラがコンテンツから離れるようになると変換が起こらないようにすることです。カメラからコンテンツへのバウンディング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私はほとんどの形式の変換を許可していますが、Z軸変換以外の変換は適用されませんが、カメラでX軸とY軸に沿って移動しながら適用する制約を探しています –

答えて

0

これはかなり一般的です:移動した後、移動した後、外出しているかどうかを確認してください。その場合、シーンに戻る...これは通常、携帯電話で画像をパンしようとすると自然です..それはブロックするだけではありません:それは抵抗をしているように見えます。あなたのジェスチャーを終えると、それは戻ってきます...それは最も簡単なことです。

1

カメラには移動可能なオーバーレイとして想像できるビューポートがあります(コンテンツが配置されていない領域に背景が表示されます)。簡単にするために、私はコンテンツの変換(例えば、ズーム)からスクロール(すなわち、ビューポートの移動)を分離する。

enter image description here

このメンタルモデルに基づいて、あなたはあなたの内容の範囲だけでなく、現在のビューポート(ビューポートよりも小さい内容の場合は、例えば)の空の可能性部分であることを、スクロール可能な範囲を定義することができます。スクロール操作(現在のビューポート内の空きスペースの増減)またはコンテンツ操作(変換および境界変更)ごとに、スクロール可能な境界を再計算する必要があります。スクロールをスクロール可能な境界に制限すると、スクロール操作によってビューポート内の空き領域が増えることはありません。

コンテンツのbounds-in-localプロパティとlocal-to-parent-transformプロパティにバインドされたObjectBinding scrollableBoundsを作成し、ビューポート境界にすることができます。次に、バインディングにバインドされている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

関連する問題