-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ab60509
commit 59d1de4
Showing
8 changed files
with
369 additions
and
17 deletions.
There are no files selected for viewing
63 changes: 63 additions & 0 deletions
63
src/main/java/com/tanishisherewith/dynamichud/helpers/animationhelper/Animation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package com.tanishisherewith.dynamichud.helpers.animationhelper; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public abstract class Animation { | ||
public long startTime; | ||
public long duration; | ||
protected boolean running = false; | ||
protected boolean finished = false; | ||
protected EasingType easing = EasingType.LINEAR; | ||
protected final List<Runnable> completionCallbacks = new ArrayList<>(); | ||
|
||
public void start() { | ||
startTime = System.currentTimeMillis(); | ||
running = true; | ||
finished = false; | ||
} | ||
|
||
public void stop() { | ||
running = false; | ||
finished = true; | ||
} | ||
|
||
public void update() { | ||
if (!running || finished) return; | ||
|
||
long elapsed = System.currentTimeMillis() - startTime; | ||
float progress = Math.min(elapsed / (float) duration, 1.0f); | ||
float easedProgress = Easing.apply(easing, progress); | ||
|
||
applyAnimation(easedProgress); | ||
|
||
if (progress >= 1.0f) { | ||
finish(); | ||
} | ||
} | ||
|
||
protected abstract void applyAnimation(float progress); | ||
|
||
public Animation duration(long durationMs) { | ||
this.duration = durationMs; | ||
return this; | ||
} | ||
|
||
public Animation easing(EasingType easing) { | ||
this.easing = easing; | ||
return this; | ||
} | ||
|
||
public Animation onComplete(Runnable callback) { | ||
completionCallbacks.add(callback); | ||
return this; | ||
} | ||
|
||
public void finish() { | ||
finished = true; | ||
running = false; | ||
completionCallbacks.forEach(Runnable::run); | ||
} | ||
|
||
public boolean isFinished() { return finished; } | ||
} |
7 changes: 7 additions & 0 deletions
7
src/main/java/com/tanishisherewith/dynamichud/helpers/animationhelper/AnimationProperty.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package com.tanishisherewith.dynamichud.helpers.animationhelper; | ||
|
||
// AnimationProperty.java | ||
public interface AnimationProperty<T> { | ||
T get(); | ||
void set(T value); | ||
} |
83 changes: 83 additions & 0 deletions
83
src/main/java/com/tanishisherewith/dynamichud/helpers/animationhelper/Easing.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package com.tanishisherewith.dynamichud.helpers.animationhelper; | ||
|
||
public class Easing { | ||
public static float apply(EasingType easingType, float progress) { | ||
return switch (easingType) { | ||
case LINEAR -> progress; | ||
case EASE_IN_SINE -> (float) (1 - Math.cos((progress * Math.PI) / 2)); | ||
case EASE_OUT_SINE -> (float) Math.sin((progress * Math.PI) / 2); | ||
case EASE_IN_OUT_SINE -> (float) (-(Math.cos(Math.PI * progress) - 1) / 2); | ||
case EASE_IN_QUAD -> progress * progress; | ||
case EASE_OUT_QUAD -> 1 - (1 - progress) * (1 - progress); | ||
case EASE_IN_OUT_QUAD -> progress < 0.5 ? 2 * progress * progress : (float) (1 - Math.pow(-2 * progress + 2, 2) / 2); | ||
case EASE_IN_CUBIC -> progress * progress * progress; | ||
case EASE_OUT_CUBIC -> (float) (1 - Math.pow(1 - progress, 3)); | ||
case EASE_IN_OUT_CUBIC -> progress < 0.5 ? 4 * progress * progress * progress : (float) (1 - Math.pow(-2 * progress + 2, 3) / 2); | ||
case EASE_IN_QUART -> progress * progress * progress * progress; | ||
case EASE_OUT_QUART -> (float) (1 - Math.pow(1 - progress, 4)); | ||
case EASE_IN_OUT_QUART -> progress < 0.5 ? 8 * progress * progress * progress * progress : (float) (1 - Math.pow(-2 * progress + 2, 4) / 2); | ||
case EASE_IN_QUINT -> progress * progress * progress * progress * progress; | ||
case EASE_OUT_QUINT -> (float) (1 - Math.pow(1 - progress, 5)); | ||
case EASE_IN_OUT_QUINT -> progress < 0.5 ? 16 * progress * progress * progress * progress * progress : (float) (1 - Math.pow(-2 * progress + 2, 5) / 2); | ||
case EASE_IN_EXPO -> (float) (progress == 0 ? 0 : Math.pow(2, 10 * progress - 10)); | ||
case EASE_OUT_EXPO -> (float) (progress == 1 ? 1 : 1 - Math.pow(2, -10 * progress)); | ||
case EASE_IN_OUT_EXPO -> { | ||
if (progress == 0 || progress == 1) yield progress; | ||
yield (float) (progress < 0.5 | ||
? Math.pow(2, 20 * progress - 10) / 2 | ||
: (2 - Math.pow(2, -20 * progress + 10)) / 2); | ||
} | ||
case EASE_IN_CIRC -> (float) (1 - Math.sqrt(1 - Math.pow(progress, 2))); | ||
case EASE_OUT_CIRC -> (float) Math.sqrt(1 - Math.pow(progress - 1, 2)); | ||
case EASE_IN_OUT_CIRC -> progress < 0.5 | ||
? (float) ((1 - Math.sqrt(1 - Math.pow(2 * progress, 2))) / 2) | ||
: (float) ((Math.sqrt(1 - Math.pow(-2 * progress + 2, 2)) + 1) / 2); | ||
case EASE_IN_BACK -> (float) (2.70158 * progress * progress * progress - 1.70158 * progress * progress); | ||
case EASE_OUT_BACK -> { | ||
float c1 = 1.70158f; | ||
float c3 = c1 + 1; | ||
yield (float) (1 + c3 * Math.pow(progress - 1, 3) + c1 * Math.pow(progress - 1, 2)); | ||
} | ||
case EASE_IN_OUT_BACK -> { | ||
float c1 = 1.70158f; | ||
float c2 = c1 * 1.525f; | ||
yield (float) (progress < 0.5 | ||
? (Math.pow(2 * progress, 2) * ((c2 + 1) * 2 * progress - c2)) / 2 | ||
: (Math.pow(2 * progress - 2, 2) * ((c2 + 1) * (progress * 2 - 2) + c2) + 2) / 2); | ||
} | ||
case EASE_IN_ELASTIC -> { | ||
float c4 = (float) (2 * Math.PI / 3); | ||
yield progress == 0 ? 0 : progress == 1 ? 1 : (float) (-Math.pow(2, 10 * progress - 10) * Math.sin((progress * 10 - 10.75) * c4)); | ||
} | ||
case EASE_OUT_ELASTIC -> { | ||
float c4 = (float) (2 * Math.PI / 3); | ||
yield progress == 0 ? 0 : progress == 1 ? 1 : (float) (Math.pow(2, -10 * progress) * Math.sin((progress * 10 - 0.75) * c4) + 1); | ||
} | ||
case EASE_IN_OUT_ELASTIC -> { | ||
float c5 = (float) (2 * Math.PI / 4.5); | ||
yield progress == 0 ? 0 : progress == 1 ? 1 : progress < 0.5 | ||
? (float) (-(Math.pow(2, 20 * progress - 10) * Math.sin((20 * progress - 11.125) * c5)) / 2) | ||
: (float) (Math.pow(2, -20 * progress + 10) * Math.sin((20 * progress - 11.125) * c5) / 2 + 1); | ||
} | ||
case EASE_IN_BOUNCE -> 1 - bounceOut(1 - progress); | ||
case EASE_OUT_BOUNCE -> bounceOut(progress); | ||
case EASE_IN_OUT_BOUNCE -> progress < 0.5 | ||
? (1 - bounceOut(1 - 2 * progress)) / 2 | ||
: (1 + bounceOut(2 * progress - 1)) / 2; | ||
}; | ||
} | ||
|
||
private static float bounceOut(float progress) { | ||
float n1 = 7.5625f; | ||
float d1 = 2.75f; | ||
if (progress < 1 / d1) { | ||
return n1 * progress * progress; | ||
} else if (progress < 2 / d1) { | ||
return n1 * (progress -= 1.5f / d1) * progress + 0.75f; | ||
} else if (progress < 2.5 / d1) { | ||
return n1 * (progress -= 2.25f / d1) * progress + 0.9375f; | ||
} else { | ||
return n1 * (progress -= 2.625f / d1) * progress + 0.984375f; | ||
} | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
src/main/java/com/tanishisherewith/dynamichud/helpers/animationhelper/EasingType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package com.tanishisherewith.dynamichud.helpers.animationhelper; | ||
|
||
public enum EasingType { | ||
LINEAR, | ||
EASE_IN_SINE, | ||
EASE_OUT_SINE, | ||
EASE_IN_OUT_SINE, | ||
EASE_IN_QUAD, | ||
EASE_OUT_QUAD, | ||
EASE_IN_OUT_QUAD, | ||
EASE_IN_CUBIC, | ||
EASE_OUT_CUBIC, | ||
EASE_IN_OUT_CUBIC, | ||
EASE_IN_QUART, | ||
EASE_OUT_QUART, | ||
EASE_IN_OUT_QUART, | ||
EASE_IN_QUINT, | ||
EASE_OUT_QUINT, | ||
EASE_IN_OUT_QUINT, | ||
EASE_IN_EXPO, | ||
EASE_OUT_EXPO, | ||
EASE_IN_OUT_EXPO, | ||
EASE_IN_CIRC, | ||
EASE_OUT_CIRC, | ||
EASE_IN_OUT_CIRC, | ||
EASE_IN_BACK, | ||
EASE_OUT_BACK, | ||
EASE_IN_OUT_BACK, | ||
EASE_IN_ELASTIC, | ||
EASE_OUT_ELASTIC, | ||
EASE_IN_OUT_ELASTIC, | ||
EASE_IN_BOUNCE, | ||
EASE_OUT_BOUNCE, | ||
EASE_IN_OUT_BOUNCE; | ||
} |
100 changes: 100 additions & 0 deletions
100
...om/tanishisherewith/dynamichud/helpers/animationhelper/animations/CompositeAnimation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package com.tanishisherewith.dynamichud.helpers.animationhelper.animations; | ||
|
||
import com.tanishisherewith.dynamichud.helpers.animationhelper.Animation; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class CompositeAnimation extends Animation { | ||
private final List<Animation> children = new ArrayList<>(); | ||
private final boolean parallel; | ||
private int currentChildIndex = 0; | ||
private long[] childStartTimes; | ||
|
||
public CompositeAnimation(boolean parallel) { | ||
this.parallel = parallel; | ||
} | ||
|
||
public CompositeAnimation add(Animation animation) { | ||
children.add(animation); | ||
return this; | ||
} | ||
|
||
@Override | ||
public void start() { | ||
super.start(); | ||
if (parallel) { | ||
children.forEach(Animation::start); | ||
} else { | ||
// Calculate total duration as sum of children's durations | ||
this.duration = children.stream().mapToLong(a -> a.duration).sum(); | ||
childStartTimes = new long[children.size()]; | ||
long accumulated = 0; | ||
for (int i = 0; i < children.size(); i++) { | ||
childStartTimes[i] = accumulated; | ||
accumulated += children.get(i).duration; | ||
} | ||
startChild(0); | ||
} | ||
} | ||
|
||
private void startChild(int index) { | ||
if (index < children.size()) { | ||
Animation child = children.get(index); | ||
child.start(); | ||
// Adjust child's start time to match group timeline | ||
child.startTime = this.startTime + childStartTimes[index]; | ||
} | ||
} | ||
|
||
@Override | ||
protected void applyAnimation(float progress) { | ||
if (parallel) { | ||
children.forEach(Animation::update); | ||
} else { | ||
long elapsed = System.currentTimeMillis() - startTime; | ||
|
||
// Find active child | ||
for (int i = 0; i < children.size(); i++) { | ||
long childDuration = children.get(i).duration; | ||
if (elapsed < childStartTimes[i] + childDuration) { | ||
if (currentChildIndex != i) { | ||
currentChildIndex = i; | ||
startChild(i); | ||
} | ||
children.get(i).update(); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public void stop() { | ||
super.stop(); | ||
children.forEach(Animation::stop); | ||
} | ||
|
||
@Override | ||
public boolean isFinished() { | ||
if (parallel) { | ||
return children.stream().allMatch(Animation::isFinished); | ||
} else { | ||
long elapsed = System.currentTimeMillis() - startTime; | ||
return elapsed >= duration; | ||
} | ||
} | ||
|
||
@Override | ||
public void finish() { | ||
// Ensure all children finish properly | ||
if (!parallel) { | ||
children.forEach(child -> { | ||
if (!child.isFinished()) { | ||
child.finish(); | ||
} | ||
}); | ||
} | ||
super.finish(); | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
...va/com/tanishisherewith/dynamichud/helpers/animationhelper/animations/ValueAnimation.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package com.tanishisherewith.dynamichud.helpers.animationhelper.animations; | ||
|
||
import com.tanishisherewith.dynamichud.helpers.animationhelper.Animation; | ||
import com.tanishisherewith.dynamichud.helpers.animationhelper.AnimationProperty; | ||
import com.tanishisherewith.dynamichud.helpers.animationhelper.Easing; | ||
import com.tanishisherewith.dynamichud.helpers.animationhelper.EasingType; | ||
|
||
public class ValueAnimation extends Animation { | ||
private final AnimationProperty<Float> property; | ||
private float startValue; | ||
private float endValue; | ||
private EasingType easing; | ||
private float value; | ||
|
||
public ValueAnimation(AnimationProperty<Float> property, float start, float end, EasingType easingType) { | ||
this.property = property; | ||
this.startValue = start; | ||
this.endValue = end; | ||
this.easing = easingType; | ||
} | ||
public ValueAnimation(AnimationProperty<Float> property, float start, float end) { | ||
this(property,start,end,EasingType.LINEAR); | ||
} | ||
|
||
@Override | ||
protected void applyAnimation(float progress) { | ||
value = startValue + (endValue - startValue) * Easing.apply(easing,progress); | ||
property.set(value); | ||
} | ||
|
||
public ValueAnimation setEasing(EasingType easing) { | ||
this.easing = easing; | ||
return this; | ||
} | ||
|
||
public ValueAnimation setStartValue(float startValue) { | ||
this.startValue = startValue; | ||
return this; | ||
} | ||
|
||
public ValueAnimation setEndValue(float endValue) { | ||
this.endValue = endValue; | ||
return this; | ||
} | ||
|
||
public float getValue() { | ||
return value; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.