Fixed animations! Updated version-naming scheme (this project doesn't depend on the protocol version)
This commit is contained in:
@@ -80,10 +80,6 @@ public class AnimationPath extends ArrayList<KeyFrame> {
|
||||
}
|
||||
|
||||
private KeyFrame getKeyFrame(KeyFrame current, KeyFrame next, int subIterator) {
|
||||
// How far the transition should be finished
|
||||
|
||||
double transition = this.linear(subIterator);
|
||||
|
||||
CombinedPathMethod method;
|
||||
|
||||
KeyFrame.PathMethod
|
||||
@@ -95,26 +91,16 @@ public class AnimationPath extends ArrayList<KeyFrame> {
|
||||
if(currentMethod.equals(KeyFrame.PathMethod.EASE_OUT) || currentMethod.equals(KeyFrame.PathMethod.EASE_IN_AND_OUT))
|
||||
currentMethod = KeyFrame.PathMethod.EASE_OUT;
|
||||
|
||||
if(nextMethod.equals(KeyFrame.PathMethod.EASE_OUT) || nextMethod.equals(KeyFrame.PathMethod.EASE_IN_AND_OUT))
|
||||
nextMethod = KeyFrame.PathMethod.EASE_OUT;
|
||||
if(nextMethod.equals(KeyFrame.PathMethod.EASE_IN) || nextMethod.equals(KeyFrame.PathMethod.EASE_IN_AND_OUT))
|
||||
nextMethod = KeyFrame.PathMethod.EASE_IN;
|
||||
|
||||
method = switch (currentMethod) {
|
||||
case LINEAR -> switch (nextMethod) {
|
||||
case LINEAR -> CombinedPathMethod.LINEAR;
|
||||
case EASE_IN -> CombinedPathMethod.LINEAR_EASE_IN;
|
||||
// Removed this case, as ease-out doesn't make sense right before a keyframe
|
||||
// case EASE_OUT -> CombinedPathMethod.LINEAR_EASE_OUT;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + nextMethod);
|
||||
};
|
||||
|
||||
// Removed this case, as ease-in doesn't make sense right after a keyframe
|
||||
// case EASE_IN -> switch (nextMethod) {
|
||||
// case LINEAR -> CombinedPathMethod.EASE_IN_LINEAR;
|
||||
// case EASE_IN -> CombinedPathMethod.EASE_IN;
|
||||
// case EASE_OUT -> CombinedPathMethod.EASE_OUT_LINEAR;
|
||||
// default -> throw new IllegalStateException("Unexpected value: " + nextMethod);
|
||||
// };
|
||||
|
||||
case EASE_OUT -> switch (nextMethod) {
|
||||
case LINEAR -> CombinedPathMethod.EASE_OUT_LINEAR;
|
||||
case EASE_IN -> CombinedPathMethod.EASE_OUT_AND_IN;
|
||||
@@ -124,36 +110,7 @@ public class AnimationPath extends ArrayList<KeyFrame> {
|
||||
default -> throw new IllegalStateException("Unexpected value: " + currentMethod);
|
||||
};
|
||||
|
||||
double threshold = Math.min(current.transition(), next.transition());
|
||||
|
||||
boolean thresholdReached;
|
||||
|
||||
if(current.transition() < next.transition())
|
||||
thresholdReached = transition > threshold;
|
||||
else
|
||||
thresholdReached = transition <= next.transition();
|
||||
|
||||
if(thresholdReached)
|
||||
transition = 2 * transition - 1;
|
||||
|
||||
transition = switch (method) {
|
||||
case LINEAR -> transition;
|
||||
|
||||
case LINEAR_EASE_IN -> thresholdReached ? easeIn(subIterator) : transition;
|
||||
|
||||
// case EASE_IN -> easeIn(subIterator);
|
||||
|
||||
case EASE_OUT -> easeOut(subIterator);
|
||||
|
||||
case EASE_OUT_LINEAR -> thresholdReached ? transition : easeOut(subIterator);
|
||||
|
||||
case EASE_OUT_AND_IN -> thresholdReached ? easeOut(subIterator) : easeIn(subIterator);
|
||||
|
||||
};
|
||||
|
||||
System.out.println(method + " " + transition + " - linear: " + linear(subIterator));
|
||||
|
||||
return inBetween(current, next, transition, thresholdReached);
|
||||
return this.inBetween(current, next, method, subIterator);
|
||||
|
||||
}
|
||||
|
||||
@@ -233,6 +190,7 @@ public class AnimationPath extends ArrayList<KeyFrame> {
|
||||
return new Point(point.x - subtrahend.x, point.y - subtrahend.y);
|
||||
}
|
||||
|
||||
// Unused right now
|
||||
/**
|
||||
* Calculate point between both points
|
||||
* @param p1 first point
|
||||
@@ -248,28 +206,72 @@ public class AnimationPath extends ArrayList<KeyFrame> {
|
||||
);
|
||||
}
|
||||
|
||||
private static Point onLine(Point p1, Point p2, double scalar) {
|
||||
return add(
|
||||
p1,
|
||||
multiply(
|
||||
subtract(p2, p1),
|
||||
scalar
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find in-between with given scalar
|
||||
* @param kf1 first frame
|
||||
* @param kf2 next frame
|
||||
* @param scalar factor (ideally between 0 and 1, representing 0% transition to 100% transition)
|
||||
* @param overHalf if this inbetween is over halfway through the transition process
|
||||
* @param subIterator how far the animation path has proceeded
|
||||
* @return in-between frame
|
||||
*/
|
||||
private static KeyFrame inBetween(KeyFrame kf1, KeyFrame kf2, double scalar, boolean overHalf) {
|
||||
// create halfway marked point
|
||||
if(overHalf)
|
||||
kf1.position().setLocation(
|
||||
middle(kf1.position(), kf2.position())
|
||||
private KeyFrame inBetween(KeyFrame kf1, KeyFrame kf2, CombinedPathMethod method, int subIterator) {
|
||||
double scalar = this.linear(subIterator);
|
||||
|
||||
double remainder = kf1.transition() - kf2.transition();
|
||||
|
||||
double transition = 0.01;
|
||||
|
||||
if(remainder > 0) {
|
||||
if(kf1.transition() > kf2.transition())
|
||||
transition = kf1.transition() + remainder / 2;
|
||||
else
|
||||
transition = 1 - kf2.transition() - remainder / 2;
|
||||
}
|
||||
|
||||
double threshold = Math.min(kf1.transition(), 1 - kf2.transition());
|
||||
|
||||
boolean thresholdReached = scalar > threshold;
|
||||
|
||||
// Create point on the line between both keyframes
|
||||
if(thresholdReached) {
|
||||
|
||||
kf1 = new KeyFrame(
|
||||
onLine(kf1.position(), kf2.position(), threshold),
|
||||
|
||||
(int) (kf1.width() + (kf2.width() - kf1.width()) * threshold),
|
||||
(int) (kf1.height() + (kf2.height() - kf1.height()) * threshold)
|
||||
);
|
||||
|
||||
// position
|
||||
}
|
||||
|
||||
scalar = switch (method) {
|
||||
case LINEAR -> scalar;
|
||||
|
||||
case LINEAR_EASE_IN -> thresholdReached ? this.easeIn(subIterator) * (1 - transition) : scalar;
|
||||
|
||||
case EASE_OUT -> easeOut(subIterator);
|
||||
|
||||
case EASE_OUT_LINEAR -> thresholdReached ? 2 * (scalar - 0.5) : this.easeOut(subIterator);
|
||||
|
||||
case EASE_OUT_AND_IN -> thresholdReached ? this.easeOut(subIterator) : this.easeIn(subIterator) * (1 - transition);
|
||||
|
||||
};
|
||||
|
||||
// Position
|
||||
Point difference = subtract(kf2.position(), kf1.position());
|
||||
|
||||
Point pos = add(kf1.position(), multiply(difference, scalar));
|
||||
|
||||
// scale
|
||||
// Scale
|
||||
|
||||
int width, height;
|
||||
|
||||
@@ -288,25 +290,27 @@ public class AnimationPath extends ArrayList<KeyFrame> {
|
||||
return new AnimationPath(this.inbetweens, new ArrayList<>(this));
|
||||
}
|
||||
|
||||
private double linear(int subIterator) {
|
||||
return (double) subIterator/2 / this.inbetweens;
|
||||
private double linear(double subIterator) {
|
||||
return subIterator / this.inbetweens;
|
||||
}
|
||||
|
||||
private double easeIn(int subIterator) {
|
||||
return this.linear(subIterator*2) * this.linear(subIterator*2);
|
||||
private double easeIn(double subIterator) {
|
||||
return this.linear(subIterator - 1) * this.linear(subIterator - 1) + 1;
|
||||
}
|
||||
|
||||
public double easeOut(int subIterator) {
|
||||
return Math.sqrt(this.linear(subIterator*2));
|
||||
private double easeOut(double subIterator) {
|
||||
return 2 * this.linear(subIterator) * this.linear(subIterator);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Enumerator purely to describe two combined PathMethods, like a 2-dimensional PathMethod enum
|
||||
*/
|
||||
private enum CombinedPathMethod {
|
||||
LINEAR,
|
||||
LINEAR_EASE_IN,
|
||||
// EASE_IN,
|
||||
EASE_OUT,
|
||||
EASE_OUT_LINEAR,
|
||||
EASE_OUT_AND_IN;
|
||||
|
||||
Reference in New Issue
Block a user