Fixed issue with looping animation pausing during transition, created new issue because of KeyFrame PathMethods (eases)

This commit is contained in:
Tinglyyy
2026-02-08 22:31:29 +01:00
parent a268926d0b
commit e61dbfa531
5 changed files with 134 additions and 35 deletions

View File

@@ -33,9 +33,32 @@ public class AnimationPath extends ArrayList<KeyFrame> {
public AnimationPath(int inbetweens) {
this.inbetweens = inbetweens;
}
/**
* Get next keyframe according to current path iterator, depending on the current frame without increasing the animation iterators
* @return next keyframe in order, depending on the current frame
*/
public KeyFrame peekNext() {
int tempSubIterator = this.subFrameIterator, tempAnimationIterator = this.animationIterator;
if(tempSubIterator >= this.inbetweens) {
tempSubIterator = 0;
tempAnimationIterator++;
}
if(tempAnimationIterator >= this.size())
return null;
tempSubIterator++;
KeyFrame current = this.get(tempAnimationIterator);
KeyFrame next = this.getNextInOrder();
return getKeyFrame(current, next, tempSubIterator);
}
/**
* Get next keyframe according to current path iterator, depending on the current frame
* Get next keyframe according to current path iterator, depending on the current frame, and increase the animation iterators
* @return next keyframe in order, depending on the current frame
*/
public KeyFrame getNext() {
@@ -53,11 +76,36 @@ public class AnimationPath extends ArrayList<KeyFrame> {
KeyFrame next = this.getNextInOrder();
return getKeyFrame(current, next, this.subFrameIterator);
}
private KeyFrame getKeyFrame(KeyFrame current, KeyFrame next, int subIterator) {
// How far the transition should be finished
double transition = (double) this.subFrameIterator / this.inbetweens;
double transition = this.linear(subIterator);
return inBetween(current, next, transition);
KeyFrame.PathMethod method;
// Translate EASE_IN_AND_OUT to its respective currently relevant counterpart
//TODO: non-linear keyframes can't behandled this way. This just makes it bug around
if(transition < 0.5)
method = current.pathMethod().equals(KeyFrame.PathMethod.EASE_IN_AND_OUT) ?
KeyFrame.PathMethod.EASE_OUT : current.pathMethod();
else
method = next.pathMethod().equals(KeyFrame.PathMethod.EASE_IN_AND_OUT) ?
KeyFrame.PathMethod.EASE_OUT : next.pathMethod();
// Else-case would be linear, which doesn't change anything
if(method.equals(KeyFrame.PathMethod.EASE_IN))
transition = this.easeIn(subIterator);
else if(method.equals(KeyFrame.PathMethod.EASE_OUT))
transition = this.easeOut(subIterator);
return inBetween(current, next, transition, method);
}
@@ -74,6 +122,13 @@ public class AnimationPath extends ArrayList<KeyFrame> {
return this.get(i);
}
/**
* @return true if there are any more frames coming
*/
public boolean anyMore() {
return this.animationIterator + 1 < this.size();
}
/**
* Reset animation path iterator to start
*/
@@ -123,7 +178,7 @@ public class AnimationPath extends ArrayList<KeyFrame> {
* @param scalar factor (ideally between 0 and 1, representing 0% transition to 100% transition)
* @return in-between frame
*/
private static KeyFrame inBetween(KeyFrame kf1, KeyFrame kf2, double scalar) {
private static KeyFrame inBetween(KeyFrame kf1, KeyFrame kf2, double scalar, KeyFrame.PathMethod method) {
// position
Point difference = subtract(kf2.position(), kf1.position());
@@ -141,6 +196,23 @@ public class AnimationPath extends ArrayList<KeyFrame> {
height = Math.toIntExact(Math.round(kf1.height() + dH * scalar));
return new KeyFrame(pos, width, height);
return new KeyFrame(pos, width, height, method);
}
@Override
public AnimationPath clone() {
return new AnimationPath(this.inbetweens, new ArrayList<>(this));
}
private double linear(int subIterator) {
return (double) subIterator/2 / this.inbetweens;
}
private double easeIn(int subIterator) {
return this.linear(subIterator/2) * this.linear(subIterator/2);
}
public double easeOut(int subIterator) {
return Math.sqrt(this.linear(subIterator*2));
}
}