From f952fa70958980436921f7f7ca7cd63a6d7d23d7 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Sun, 22 Feb 2026 00:12:13 +0100 Subject: [PATCH] Better animation system --- .../java/org/saturnclient/ui2/Element.java | 6 ++ .../org/saturnclient/ui2/ElementContext.java | 4 +- .../org/saturnclient/ui2/SaturnScreen.java | 47 +++----------- .../org/saturnclient/ui2/anim/Animation.java | 64 +------------------ .../java/org/saturnclient/ui2/anim/Fade.java | 4 +- .../org/saturnclient/ui2/anim/FadeOut.java | 4 +- .../org/saturnclient/ui2/anim/SlideX.java | 2 +- .../saturnclient/ui2/anim/SlideXAbsolute.java | 2 +- .../org/saturnclient/ui2/anim/SlideY.java | 2 +- .../ui2/components/ElementRenderer.java | 11 ++-- .../org/saturnclient/ui2/elements/Scroll.java | 2 +- 11 files changed, 33 insertions(+), 115 deletions(-) diff --git a/src/main/java/org/saturnclient/ui2/Element.java b/src/main/java/org/saturnclient/ui2/Element.java index ec8b110..296ec7f 100644 --- a/src/main/java/org/saturnclient/ui2/Element.java +++ b/src/main/java/org/saturnclient/ui2/Element.java @@ -41,6 +41,12 @@ public class Element { public void mouseReleased(double mouseX, double mouseY, int button) { } + public void playAnimationFrame(long elapsed) { + if (this.animation != null) { + this.animation.tick(this.curve.apply(Math.min(1.0, (double) elapsed / this.animation.duration)), this); + } + } + public Element dimensions(int width, int height) { this.width = width; this.height = height; diff --git a/src/main/java/org/saturnclient/ui2/ElementContext.java b/src/main/java/org/saturnclient/ui2/ElementContext.java index 8f3f898..def84dd 100644 --- a/src/main/java/org/saturnclient/ui2/ElementContext.java +++ b/src/main/java/org/saturnclient/ui2/ElementContext.java @@ -4,13 +4,15 @@ public class ElementContext { public int mouseX, mouseY; public int elementWidth, elementHeight; public float elementScale; + public long elapsed; - public ElementContext(int mouseX, int mouseY, Element e) { + public ElementContext(long elapsed, int mouseX, int mouseY, Element e) { this.mouseX = mouseX - e.x; this.mouseY = mouseY - e.y; this.elementWidth = e.width; this.elementHeight = e.height; this.elementScale = e.scale; + this.elapsed = elapsed; } public boolean isHovering() { diff --git a/src/main/java/org/saturnclient/ui2/SaturnScreen.java b/src/main/java/org/saturnclient/ui2/SaturnScreen.java index c6af321..f88cbe6 100644 --- a/src/main/java/org/saturnclient/ui2/SaturnScreen.java +++ b/src/main/java/org/saturnclient/ui2/SaturnScreen.java @@ -1,11 +1,11 @@ package org.saturnclient.ui2; +import java.time.Duration; +import java.time.Instant; import java.util.ArrayList; import java.util.List; import org.saturnclient.saturnclient.mixin.DrawContextAccessor; -import org.saturnclient.ui2.anim.Animation; -import org.saturnclient.ui2.anim.SlideXAbsolute; import org.saturnclient.ui2.components.ElementRenderer; import net.minecraft.client.MinecraftClient; @@ -23,6 +23,7 @@ public abstract class SaturnScreen extends Screen { private final Pool pool = new Pool(3); protected List elements = new ArrayList<>(); protected float backgroundOpacity = 1.0f; + protected Instant start = null; public int blurDuration = 700; public float blurProgress = 0.0f; public int backgroundBlur = 10; @@ -41,36 +42,7 @@ public abstract class SaturnScreen extends Screen { } public void draw(Element element) { - synchronized (elements) { - elements.add(element); - } - - if (element.animation != null) { - element.animation.init(element); - - Animation.execute((Float progress) -> { - element.animation.tick(progress, element); - }, element.animation.duration); - } - - if (element.duration != null) { - new Thread(() -> { - try { - Animation fadeOut = new SlideXAbsolute(700, -(width - element.x)); - Thread.sleep(element.duration); - fadeOut.init(element); - Animation.executeSync((Float progress) -> { - fadeOut.tick(progress, element); - }, fadeOut.duration); - synchronized (elements) { - elements.remove(element); - } - - } catch (InterruptedException e) { - e.printStackTrace(); - } - }).start(); - } + ElementRenderer.draw(elements, element); } @Override @@ -79,10 +51,6 @@ public abstract class SaturnScreen extends Screen { width *= 2; height *= 2; ui(); // abstraction to render the saturn ui and also render extra stuff here - - Animation.execute((Float progress) -> { - blurProgress = progress; - }, blurDuration); } public abstract void ui(); @@ -90,6 +58,11 @@ public abstract class SaturnScreen extends Screen { @SuppressWarnings("deprecation") @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { + if (start == null) { + start = Instant.now(); + } + long elapsed = Duration.between(start, Instant.now()).toMillis(); + mouseX *= 2; mouseY *= 2; @@ -114,7 +87,7 @@ public abstract class SaturnScreen extends Screen { renderScope.matrices.scale(0.5f, 0.5f, 0.5f); - ElementRenderer.render(new ArrayList<>(elements), renderScope, mouseX, mouseY); + ElementRenderer.render(new ArrayList<>(elements), elapsed, renderScope, mouseX, mouseY); renderScope.matrices.pop(); } diff --git a/src/main/java/org/saturnclient/ui2/anim/Animation.java b/src/main/java/org/saturnclient/ui2/anim/Animation.java index d1ed85d..269cbcf 100644 --- a/src/main/java/org/saturnclient/ui2/anim/Animation.java +++ b/src/main/java/org/saturnclient/ui2/anim/Animation.java @@ -1,8 +1,5 @@ package org.saturnclient.ui2.anim; -import java.util.function.Consumer; -import java.util.function.Function; - import org.saturnclient.ui2.Element; public abstract class Animation { @@ -12,64 +9,7 @@ public abstract class Animation { this.duration = duration; } - public abstract void tick(float progress, Element element); + public abstract void tick(double progress, Element element); + public abstract void init(Element element); - - public static void execute(Consumer tick, int duration) { - new Thread(() -> { - Function curveFunction = Curve::easeInOutCubic; - float progress = 0.0f; - double incremental = (1000 - duration) / 10000.0; - - for (int i = 0; i <= 100; i++) { - float newProgress = (float) (double) curveFunction.apply(i / 100.0); - - while (Math.abs(newProgress - progress) > 1e-6) { - if (progress < newProgress) { - progress += incremental; - if (progress > newProgress) progress = newProgress; - } else { - progress -= incremental; - if (progress < newProgress) progress = newProgress; - } - - tick.accept(newProgress); - - try { - Thread.sleep(duration / 100); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - }).start(); - } - - public static void executeSync(Consumer tick, int duration) { - Function curveFunction = Curve::easeInOutCubic; - float progress = 0.0f; - double incremental = (1000 - duration) / 10000.0; - - for (int i = 0; i <= 100; i++) { - float newProgress = (float) (double) curveFunction.apply(i / 100.0); - - while (Math.abs(newProgress - progress) > 1e-6) { - if (progress < newProgress) { - progress += incremental; - if (progress > newProgress) progress = newProgress; - } else { - progress -= incremental; - if (progress < newProgress) progress = newProgress; - } - - tick.accept(newProgress); - - try { - Thread.sleep(duration / 100); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } } diff --git a/src/main/java/org/saturnclient/ui2/anim/Fade.java b/src/main/java/org/saturnclient/ui2/anim/Fade.java index 47dfd65..b20bade 100644 --- a/src/main/java/org/saturnclient/ui2/anim/Fade.java +++ b/src/main/java/org/saturnclient/ui2/anim/Fade.java @@ -10,8 +10,8 @@ public class Fade extends Animation { } @Override - public void tick(float progress, Element element) { - element.opacity = targetOpacity * progress; + public void tick(double progress, Element element) { + element.opacity = targetOpacity * (float) progress; } @Override diff --git a/src/main/java/org/saturnclient/ui2/anim/FadeOut.java b/src/main/java/org/saturnclient/ui2/anim/FadeOut.java index a1fb42a..77d93f6 100644 --- a/src/main/java/org/saturnclient/ui2/anim/FadeOut.java +++ b/src/main/java/org/saturnclient/ui2/anim/FadeOut.java @@ -10,8 +10,8 @@ public class FadeOut extends Animation { } @Override - public void tick(float progress, Element element) { - element.opacity = targetOpacity - progress; + public void tick(double progress, Element element) { + element.opacity = targetOpacity - (float) progress; } @Override diff --git a/src/main/java/org/saturnclient/ui2/anim/SlideX.java b/src/main/java/org/saturnclient/ui2/anim/SlideX.java index 595c412..58d5e8c 100644 --- a/src/main/java/org/saturnclient/ui2/anim/SlideX.java +++ b/src/main/java/org/saturnclient/ui2/anim/SlideX.java @@ -24,7 +24,7 @@ public class SlideX extends Animation { } @Override - public void tick(float progress, Element element) { + public void tick(double progress, Element element) { element.x = elementX + (int) (offset * progress); } diff --git a/src/main/java/org/saturnclient/ui2/anim/SlideXAbsolute.java b/src/main/java/org/saturnclient/ui2/anim/SlideXAbsolute.java index ace746f..75a3121 100644 --- a/src/main/java/org/saturnclient/ui2/anim/SlideXAbsolute.java +++ b/src/main/java/org/saturnclient/ui2/anim/SlideXAbsolute.java @@ -24,7 +24,7 @@ public class SlideXAbsolute extends Animation { } @Override - public void tick(float progress, Element element) { + public void tick(double progress, Element element) { element.x = elementX + (int) (offset * progress); } diff --git a/src/main/java/org/saturnclient/ui2/anim/SlideY.java b/src/main/java/org/saturnclient/ui2/anim/SlideY.java index 48ca61b..9d91f3b 100644 --- a/src/main/java/org/saturnclient/ui2/anim/SlideY.java +++ b/src/main/java/org/saturnclient/ui2/anim/SlideY.java @@ -26,7 +26,7 @@ public class SlideY extends Animation { } @Override - public void tick(float progress, Element element) { + public void tick(double progress, Element element) { element.y = elementY + (int) (offset * progress); } diff --git a/src/main/java/org/saturnclient/ui2/components/ElementRenderer.java b/src/main/java/org/saturnclient/ui2/components/ElementRenderer.java index ee165da..30842a1 100644 --- a/src/main/java/org/saturnclient/ui2/components/ElementRenderer.java +++ b/src/main/java/org/saturnclient/ui2/components/ElementRenderer.java @@ -7,7 +7,6 @@ import org.saturnclient.ui2.Element; import org.saturnclient.ui2.ElementContext; import org.saturnclient.ui2.RenderScope; import org.saturnclient.ui2.Utils; -import org.saturnclient.ui2.anim.Animation; public class ElementRenderer { public static void draw(List elements, Element element) { @@ -17,20 +16,18 @@ public class ElementRenderer { if (element.animation != null) { element.animation.init(element); - - Animation.execute((Float progress) -> { - element.animation.tick(progress, element); - }, element.animation.duration); } } - public static void render(List elements, RenderScope renderScope, int mouseX, int mouseY) { + public static void render(List elements, long elapsed, RenderScope renderScope, int mouseX, int mouseY) { for (Element element : elements) { + element.playAnimationFrame(elapsed); + renderScope.matrices.push(); renderScope.setOpacity(element.opacity); renderScope.matrices.translate(element.x, element.y, 0); renderScope.matrices.scale(element.scale, element.scale, 1.0f); - element.render(renderScope, new ElementContext(mouseX, mouseY, element)); + element.render(renderScope, new ElementContext(elapsed, mouseX, mouseY, element)); renderScope.matrices.pop(); renderScope.setRenderLayer(null); } diff --git a/src/main/java/org/saturnclient/ui2/elements/Scroll.java b/src/main/java/org/saturnclient/ui2/elements/Scroll.java index 4ebd219..e02e379 100644 --- a/src/main/java/org/saturnclient/ui2/elements/Scroll.java +++ b/src/main/java/org/saturnclient/ui2/elements/Scroll.java @@ -36,7 +36,7 @@ public class Scroll extends Element { renderScope.matrices.push(); renderScope.matrices.translate(padding, -scroll + padding, 0); - ElementRenderer.render(children, renderScope, + ElementRenderer.render(children, ctx.elapsed, renderScope, ctx.mouseX - padding, ctx.mouseY - padding + scroll);