diff --git a/src/main/java/org/saturnclient/ui2/Element.java b/src/main/java/org/saturnclient/ui2/Element.java index 7423320..1d520bd 100644 --- a/src/main/java/org/saturnclient/ui2/Element.java +++ b/src/main/java/org/saturnclient/ui2/Element.java @@ -1,11 +1,14 @@ package org.saturnclient.ui2; +import org.saturnclient.ui2.anim.Animation; + public class Element { public int x; public int y; public int width; public int height; public boolean focused; + public Animation animation; public void render(RenderScope renderScope, RenderContext ctx) { } @@ -40,4 +43,10 @@ public class Element { return this; } + + public final Element animation(Animation animation) { + this.animation = animation; + + return this; + } } diff --git a/src/main/java/org/saturnclient/ui2/SaturnScreen.java b/src/main/java/org/saturnclient/ui2/SaturnScreen.java index 1b3803c..c00c221 100644 --- a/src/main/java/org/saturnclient/ui2/SaturnScreen.java +++ b/src/main/java/org/saturnclient/ui2/SaturnScreen.java @@ -1,16 +1,12 @@ package org.saturnclient.ui2; -import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.function.Function; -import org.saturnclient.saturnclient.SaturnClient; import org.saturnclient.saturnclient.config.ThemeManager; import org.saturnclient.saturnclient.mixin.DrawContextAccessor; -import org.saturnclient.ui2.anim.Animation; import org.saturnclient.ui2.anim.Curve; -import org.saturnclient.ui2.anim.SlideUp; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; @@ -25,41 +21,61 @@ public class SaturnScreen extends Screen { } public void draw(Element element) { - Animation animation = new SlideUp(); - // Function curve = Curve::easeIn; - - int duration = 500; - synchronized (elements) { elements.add(element); } + + if (element.animation != null) { + element.animation.init(element); + new Thread(() -> { + Function curveFunction = Curve::easeInOutCubicReverse; + int delay = (element.animation.duration / 20) - 15; + long startTime = System.currentTimeMillis(); + float lastProgress = 0.0f; - // new Thread(() -> { - // boolean running = true; - // Instant start = Instant.now(); - // int tick = 0; - // while (running) { - // if (animation != null) { - // int elapsedMs = (int) java.time.Duration.between(start, Instant.now()).toMillis(); + while (true) { + int elapsed = (int) (System.currentTimeMillis() - startTime); - // if (elapsedMs > duration) { - // running = false; - // } + float progress = Math.round(curveFunction.apply((double) elapsed / element.animation.duration) * 1000.0f) / 1000.0f; - // float progress = animation.tick(tick, element); + float p = lastProgress; - // SaturnClient.LOGGER.info("ms: " + curve.apply(progress) + ", Progress: " + progress); - - // try { - // Thread.sleep(30); - // } catch (Exception e) { - // } - // tick++; - // } else { - // running = false; - // } - // } - // }).start(); + while (progress != p) { + if (p < progress) { + p += 0.01f; + if (p > progress) p = progress; + } else if (p > progress) { + p -= 0.01f; + if (p < progress) p = progress; + } + + element.animation.tick(p, element); + + try { + Thread.sleep(4); + } catch (Exception e) { + e.printStackTrace(); + } + } + + if (elapsed > (element.animation.duration + 30)) { + break; + } + + if (progress != lastProgress) { + lastProgress = p; + } + + if (delay > 0) { + try { + Thread.sleep(delay); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + }).start(); + } } @Override diff --git a/src/main/java/org/saturnclient/ui2/anim/Animation.java b/src/main/java/org/saturnclient/ui2/anim/Animation.java index fac53eb..ca04a39 100644 --- a/src/main/java/org/saturnclient/ui2/anim/Animation.java +++ b/src/main/java/org/saturnclient/ui2/anim/Animation.java @@ -3,5 +3,12 @@ package org.saturnclient.ui2.anim; import org.saturnclient.ui2.Element; public abstract class Animation { - public abstract float tick(int tick, Element element); + public int duration; + + Animation(int duration) { + this.duration = duration; + } + + public abstract void tick(float progress, Element element); + public abstract void init(Element element); } diff --git a/src/main/java/org/saturnclient/ui2/anim/Curve.java b/src/main/java/org/saturnclient/ui2/anim/Curve.java index 81c5e3e..82db6fb 100644 --- a/src/main/java/org/saturnclient/ui2/anim/Curve.java +++ b/src/main/java/org/saturnclient/ui2/anim/Curve.java @@ -1,85 +1,11 @@ package org.saturnclient.ui2.anim; -import java.time.Instant; -import java.util.function.Function; - -import org.saturnclient.saturnclient.SaturnClient; - public class Curve { - // Define the curve functions (ease-in, ease-out, ease-in-out) - public static int easeIn(float progress, long elapsedTime, float totalDuration) { - // Ease-in: Modify the curve based on elapsed time - float t = progress; - t *= t; // Ease-in: t^2 - // Scale the delay based on the remaining time - return (int) ((t * (totalDuration - elapsedTime)) / totalDuration); + public static double easeInOutCubic(double x) { + return (x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2); } - public static int easeOut(float progress, long elapsedTime, float totalDuration) { - // Ease-out: Modify the curve based on elapsed time - float t = progress; - t = 1 - (1 - t) * (1 - t); // Ease-out: 1 - (1 - t)^2 - // Scale the delay based on the remaining time - return (int) ((t * (totalDuration - elapsedTime)) / totalDuration); - } - - public static int easeInOut(float progress, long elapsedTime, float totalDuration) { - // Ease-in-out: Modify the curve based on elapsed time - double t = progress; - if (t < 0.5) { - t = 2 * t * t; // Ease-in: t^2 - } else { - t = 1 - Math.pow(-2 * t + 2, 2) / 2; // Ease-out: 1 - (2t-2)^2 / 2 - } - // Scale the delay based on the remaining time - return (int) ((t * (totalDuration - elapsedTime)) / totalDuration); - } - - public static void animate(float totalDuration, float increment) { - long startTime = System.currentTimeMillis(); - float progress = 0.0f; - float progressPerStep = increment; - long elapsedTime = 0; // Track the total elapsed time - - // Animation loop until progress reaches 1.0 - while (progress < 1.0f) { - // Calculate the current progress value - progress = Math.min(progress + progressPerStep, 1.0f); // Ensure progress does not exceed 1.0 - - // Calculate the elapsed time - elapsedTime = System.currentTimeMillis() - startTime; - - // Calculate the delay based on the current progress and elapsed time using the easing function - // We switch between easeIn, easeOut, and easeInOut for different effects - int delay = easeInOut(progress, elapsedTime, totalDuration); - - // Print the progress and delay for debugging - System.out.println("Progress: " + (progress * 100) + "%, Delay: " + delay + "ms"); - - // Ensure we don't sleep for a negative value - if (delay < 1) { - delay = 1; // Avoid immediate jumps, ensure some delay for visual effect - } - - // Sleep for the delay calculated by the easing function - try { - Thread.sleep(delay); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - // If the elapsed time exceeds the total duration, break out of the loop - if (elapsedTime >= totalDuration) { - break; - } - } - - System.out.println("Animation Complete!"); - } - - public static void main(String[] args) { - float durationInMillis = 500.0f; // Total duration of the animation in ms - float increment = 0.01f; // Increment the progress by 1% each step - animate(durationInMillis, increment); // Start the animation + public static double easeInOutCubicReverse(double x) { + return -(x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2); } } diff --git a/src/main/java/org/saturnclient/ui2/anim/SlideUp.java b/src/main/java/org/saturnclient/ui2/anim/SlideUp.java deleted file mode 100644 index b7393ac..0000000 --- a/src/main/java/org/saturnclient/ui2/anim/SlideUp.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.saturnclient.ui2.anim; - -import org.saturnclient.ui2.Element; - -public class SlideUp extends Animation { - int targetY; - - @Override - public float tick(int tick, Element element) { - if (tick == 0) { - targetY = element.y; - element.y += 20; - } else if (element.y > targetY) { - element.y--; - return ((float) element.y) / targetY; - } - - return 0.1f; - } -} diff --git a/src/main/java/org/saturnclient/ui2/screens/ShiftMenu.java b/src/main/java/org/saturnclient/ui2/screens/ShiftMenu.java index e36602c..f69620a 100644 --- a/src/main/java/org/saturnclient/ui2/screens/ShiftMenu.java +++ b/src/main/java/org/saturnclient/ui2/screens/ShiftMenu.java @@ -10,6 +10,7 @@ import org.saturnclient.ui2.SaturnScreen; import org.saturnclient.ui2.elements.Button; import org.saturnclient.ui2.elements.ImageTexture; import org.saturnclient.ui2.elements.TextureButton; +import org.saturnclient.ui2.anim.SlideY; public class ShiftMenu extends SaturnScreen { public ShiftMenu() { @@ -18,21 +19,21 @@ public class ShiftMenu extends SaturnScreen { @Override public void ui() { - draw(new ImageTexture(Textures.LOGO).dimensions(49, 49).centerOffset(width, height, 0, -45)); - // draw(new ImageTexture(Textures.LOGO_TEXT).dimensions(49, 8).centerOffset(width, height, 0, -23)); + draw(new ImageTexture(Textures.LOGO).dimensions(49, 49).centerOffset(width, height, 0, -45).animation(new SlideY(300))); + draw(new ImageTexture(Textures.LOGO_TEXT).dimensions(49, 8).centerOffset(width, height, 0, -23)); - // Element button = new Button("Settings", () -> { - // SaturnClient.client.setScreen(new ModMenu()); - // }).center(width, height); + Element button = new Button("Settings", () -> { + SaturnClient.client.setScreen(new ModMenu()); + }).center(width, height); - // draw(button); + draw(button); - // draw(new TextureButton(Textures.COSMETICS, () -> { - // client.setScreen(new CloaksMenu()); - // }).dimensions(button.height, button.height).centerOffset(width, height, (button.width / 2) + (button.height / 2) + 4, 0)); + draw(new TextureButton(Textures.COSMETICS, () -> { + client.setScreen(new CloaksMenu()); + }).dimensions(button.height, button.height).centerOffset(width, height, (button.width / 2) + (button.height / 2) + 4, 0)); - // draw(new TextureButton(Textures.HUD_ICON, () -> { - // client.setScreen(new HudEditor()); - // }).dimensions(button.height, button.height).centerOffset(width, height, -((button.width / 2) + (button.height / 2) + 4), 0)); + draw(new TextureButton(Textures.HUD_ICON, () -> { + client.setScreen(new HudEditor()); + }).dimensions(button.height, button.height).centerOffset(width, height, -((button.width / 2) + (button.height / 2) + 4), 0)); } } diff --git a/src/main/java/org/test/test/AnimationExample.java b/src/main/java/org/test/test/AnimationExample.java deleted file mode 100644 index 9b3863e..0000000 --- a/src/main/java/org/test/test/AnimationExample.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.test.test; - -import java.util.function.Function; - -public class AnimationExample { - public static void main(String[] args) { - long stime = System.currentTimeMillis(); - Function curveFunction = CurveFunctions::easeOut; - int duration = 300; - int delayOnProgress = duration / 4; - - // 0.1 -> 0.5 = +=0.01 - - float progress = 0f; - - while (System.currentTimeMillis() - stime < duration) { - float newProgress = Math.min(1.0f, curveFunction.apply(progress + 0.05f)); - - if (newProgress == progress) { - newProgress += 0.05; - } - - while (progress != newProgress) { - if (progress > newProgress) { - progress -= 0.05; - if (progress < newProgress) progress = newProgress; - } else if (progress < newProgress) { - progress += 0.05; - if (progress > newProgress) progress = newProgress; - } else { - progress += 0.05; - } - } - - System.out.println("New Progress: " + progress); - - } - - - System.out.println((System.currentTimeMillis() - stime) + "ms"); - } - - // Define the EasingFunction interface (to be passed to functions like easeInOut) - @FunctionalInterface - public interface EasingFunction { - double apply(double t); // Apply the easing function to the normalized progress - } -} diff --git a/src/main/java/org/test/test/CurveFunctions.java b/src/main/java/org/test/test/CurveFunctions.java deleted file mode 100644 index 3525c07..0000000 --- a/src/main/java/org/test/test/CurveFunctions.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.test.test; - -public class CurveFunctions { - public static float linear(float t) { - return t; - } - - public static float easeIn(float t) { - return t * t; - } - - public static float easeOut(float t) { - return (float)(1 - Math.pow(1 - t, 2)); - } - - public static float easeInOut(float t) { - return (float)((-Math.cos(Math.PI * t) / 2.0) + 0.5); - } - - public static float bounceOut(float t) { - if (t < (1/2.75f)) { - return 7.5625f * t * t; - } else if (t < (2/2.75f)) { - t -= (1.5f/2.75f); - return 7.5625f * t * t + 0.75f; - } else if (t < (2.5/2.75)) { - t -= (2.25f/2.75f); - return 7.5625f * t * t + 0.9375f; - } else { - t -= (2.625f/2.75f); - return 7.5625f * t * t + 0.984375f; - } - } -}