1
0
mirror of https://github.com/aNNiMON/HotaruFX.git synced 2024-09-19 14:14:21 +03:00

More abstractions

This commit is contained in:
Victor 2017-08-24 17:38:51 +03:00
parent 1df345c996
commit d9001bc106
10 changed files with 131 additions and 34 deletions

View File

@ -1,24 +1,26 @@
package com.annimon.hotarufx; package com.annimon.hotarufx;
import com.annimon.hotarufx.visual.Composition; import com.annimon.hotarufx.visual.Composition;
import com.annimon.hotarufx.visual.KeyFrame;
import com.annimon.hotarufx.visual.objects.CircleNode; import com.annimon.hotarufx.visual.objects.CircleNode;
import javafx.application.Application; import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.scene.paint.Paint; import javafx.scene.paint.Paint;
import javafx.stage.Stage; import javafx.stage.Stage;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.val; import lombok.val;
public class Main extends Application { public class Main extends Application {
@Override @Override
public void start(Stage primaryStage) { public void start(Stage primaryStage) {
val group = new Group(); val composition = new Composition(1280, 720, 30);
val composition = new Composition(1280, 720, Color.WHITE, group); val scene = composition.newScene(KeyFrame.of(0));
val colors = new Paint[] {Color.GREEN, Color.RED}; val colors = new Paint[] {Color.GREEN, Color.RED};
val halfWidth = composition.getVirtualWidth() / 2; val halfWidth = scene.getVirtualWidth() / 2;
val halfHeight = composition.getVirtualHeight() / 2; val halfHeight = scene.getVirtualHeight() / 2;
for (int y = -1; y <= 1; y++) { for (int y = -1; y <= 1; y++) {
for (int x = -1; x <= 1; x++) { for (int x = -1; x <= 1; x++) {
val circle = new CircleNode(); val circle = new CircleNode();
@ -26,13 +28,9 @@ public class Main extends Application {
circle.getCircle().setCenterX(x * halfWidth); circle.getCircle().setCenterX(x * halfWidth);
circle.getCircle().setCenterY(y * halfHeight); circle.getCircle().setCenterY(y * halfHeight);
circle.getCircle().setRadius(50); circle.getCircle().setRadius(50);
circle.render(composition); circle.render(scene);
} }
} }
primaryStage.setTitle("HotaruFX");
primaryStage.setScene(composition.getScene());
primaryStage.show();
} }
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -0,0 +1,10 @@
package com.annimon.hotarufx.exceptions;
import com.annimon.hotarufx.visual.KeyFrame;
public class KeyFrameDuplicationException extends RuntimeException {
public KeyFrameDuplicationException(KeyFrame keyFrame) {
super("Key frame " + keyFrame.getFrame() + " already exists in timeline");
}
}

View File

@ -1,19 +1,13 @@
package com.annimon.hotarufx.visual; package com.annimon.hotarufx.visual;
import javafx.scene.Group; import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.paint.Paint; import javafx.scene.paint.Color;
import lombok.Getter; import lombok.Getter;
import lombok.val;
public class Composition { public class Composition {
@Getter
private final Group group;
@Getter
private final Scene scene;
@Getter @Getter
private final int private final int
virtualWidth, virtualHeight, virtualWidth, virtualHeight,
@ -21,22 +15,34 @@ public class Composition {
@Getter @Getter
private final double factor; private final double factor;
public Composition(int sceneWidth, int sceneHeight, Paint background, Group group) { @Getter
private final double frameRate;
@Getter
private final TimeLine timeLine;
public Composition(int sceneWidth, int sceneHeight, double frameRate) {
this.sceneWidth = sceneWidth; this.sceneWidth = sceneWidth;
this.sceneHeight = sceneHeight; this.sceneHeight = sceneHeight;
this.frameRate = frameRate;
virtualHeight = 1080; virtualHeight = 1080;
factor = virtualHeight / (double) sceneHeight; factor = virtualHeight / (double) sceneHeight;
virtualWidth = (int) (sceneWidth * factor); virtualWidth = (int) (sceneWidth * factor);
timeLine = new TimeLine();
}
public VirtualScene newScene(KeyFrame keyFrame) {
val group = new Group();
group.setScaleX(1d / factor); group.setScaleX(1d / factor);
group.setScaleY(1d / factor); group.setScaleY(1d / factor);
group.setTranslateX(sceneWidth / 2); group.setTranslateX(sceneWidth / 2);
group.setTranslateY(sceneHeight / 2); group.setTranslateY(sceneHeight / 2);
this.group = group; val scene = new VirtualScene(group, virtualWidth, virtualHeight);
this.scene = new Scene(group, sceneWidth, sceneHeight, background); timeLine.add(keyFrame, scene);
return scene;
} }
public void add(Node node) { public Scene produceAnimationScene(VirtualScene scene) {
group.getChildren().add(node); return new Scene(scene.getGroup(), sceneWidth, sceneHeight, Color.WHITE);
} }
} }

View File

@ -0,0 +1,18 @@
package com.annimon.hotarufx.visual;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor(staticName="of")
@EqualsAndHashCode
public class KeyFrame implements Comparable<KeyFrame> {
@Getter
private final int frame;
@Override
public int compareTo(KeyFrame o) {
return Integer.compare(frame, o.frame);
}
}

View File

@ -0,0 +1,24 @@
package com.annimon.hotarufx.visual;
import com.annimon.hotarufx.exceptions.KeyFrameDuplicationException;
import java.util.Map;
import java.util.TreeMap;
import lombok.Getter;
import lombok.val;
public class TimeLine {
@Getter
private final Map<KeyFrame, VirtualScene> keyFrames;
public TimeLine() {
keyFrames = new TreeMap<>();
}
public void add(KeyFrame keyFrame, VirtualScene scene) {
val previous = keyFrames.put(keyFrame, scene);
if (previous != null) {
throw new KeyFrameDuplicationException(keyFrame);
}
}
}

View File

@ -0,0 +1,20 @@
package com.annimon.hotarufx.visual;
import javafx.scene.Group;
import javafx.scene.Node;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class VirtualScene {
@Getter
private final Group group;
@Getter
private final int virtualWidth, virtualHeight;
public void add(Node node) {
group.getChildren().add(node);
}
}

View File

@ -1,9 +1,8 @@
package com.annimon.hotarufx.visual.objects; package com.annimon.hotarufx.visual.objects;
import com.annimon.hotarufx.visual.Composition; import com.annimon.hotarufx.visual.VirtualScene;
import javafx.scene.shape.Circle; import javafx.scene.shape.Circle;
import lombok.Getter; import lombok.Getter;
import lombok.val;
public class CircleNode implements ObjectNode { public class CircleNode implements ObjectNode {
@ -15,7 +14,7 @@ public class CircleNode implements ObjectNode {
} }
@Override @Override
public void render(Composition composition) { public void render(VirtualScene scene) {
composition.add(circle); scene.add(circle);
} }
} }

View File

@ -1,8 +1,8 @@
package com.annimon.hotarufx.visual.objects; package com.annimon.hotarufx.visual.objects;
import com.annimon.hotarufx.visual.Composition; import com.annimon.hotarufx.visual.VirtualScene;
public interface ObjectNode { public interface ObjectNode {
void render(Composition composition); void render(VirtualScene scene);
} }

View File

@ -1,7 +1,5 @@
package com.annimon.hotarufx.visual; package com.annimon.hotarufx.visual;
import javafx.scene.Group;
import javafx.scene.paint.Color;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
@ -12,10 +10,10 @@ class CompositionTest {
@Test @Test
void testVirtualSize() { void testVirtualSize() {
Composition composition; Composition composition;
composition = new Composition(1280, 720, Color.WHITE, new Group()); composition = new Composition(1280, 720, 30);
assertThat(composition.getVirtualWidth(), is(1920)); assertThat(composition.getVirtualWidth(), is(1920));
composition = new Composition(1280, 1280, Color.WHITE, new Group()); composition = new Composition(1280, 1280, 30);
assertThat(composition.getVirtualWidth(), is(1080)); assertThat(composition.getVirtualWidth(), is(1080));
} }
} }

View File

@ -0,0 +1,24 @@
package com.annimon.hotarufx.visual;
import lombok.val;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.junit.jupiter.api.Assertions.*;
class TimeLineTest {
@Test
void add() {
val timeline = new TimeLine();
timeline.add(KeyFrame.of(20), null);
timeline.add(KeyFrame.of(10), null);
timeline.add(KeyFrame.of(0), null);
timeline.add(KeyFrame.of(1), null);
assertThat(timeline.getKeyFrames().keySet(), contains(
KeyFrame.of(0), KeyFrame.of(1),
KeyFrame.of(10), KeyFrame.of(20)
));
}
}