-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Explore Animation Observables #34
Comments
Here is some messing around I did with RxKotlinFX and TornadoFX. This creates a
class MyView: View() {
override val root = VBox()
init {
with(root) {
val rectangle = Rectangle(50.0, 50.0, 50.0, 50.0).apply {
padding = Insets(20.0)
}
this += rectangle
JavaFxObservable.interval(Duration.millis(10000))
.map { it * 1.0 }
.scan { x, y -> x + y }
.subscribe {
val timeline = Timeline()
val keyValue = KeyValue(rectangle.rotateProperty(), it)
val keyFrame = KeyFrame(Duration.millis(500.0), keyValue)
timeline.cycleCount = 1
timeline.keyFrames += keyFrame
timeline.play()
}
}
}
} |
I just added a JavaFxObservable.interval(Duration.millis(1000))
.subscribe(i -> System.out.println(i)); |
Haha, oh my gosh this is fun. Using some creative Observable.concat(JavaFxObservable.interval(Duration.millis(10000))
.map { it * 1.0 }
.scan { x, y -> x + y }
.takeWhile { it < 90.0 }, Observable.just(0.0))
.subscribeAnimation(rectangle.rotateProperty().asObject(), Duration.seconds(1.0), Interpolator.EASE_OUT) I can even compose it to do this routine three times. Observable.range(0, 2)
.concatMap {
Observable.concat(JavaFxObservable.interval(Duration.millis(10000))
.map { it * 1.0 }
.scan { x, y -> x + y }
.takeWhile { it < 90.0 }, Observable.just(0.0))
}.subscribeAnimation(rectangle.rotateProperty().asObject(), Duration.seconds(1.0), Interpolator.EASE_OUT) |
Alright, here is a complete working concept written in Java. I don't know if the In this example, it will keep rotating the square at increasing speed until it hits 90 degrees rotation, then it "snaps back" to 0. Then it rotates -180 degrees in the opposite direction and snaps back again. What's cool here though is the import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
import rx.Observable;
import rx.observables.JavaFxObservable;
import java.util.concurrent.atomic.AtomicBoolean;
public final class JavaFxApp extends Application {
private final Rectangle rectangle = new Rectangle(60,60,60,60);
private final Button startStopButton = new Button("Start/Stop");
private final AtomicBoolean isWorking = new AtomicBoolean(false);
@Override
public void start(Stage primaryStage) throws Exception {
BorderPane root = new BorderPane();
root.setCenter(rectangle);
root.setBottom(startStopButton);
JavaFxObservable.fromActionEvents(startStopButton)
.map(ae -> isWorking.getAndSet(!isWorking.get()))
.switchMap(b -> {
if (b) {
return Observable.just(0);
} else {
return Observable.concat(
JavaFxObservable.interval(Duration.millis(200))
.map(i -> i * 2)
.takeWhile(i -> rectangle.getRotate() <= 90),
Observable.just(0), //reset
JavaFxObservable.interval(Duration.millis(200))
.map(i -> i * -3)
.takeWhile(i -> rectangle.getRotate() >= -180),
Observable.just(0) //reset
).doOnCompleted(() -> isWorking.set(false));
}
}).subscribe(i -> {
Timeline timeline = new Timeline();
KeyValue keyValue = new KeyValue(rectangle.rotateProperty(), i, Interpolator.EASE_OUT);
KeyFrame keyFrame = new KeyFrame(Duration.seconds(1), keyValue);
timeline.getKeyFrames().add(keyFrame);
timeline.play();
});
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
} I don't think any additional code other than the |
Okay, I think I'm ready to close this issue and do a release later. Another application, throttling the sequence with import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
import rx.Observable;
import rx.observables.JavaFxObservable;
public final class JavaFxApp extends Application {
private final Rectangle rectangle = new Rectangle(60,60,60,60);
private final Button nextButton = new Button("Next");
private final Label rotationLabel = new Label("0");
@Override
public void start(Stage primaryStage) throws Exception {
BorderPane root = new BorderPane();
root.setCenter(rectangle);
root.setLeft(nextButton);
root.setBottom(rotationLabel);
Observable<ActionEvent> buttonClicks = JavaFxObservable.fromActionEvents(nextButton);
Observable<Integer> sequence = Observable.concat(
Observable.range(1,1000)
.map(i -> i * 10)
.zipWith(buttonClicks, (i,ae) -> i)
.takeWhile(i -> rectangle.getRotate() <= 90),
Observable.just(0).zipWith(buttonClicks, (i,ae) -> i), //reset
Observable.range(1,1000)
.map(i -> i * -20)
.zipWith(buttonClicks, (i,ae) -> i)
.takeWhile(i -> rectangle.getRotate() >= -180),
Observable.just(0).zipWith(buttonClicks, (i,ae) -> i) //reset
);
sequence.subscribe(i -> {
Timeline timeline = new Timeline();
KeyValue keyValue = new KeyValue(rectangle.rotateProperty(), i, Interpolator.EASE_OUT);
KeyFrame keyFrame = new KeyFrame(Duration.seconds(1), keyValue);
timeline.getKeyFrames().add(keyFrame);
timeline.play();
});
JavaFxObservable.fromObservableValue(rectangle.rotateProperty())
.map(Object::toString)
.subscribe(rotationLabel::setText);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
} |
I'll need to do some exploring and see if RxJavaFX can support animation a little better.
http://www.java2s.com/Tutorials/Java/JavaFX/1010__JavaFX_Timeline_Animation.htm
The text was updated successfully, but these errors were encountered: