2017-04-21 7 views
0

私はTilesPaneのレイアウトに追加するImageViewを持っています。私は、(x,y)の位置から追加する位置までImageViewをアニメートしたいと思います。ノードをレイアウトにアニメーションする

私はこのような何か試してみました:

TilePane tp = new TilePane(); 

... 

ImageView iv = new ImageView(img); 
tp.getChildren().add(iv); 

TranslateTransition tt = new TranslateTransition(Duration.seconds(5), iv); 
tt.setFromX(0); 
tt.setFromY(0); 
tt.setToX(iv.x); 
tt.setToY(iv.y); 
tt.play(); 

をしかし、私はこのエラーを取得する:私はやってみました何error: x has private access in ImageView

  1. TilePaneレイアウトに画像を追加します。
  2. イメージの位置を取得します。
  3. 指定された(x,y)位置から現在の位置に画像をアニメートします。

これが正しい/最良の方法でない場合は、どのような選択肢がありますか?そうであれば、どうすればこのエラーを回避できますか?

+0

HTTPS([関連するコードのすべて]をご提示ください。 // stackoverflow.com/help/mcve)と完全なスタックトレース(もしあれば)があります。あなたはどうやって「イメージの位置を取得するか」とは言わない。 – jewelsea

+0

@jewelseaそれぞれxとyの座標に 'iv.x'と' ix.y'を使います – sudoman

+0

ああ、コンパイルされません。 [レイアウトパスを生成する]必要があります(http://stackoverflow.com/questions/26152642/get-the-height-of-a-node-in-javafx-generate-a-layout-pass)。ノードはlayoutXとlayoutYの値が設定されたときに終了し、次にソース位置とレイアウトの位置の差が負の値に設定されます。ソースの場所の座標系が何であるかは指定しません。シーンの座標とsceneToLocalを使用する場合はおそらく。ちょうどいくつかの考え、多分私はそれを試してみましょう。 – jewelsea

答えて

2

、あまり追加しません。開始点は無作為に計算され、シーン座標にあり、次にsceneToLocal関数を介してローカル座標に変換されます。

なんらかの理由で(私がわからない)ステージが表示されるまで(tilePaneの高さと幅が0と表示される前に)、tilePaneのレイアウトパス要求が機能していないようです。だから私は何か計算やアニメーションをしようとする前に、最初にステージを示します。ランダムな開始位置で

魚:アニメーション後のタイル張りの学校で

randomstart

魚:

ordered finish

import javafx.animation.*; 
import javafx.application.Application; 
import javafx.geometry.*; 
import javafx.scene.Group; 
import javafx.scene.Node; 
import javafx.scene.Scene; 
import javafx.scene.image.*; 
import javafx.scene.layout.TilePane; 
import javafx.stage.Stage; 
import javafx.util.Duration; 

import java.util.*; 
import java.util.stream.Collectors; 

public class Layup extends Application { 

    private final Random random = new Random(42); 

    // image license: linkware - backlink to http://www.fasticon.com 
    private static final String[] IMAGE_LOCS = { 
      "http://icons.iconarchive.com/icons/fasticon/fish-toys/128/Blue-Fish-icon.png", 
      "http://icons.iconarchive.com/icons/fasticon/fish-toys/128/Red-Fish-icon.png", 
      "http://icons.iconarchive.com/icons/fasticon/fish-toys/128/Yellow-Fish-icon.png", 
      "http://icons.iconarchive.com/icons/fasticon/fish-toys/128/Green-Fish-icon.png" 
    }; 

    @Override 
    public void start(Stage stage) throws Exception { 
     TilePane tilePane = createTilePane(IMAGE_LOCS); 

     Scene scene = new Scene(new Group(tilePane)); 

     stage.setScene(scene); 
     stage.show(); 
     stage.setTitle("Click on the scene to animate"); 

     animateIn(tilePane); 

     scene.setOnMouseClicked(event -> animateIn(tilePane)); 
    } 

    private TilePane createTilePane(String[] imageLocs) { 
     TilePane tilePane = new TilePane(10, 10); 
     tilePane.setPrefColumns(2); 

     Arrays.stream(imageLocs).map(
       loc -> new ImageView(new Image(
         loc, 64, 0, true, true 
       )) 
     ).collect(Collectors.toCollection(tilePane::getChildren)); 

     tilePane.setPadding(new Insets(200)); 
     return tilePane; 
    } 

    private void animateIn(TilePane tilePane) { 
     // layout tilePane 
     tilePane.applyCss(); 
     tilePane.layout(); 

     double W = (int) tilePane.getScene().getWidth(); 
     double H = (int) tilePane.getScene().getHeight(); 

     ParallelTransition pt = new ParallelTransition(); 

     for (int i = 0; i < IMAGE_LOCS.length; i++) { 
      Node child = tilePane.getChildren().get(i); 

      Point2D start = new Point2D(
        random.nextInt((int) (W - child.getBoundsInLocal().getWidth())), 
        random.nextInt((int) (H - child.getBoundsInLocal().getHeight())) 
      ); 

      Point2D startInLocal = child.sceneToLocal(start); 

      TranslateTransition tt = new TranslateTransition(Duration.seconds(.5), child); 
      tt.setFromX(startInLocal.getX()); 
      tt.setFromY(startInLocal.getY()); 
      tt.setToX(0); 
      tt.setToY(0); 

      pt.getChildren().add(tt); 
     } 

     pt.play(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+0

遅い返事のビット(申し訳ありません)、私はあなたの答えを受け入れることが本当に好きです、それは欠けているものがあります、どのように私たちは同じ位置から開始する魚を得ることができますか? – sudoman

+1

すべてを同じ位置から開始する場合は、TilePaneではなくStackPaneを使用してください。私はちょうどそれがあなたの質問で使用しているものとしてTilePaneを使用していましたので、タイルの位置からアイテムを開始したいと思っていました。 – jewelsea

1

最終的な位置は、レイアウトパスの後でlayoutXおよびlayoutYのプロパティによって決定されます。さらに、任意の遷移はこの位置に関連するので、(0, 0)は遷移の最終値である必要があります。

これは私が、それはファビアンの回答に似て思い付いたものです

private static final double START_X = 50; 
private static final double START_Y = 50; 

@Override 
public void start(Stage primaryStage) { 
    TilePane tilePane = new TilePane(); 
    tilePane.setPrefSize(200, 200); 
    Image image = new Image("https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-icon.png", 50, 50, true, false); 
    Button btn = new Button("add"); 
    btn.setOnAction((ActionEvent event) -> { 
     ImageView img = new ImageView(image); 
     tilePane.getChildren().add(img); 

     // layout tilePane 
     tilePane.applyCss(); 
     tilePane.layout(); 

     // create transition from start position to final position 
     TranslateTransition transition = new TranslateTransition(Duration.seconds(4), img); 
     transition.setFromX(START_X - img.getLayoutX()); 
     transition.setFromY(START_Y - img.getLayoutY()); 
     transition.setToX(0); 
     transition.setToY(0); 

     transition.play(); 
    }); 

    VBox root = new VBox(btn, tilePane); 

    Scene scene = new Scene(root); 

    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 
+0

私が探しているものではなく、指定された位置から画像が始まりません。シーン内の座標で正確に始まる必要があります。それはまだ画像自体に相対的です – sudoman

関連する問題