From aec580e60ca6c68e028a0c2302b8b566889f4ba9 Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 8 Sep 2017 16:36:51 +0300 Subject: [PATCH] Add interpolators --- .../hotarufx/bundles/BundleLoader.java | 3 +- .../hotarufx/bundles/InterpolatorsBundle.java | 31 +++++++++++++ .../hotarufx/lib/InterpolatorValue.java | 45 +++++++++++++++++++ .../annimon/hotarufx/lib/PropertyValue.java | 30 ++++++++++--- .../java/com/annimon/hotarufx/lib/Types.java | 3 +- .../hotarufx/visual/KeyFrameValue.java | 17 +++++++ .../hotarufx/visual/PropertyTimeline.java | 10 ++++- .../visual/PropertyTimelineHolder.java | 5 ++- 8 files changed, 131 insertions(+), 13 deletions(-) create mode 100644 app/src/main/java/com/annimon/hotarufx/bundles/InterpolatorsBundle.java create mode 100644 app/src/main/java/com/annimon/hotarufx/lib/InterpolatorValue.java create mode 100644 app/src/main/java/com/annimon/hotarufx/visual/KeyFrameValue.java diff --git a/app/src/main/java/com/annimon/hotarufx/bundles/BundleLoader.java b/app/src/main/java/com/annimon/hotarufx/bundles/BundleLoader.java index 7508ec5..e926256 100644 --- a/app/src/main/java/com/annimon/hotarufx/bundles/BundleLoader.java +++ b/app/src/main/java/com/annimon/hotarufx/bundles/BundleLoader.java @@ -15,7 +15,8 @@ public final class BundleLoader { return Arrays.asList( CompositionBundle.class, NodesBundle.class, - NodeUtilsBundle.class + NodeUtilsBundle.class, + InterpolatorsBundle.class ); } diff --git a/app/src/main/java/com/annimon/hotarufx/bundles/InterpolatorsBundle.java b/app/src/main/java/com/annimon/hotarufx/bundles/InterpolatorsBundle.java new file mode 100644 index 0000000..ac4d28e --- /dev/null +++ b/app/src/main/java/com/annimon/hotarufx/bundles/InterpolatorsBundle.java @@ -0,0 +1,31 @@ +package com.annimon.hotarufx.bundles; + +import com.annimon.hotarufx.lib.Context; +import com.annimon.hotarufx.lib.InterpolatorValue; +import java.util.HashMap; +import java.util.Map; +import javafx.animation.Interpolator; + +public class InterpolatorsBundle implements Bundle { + + private static final Map FUNCTIONS; + static { + FUNCTIONS = new HashMap<>(); + } + + @Override + public Map functionsInfo() { + return FUNCTIONS; + } + + @Override + public void load(Context context) { + Bundle.super.load(context); + context.variables().put("linear", new InterpolatorValue(Interpolator.LINEAR)); + context.variables().put("discrete", new InterpolatorValue(Interpolator.DISCRETE)); + context.variables().put("easeIn", new InterpolatorValue(Interpolator.EASE_IN)); + context.variables().put("easeOut", new InterpolatorValue(Interpolator.EASE_OUT)); + context.variables().put("ease", new InterpolatorValue(Interpolator.EASE_BOTH)); + context.variables().put("easeBoth", new InterpolatorValue(Interpolator.EASE_BOTH)); + } +} diff --git a/app/src/main/java/com/annimon/hotarufx/lib/InterpolatorValue.java b/app/src/main/java/com/annimon/hotarufx/lib/InterpolatorValue.java new file mode 100644 index 0000000..4f121d7 --- /dev/null +++ b/app/src/main/java/com/annimon/hotarufx/lib/InterpolatorValue.java @@ -0,0 +1,45 @@ +package com.annimon.hotarufx.lib; + +import com.annimon.hotarufx.exceptions.TypeException; +import javafx.animation.Interpolator; +import lombok.Getter; + +public class InterpolatorValue implements Value { + + @Getter + private final Interpolator interpolator; + + public InterpolatorValue(Interpolator interpolator) { + this.interpolator = interpolator; + } + + @Override + public int type() { + return Types.INTERPOLATOR; + } + + @Override + public Object raw() { + return interpolator; + } + + @Override + public int asInt() { + throw new TypeException("Cannot cast interpolator to integer"); + } + + @Override + public double asNumber() { + throw new TypeException("Cannot cast interpolator to number"); + } + + @Override + public String asString() { + throw new TypeException("Cannot cast interpolator to string"); + } + + @Override + public int compareTo(Value o) { + return 0; + } +} diff --git a/app/src/main/java/com/annimon/hotarufx/lib/PropertyValue.java b/app/src/main/java/com/annimon/hotarufx/lib/PropertyValue.java index 8385645..6d90aa1 100644 --- a/app/src/main/java/com/annimon/hotarufx/lib/PropertyValue.java +++ b/app/src/main/java/com/annimon/hotarufx/lib/PropertyValue.java @@ -7,6 +7,7 @@ import com.annimon.hotarufx.visual.Property; import com.annimon.hotarufx.visual.PropertyTimeline; import java.util.HashMap; import java.util.Map; +import javafx.animation.Interpolator; import javafx.scene.Node; import javafx.scene.paint.Paint; import javafx.scene.text.Font; @@ -41,44 +42,59 @@ public class PropertyValue implements Value { @SuppressWarnings("unchecked") private Function add() { return args -> { - Validator.with(args).checkAtLeast(2); + Validator.with(args).checkOrOr(2, 3); + final Interpolator interpolator; + if (args.length == 2) { + interpolator = Interpolator.LINEAR; + } else { + if (args[2].type() != Types.INTERPOLATOR) { + throw new TypeException("Interpolator required at third argument"); + } + interpolator = ((InterpolatorValue) args[2]).getInterpolator(); + } val type = property.getType(); switch (type) { case BOOLEAN: ((PropertyTimeline)property.getProperty().get()).add( KeyFrame.of(args[0].asInt()), - type.getFromHFX().apply(args[1]) + type.getFromHFX().apply(args[1]), + interpolator ); break; case NUMBER: ((PropertyTimeline)property.getProperty().get()).add( KeyFrame.of(args[0].asInt()), - type.getFromHFX().apply(args[1]) + type.getFromHFX().apply(args[1]), + interpolator ); break; case STRING: ((PropertyTimeline)property.getProperty().get()).add( KeyFrame.of(args[0].asInt()), - type.getFromHFX().apply(args[1]) + type.getFromHFX().apply(args[1]), + interpolator ); break; case NODE: case CLIP_NODE: ((PropertyTimeline)property.getProperty().get()).add( KeyFrame.of(args[0].asInt()), - type.getFromHFX().apply(args[1]) + type.getFromHFX().apply(args[1]), + interpolator ); break; case PAINT: ((PropertyTimeline)property.getProperty().get()).add( KeyFrame.of(args[0].asInt()), - type.getFromHFX().apply(args[1]) + type.getFromHFX().apply(args[1]), + interpolator ); break; case FONT: ((PropertyTimeline)property.getProperty().get()).add( KeyFrame.of(args[0].asInt()), - type.getFromHFX().apply(args[1]) + type.getFromHFX().apply(args[1]), + interpolator ); break; } diff --git a/app/src/main/java/com/annimon/hotarufx/lib/Types.java b/app/src/main/java/com/annimon/hotarufx/lib/Types.java index 6e360e1..8572f38 100644 --- a/app/src/main/java/com/annimon/hotarufx/lib/Types.java +++ b/app/src/main/java/com/annimon/hotarufx/lib/Types.java @@ -10,5 +10,6 @@ public class Types { MAP = 4, NODE = 5, PROPERTY = 6, - FUNCTION = 7; + INTERPOLATOR = 7, + FUNCTION = 8; } diff --git a/app/src/main/java/com/annimon/hotarufx/visual/KeyFrameValue.java b/app/src/main/java/com/annimon/hotarufx/visual/KeyFrameValue.java new file mode 100644 index 0000000..531f9bf --- /dev/null +++ b/app/src/main/java/com/annimon/hotarufx/visual/KeyFrameValue.java @@ -0,0 +1,17 @@ +package com.annimon.hotarufx.visual; + +import javafx.animation.Interpolator; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public class KeyFrameValue { + + private final T value; + private final Interpolator interpolator; + + public KeyFrameValue(T value) { + this(value, Interpolator.LINEAR); + } +} diff --git a/app/src/main/java/com/annimon/hotarufx/visual/PropertyTimeline.java b/app/src/main/java/com/annimon/hotarufx/visual/PropertyTimeline.java index bc45d18..d1724c2 100644 --- a/app/src/main/java/com/annimon/hotarufx/visual/PropertyTimeline.java +++ b/app/src/main/java/com/annimon/hotarufx/visual/PropertyTimeline.java @@ -2,6 +2,7 @@ package com.annimon.hotarufx.visual; import java.util.Map; import java.util.TreeMap; +import javafx.animation.Interpolator; import javafx.beans.value.WritableValue; import lombok.Getter; @@ -9,7 +10,7 @@ import lombok.Getter; public class PropertyTimeline { private final WritableValue property; - private final Map keyFrames; + private final Map> keyFrames; public PropertyTimeline(WritableValue property) { this.property = property; @@ -17,7 +18,12 @@ public class PropertyTimeline { } public PropertyTimeline add(KeyFrame keyFrame, T value) { - keyFrames.put(keyFrame, value); + keyFrames.put(keyFrame, new KeyFrameValue<>(value)); + return this; + } + + public PropertyTimeline add(KeyFrame keyFrame, T value, Interpolator interpolator) { + keyFrames.put(keyFrame, new KeyFrameValue<>(value, interpolator)); return this; } } diff --git a/app/src/main/java/com/annimon/hotarufx/visual/PropertyTimelineHolder.java b/app/src/main/java/com/annimon/hotarufx/visual/PropertyTimelineHolder.java index f17d532..ec6129a 100644 --- a/app/src/main/java/com/annimon/hotarufx/visual/PropertyTimelineHolder.java +++ b/app/src/main/java/com/annimon/hotarufx/visual/PropertyTimelineHolder.java @@ -33,8 +33,9 @@ public final class PropertyTimelineHolder { public void applyIfPresent(TimeLine timeline) { if (isEmpty()) return; - propertyTimeline.getKeyFrames().forEach((keyFrame, value) -> { - timeline.addKeyFrame(keyFrame, new KeyValue(propertyTimeline.getProperty(), value)); + propertyTimeline.getKeyFrames().forEach((keyFrame, p) -> { + timeline.addKeyFrame(keyFrame, new KeyValue( + propertyTimeline.getProperty(), p.getValue(), p.getInterpolator())); }); }