# Rechteck Mit Hilfe Von Timeline, KeyFrames animieren



## bluna (6. Dez 2012)

Nabend...

Es geht um JavaFx 2.x

Ich möchte gerne ein Rechteck mit Hilfe von einer Timeline und KeyFrames animieren.

Die Animation soll so verlaufen, dass das Rechteck sich sich im Rechteck bewegt.

Von der Startposition (z.b. x=100, y=100) 100pixel nach rechts, dann 100 nach unten, dann 100 nach links und dann 100 nach oben.

Nach vielen verschiedenen Ansätzen habe ich es leider nicht geschafft das Rechteck so zu bewegen - Nach der 2. Richtungsänderung verhält es sich für mich "komisch" - weil ich das Timline/Keyframe/Interpolator - wohl noch nicht durchschaut habe.

Mein aktuelle Lösungsansatz


```
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class MovingRectangle extends Application {

	@Override
	public void start(Stage stage) throws Exception {
		Group group = new Group();
		Scene scene = new Scene(group);
		stage.setWidth(500);
		stage.setHeight(500);
		Rectangle rect = new Rectangle(100, 100, 200, 200);
		rect.fillProperty().set(Color.GREEN);
		
		group.getChildren().add(rect);
		
		stage.setScene(scene);
		stage.show();
		
		KeyValue x1 = new KeyValue(rect.xProperty(), rect.xProperty().doubleValue());
		KeyValue y1 = new KeyValue(rect.yProperty(), rect.yProperty().doubleValue());
		
		KeyValue x2 = new KeyValue(rect.xProperty(), rect.xProperty().doubleValue()+50);
		KeyValue y2 = new KeyValue(rect.yProperty(), rect.yProperty().doubleValue());
		
		KeyValue x3 = new KeyValue(rect.xProperty(), rect.xProperty().doubleValue());
		KeyValue y3 = new KeyValue(rect.yProperty(), rect.yProperty().doubleValue()+50);
		
		KeyValue x4 = new KeyValue(rect.xProperty(), rect.xProperty().doubleValue()-50);
		KeyValue y4 = new KeyValue(rect.yProperty(), rect.yProperty().doubleValue());
		
		KeyValue x5 = new KeyValue(rect.xProperty(), rect.xProperty().doubleValue());
		KeyValue y5 = new KeyValue(rect.yProperty(), rect.yProperty().doubleValue()-50);

		KeyFrame kf1 = new KeyFrame(Duration.seconds(0), x1, y1);
		KeyFrame kf2 = new KeyFrame(Duration.seconds(2), x2, y2);
		KeyFrame kf3 = new KeyFrame(Duration.seconds(4), x3, y3);
		KeyFrame kf4 = new KeyFrame(Duration.seconds(6), x4, y4);
		KeyFrame kf5 = new KeyFrame(Duration.seconds(8), x5, y5);
		
		Timeline timeline = new Timeline();
		timeline.getKeyFrames().addAll(kf1, kf2, kf3, kf4, kf5);
		timeline.play();

	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Application.launch(null);
	}

}
```



Wer erklärt mir warum es nicht funktioniert / Postet die Lösung


----------



## Paddelpirat (7. Dez 2012)

Hi,

guck dir mal die Doku zu Timeline an. Das wird eigentlich dazu verwendet um Aktionen parallel durchzuführen. Daher kommen deine "unerwarteten" Bewegungen, denn du führst mehrere Aktionen gleichzeitig aus. Außerdem gibst du bei den KeyFrames die Dauer der Bewegung an und nicht den zeitlichen Startpunkt. Dies führt dazu, dass manche Bewegungen "richtig" und manche "falsch" aussehen, da sie sich überschneiden.

Für deinen Fall gibt es die PathTransition:


```
Path path = new Path();
        path.getElements().add(new MoveTo(100, 100));
        path.getElements().add(new LineTo(200.0f, 100.0f));
        path.getElements().add(new MoveTo(200, 100));
        path.getElements().add(new LineTo(200.0f, 200.0f));
        path.getElements().add(new MoveTo(200, 200));
        path.getElements().add(new LineTo(100.0f, 200.0f));
        path.getElements().add(new MoveTo(100, 200));
        path.getElements().add(new LineTo(100.0f, 100.0f));
        path.getElements().add(new MoveTo(100, 100));
        
        
        PathTransition pathTransition = new PathTransition();
        pathTransition.setDuration(Duration.millis(8000));
        pathTransition.setPath(path);
        pathTransition.setNode(rect);
        pathTransition.setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
        pathTransition.play();
```


----------



## bluna (9. Dez 2012)

hi, danke für die antwort.

ich habe bereits die offizielle oracle-doku gelesen.
Ich sehe zwar dass ich offentsichtlich irgend etwas nicht verstanden zu haben, aber ich habe nirgends davon gelesen, dass die Timeline generell nur für Paralele Animationen gedacht ist. Kannst du mir sagen, wo du das gelsen hast ?


----------



## Paddelpirat (9. Dez 2012)

Ich gebe zu so ganz explizit steht es da auch nicht. Ich habe mich bei meinem Test mal zwei KeyFrames beschränkt, wobei das eine eine horizontale und das andere eine vertikale Bewegung durchführen sollte.

Als Ergebnis erhielt ich eine schräge Bewegung, also hat die Timeline die einzelnen Schritte der beiden KeyFrames abwechselnd abgearbeitet. In der JavaFX-Doku steht dann noch dieser Satz:


```
Timeline processes individual KeyFrame at or after specified time interval elapsed, it does not guarantee the timing when KeyFrame is processed.
```

Heißt für mich, dass man das benutzen sollte, wenn man mehrere Aktionen durchführen möchte und die Reihenfolge in der dies stattfindet egal ist.

Außerdem hörte sich die PathTransition schon sehr nach dem an, was du machen wolltest. Wobei man auch mehrere PathTransitions definieren und sie dann mit einer SequentialTransition nacheinander ausführen könnte.

Timeline (JavaFX 2.2)


----------

