working animations
This commit is contained in:
@@ -1,11 +1,14 @@
|
|||||||
package org.saturnclient.ui2;
|
package org.saturnclient.ui2;
|
||||||
|
|
||||||
|
import org.saturnclient.ui2.anim.Animation;
|
||||||
|
|
||||||
public class Element {
|
public class Element {
|
||||||
public int x;
|
public int x;
|
||||||
public int y;
|
public int y;
|
||||||
public int width;
|
public int width;
|
||||||
public int height;
|
public int height;
|
||||||
public boolean focused;
|
public boolean focused;
|
||||||
|
public Animation animation;
|
||||||
|
|
||||||
public void render(RenderScope renderScope, RenderContext ctx) {
|
public void render(RenderScope renderScope, RenderContext ctx) {
|
||||||
}
|
}
|
||||||
@@ -40,4 +43,10 @@ public class Element {
|
|||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final Element animation(Animation animation) {
|
||||||
|
this.animation = animation;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
package org.saturnclient.ui2;
|
package org.saturnclient.ui2;
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
|
||||||
import org.saturnclient.saturnclient.config.ThemeManager;
|
import org.saturnclient.saturnclient.config.ThemeManager;
|
||||||
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
import org.saturnclient.saturnclient.mixin.DrawContextAccessor;
|
||||||
import org.saturnclient.ui2.anim.Animation;
|
|
||||||
import org.saturnclient.ui2.anim.Curve;
|
import org.saturnclient.ui2.anim.Curve;
|
||||||
import org.saturnclient.ui2.anim.SlideUp;
|
|
||||||
|
|
||||||
import net.minecraft.client.gui.DrawContext;
|
import net.minecraft.client.gui.DrawContext;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
@@ -25,41 +21,61 @@ public class SaturnScreen extends Screen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void draw(Element element) {
|
public void draw(Element element) {
|
||||||
Animation animation = new SlideUp();
|
|
||||||
// Function<Float, Integer> curve = Curve::easeIn;
|
|
||||||
|
|
||||||
int duration = 500;
|
|
||||||
|
|
||||||
synchronized (elements) {
|
synchronized (elements) {
|
||||||
elements.add(element);
|
elements.add(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (element.animation != null) {
|
||||||
|
element.animation.init(element);
|
||||||
|
new Thread(() -> {
|
||||||
|
Function<Double, Double> curveFunction = Curve::easeInOutCubicReverse;
|
||||||
|
int delay = (element.animation.duration / 20) - 15;
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
float lastProgress = 0.0f;
|
||||||
|
|
||||||
// new Thread(() -> {
|
while (true) {
|
||||||
// boolean running = true;
|
int elapsed = (int) (System.currentTimeMillis() - startTime);
|
||||||
// Instant start = Instant.now();
|
|
||||||
// int tick = 0;
|
|
||||||
// while (running) {
|
|
||||||
// if (animation != null) {
|
|
||||||
// int elapsedMs = (int) java.time.Duration.between(start, Instant.now()).toMillis();
|
|
||||||
|
|
||||||
// if (elapsedMs > duration) {
|
float progress = Math.round(curveFunction.apply((double) elapsed / element.animation.duration) * 1000.0f) / 1000.0f;
|
||||||
// running = false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// float progress = animation.tick(tick, element);
|
float p = lastProgress;
|
||||||
|
|
||||||
// SaturnClient.LOGGER.info("ms: " + curve.apply(progress) + ", Progress: " + progress);
|
while (progress != p) {
|
||||||
|
if (p < progress) {
|
||||||
// try {
|
p += 0.01f;
|
||||||
// Thread.sleep(30);
|
if (p > progress) p = progress;
|
||||||
// } catch (Exception e) {
|
} else if (p > progress) {
|
||||||
// }
|
p -= 0.01f;
|
||||||
// tick++;
|
if (p < progress) p = progress;
|
||||||
// } else {
|
}
|
||||||
// running = false;
|
|
||||||
// }
|
element.animation.tick(p, element);
|
||||||
// }
|
|
||||||
// }).start();
|
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
|
@Override
|
||||||
|
|||||||
@@ -3,5 +3,12 @@ package org.saturnclient.ui2.anim;
|
|||||||
import org.saturnclient.ui2.Element;
|
import org.saturnclient.ui2.Element;
|
||||||
|
|
||||||
public abstract class Animation {
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,85 +1,11 @@
|
|||||||
package org.saturnclient.ui2.anim;
|
package org.saturnclient.ui2.anim;
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import org.saturnclient.saturnclient.SaturnClient;
|
|
||||||
|
|
||||||
public class Curve {
|
public class Curve {
|
||||||
// Define the curve functions (ease-in, ease-out, ease-in-out)
|
public static double easeInOutCubic(double x) {
|
||||||
public static int easeIn(float progress, long elapsedTime, float totalDuration) {
|
return (x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2);
|
||||||
// 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 int easeOut(float progress, long elapsedTime, float totalDuration) {
|
public static double easeInOutCubicReverse(double x) {
|
||||||
// Ease-out: Modify the curve based on elapsed time
|
return -(x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,6 +10,7 @@ import org.saturnclient.ui2.SaturnScreen;
|
|||||||
import org.saturnclient.ui2.elements.Button;
|
import org.saturnclient.ui2.elements.Button;
|
||||||
import org.saturnclient.ui2.elements.ImageTexture;
|
import org.saturnclient.ui2.elements.ImageTexture;
|
||||||
import org.saturnclient.ui2.elements.TextureButton;
|
import org.saturnclient.ui2.elements.TextureButton;
|
||||||
|
import org.saturnclient.ui2.anim.SlideY;
|
||||||
|
|
||||||
public class ShiftMenu extends SaturnScreen {
|
public class ShiftMenu extends SaturnScreen {
|
||||||
public ShiftMenu() {
|
public ShiftMenu() {
|
||||||
@@ -18,21 +19,21 @@ public class ShiftMenu extends SaturnScreen {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void ui() {
|
public void ui() {
|
||||||
draw(new ImageTexture(Textures.LOGO).dimensions(49, 49).centerOffset(width, height, 0, -45));
|
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));
|
draw(new ImageTexture(Textures.LOGO_TEXT).dimensions(49, 8).centerOffset(width, height, 0, -23));
|
||||||
|
|
||||||
// Element button = new Button("Settings", () -> {
|
Element button = new Button("Settings", () -> {
|
||||||
// SaturnClient.client.setScreen(new ModMenu());
|
SaturnClient.client.setScreen(new ModMenu());
|
||||||
// }).center(width, height);
|
}).center(width, height);
|
||||||
|
|
||||||
// draw(button);
|
draw(button);
|
||||||
|
|
||||||
// draw(new TextureButton(Textures.COSMETICS, () -> {
|
draw(new TextureButton(Textures.COSMETICS, () -> {
|
||||||
// client.setScreen(new CloaksMenu());
|
client.setScreen(new CloaksMenu());
|
||||||
// }).dimensions(button.height, button.height).centerOffset(width, height, (button.width / 2) + (button.height / 2) + 4, 0));
|
}).dimensions(button.height, button.height).centerOffset(width, height, (button.width / 2) + (button.height / 2) + 4, 0));
|
||||||
|
|
||||||
// draw(new TextureButton(Textures.HUD_ICON, () -> {
|
draw(new TextureButton(Textures.HUD_ICON, () -> {
|
||||||
// client.setScreen(new HudEditor());
|
client.setScreen(new HudEditor());
|
||||||
// }).dimensions(button.height, button.height).centerOffset(width, height, -((button.width / 2) + (button.height / 2) + 4), 0));
|
}).dimensions(button.height, button.height).centerOffset(width, height, -((button.width / 2) + (button.height / 2) + 4), 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<Float, Float> 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user