Skip to content

Commit

Permalink
Easing
Browse files Browse the repository at this point in the history
  • Loading branch information
tanishisherewithhh committed Feb 9, 2025
1 parent ab60509 commit 59d1de4
Show file tree
Hide file tree
Showing 8 changed files with 369 additions and 17 deletions.
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; }
}
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);
}
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;
}
}
}
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;
}
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();
}
}
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ public void render(DrawContext drawContext, int mouseX, int mouseY, float delta)

if (GlobalConfig.get().shouldDisplayDescriptions()) {
for (Widget widget : widgetRenderer.getWidgets()) {
if (widget == null || widget.shiftDown) continue;
if (widget == null || widget.isShiftDown) continue;

if (widget.getWidgetBox().isMouseOver(mouseX, mouseY)) {
drawContext.drawTooltip(client.textRenderer, Text.of(widget.DATA.description()), mouseX, mouseY);
drawContext.drawTooltip(client.textRenderer, widget.tooltipText, mouseX, mouseY);
break;
}
}
Expand Down
Loading

0 comments on commit 59d1de4

Please sign in to comment.