mirror of
https://github.com/aNNiMON/HotaruFX.git
synced 2024-09-19 14:14:21 +03:00
Ability to pause and seek animation
This commit is contained in:
parent
aec580e60c
commit
3adc39f288
@ -34,6 +34,7 @@ import javafx.scene.control.TitledPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Modality;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.util.Duration;
|
||||
import lombok.val;
|
||||
import org.fxmisc.richtext.CodeArea;
|
||||
import org.fxmisc.richtext.LineNumberFactory;
|
||||
@ -157,7 +158,17 @@ public class EditorController implements Initializable, DocumentListener {
|
||||
stage.initOwner(primaryStage);
|
||||
stage.initModality(Modality.WINDOW_MODAL);
|
||||
stage.setScene(composition.produceAnimationScene());
|
||||
composition.getTimeline().getFxTimeline().play();
|
||||
val timeline = composition.getTimeline();
|
||||
timeline.getFxTimeline().currentTimeProperty().addListener((o, oldValue, d) -> {
|
||||
val min = (int) d.toMinutes();
|
||||
val durationSec = d.subtract(Duration.minutes(min));
|
||||
val sec = (int) durationSec.toSeconds();
|
||||
val durationMs = durationSec.subtract(Duration.seconds(sec));
|
||||
val frame = (int) (durationMs.toMillis() * timeline.getFrameRate() / 1000d);
|
||||
val allFrame = (int) (d.toMillis() * timeline.getFrameRate() / 1000d);
|
||||
stage.setTitle(String.format("%02d:%02d.%02d %d", min, sec, frame, allFrame));
|
||||
});
|
||||
stage.setOnShown(e -> timeline.getFxTimeline().play());
|
||||
stage.show();
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package com.annimon.hotarufx.visual;
|
||||
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.Paint;
|
||||
import lombok.Getter;
|
||||
@ -62,6 +63,30 @@ public class Composition {
|
||||
}
|
||||
|
||||
public Scene produceAnimationScene() {
|
||||
return new Scene(scene.getGroup(), sceneWidth, sceneHeight, background);
|
||||
val fxScene = new Scene(scene.getGroup(), sceneWidth, sceneHeight, background);
|
||||
fxScene.setOnKeyPressed(e -> {
|
||||
switch (e.getCode()) {
|
||||
case SPACE:
|
||||
timeline.togglePause();
|
||||
break;
|
||||
case BACK_SPACE:
|
||||
timeline.getFxTimeline().playFromStart();
|
||||
break;
|
||||
case LEFT:
|
||||
case RIGHT:
|
||||
int sign = e.getCode() == KeyCode.LEFT ? -1 : 1;
|
||||
if (e.isShiftDown()) {
|
||||
timeline.seek(sign);
|
||||
} else if (e.isControlDown()) {
|
||||
timeline.seek(10 * sign);
|
||||
} else if (e.isAltDown()) {
|
||||
timeline.seek(30 * sign);
|
||||
} else {
|
||||
timeline.seekFrame(sign);
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
return fxScene;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import javafx.animation.KeyValue;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.util.Duration;
|
||||
import lombok.Getter;
|
||||
import lombok.val;
|
||||
|
||||
public class TimeLine {
|
||||
|
||||
@ -26,4 +27,31 @@ public class TimeLine {
|
||||
private Duration duration(KeyFrame keyFrame) {
|
||||
return Duration.millis(1000d * keyFrame.getFrame() / frameRate);
|
||||
}
|
||||
|
||||
public void togglePause() {
|
||||
switch (fxTimeline.getStatus()) {
|
||||
case PAUSED:
|
||||
fxTimeline.play();
|
||||
break;
|
||||
case RUNNING:
|
||||
fxTimeline.pause();
|
||||
break;
|
||||
case STOPPED:
|
||||
fxTimeline.playFromStart();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void seekFrame(final int value) {
|
||||
fxTimeline.pause();
|
||||
val offset = Duration.millis(1000d * Math.abs(value) / frameRate);
|
||||
val now = fxTimeline.getCurrentTime();
|
||||
val newDuration = value > 0 ? now.add(offset) : now.subtract(offset);
|
||||
fxTimeline.jumpTo(newDuration);
|
||||
}
|
||||
|
||||
public void seek(final int sec) {
|
||||
val now = fxTimeline.getCurrentTime();
|
||||
fxTimeline.jumpTo(now.add(Duration.seconds(sec)));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user