working animations
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Float, Integer> curve = Curve::easeIn;
|
||||
|
||||
int duration = 500;
|
||||
|
||||
synchronized (elements) {
|
||||
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(() -> {
|
||||
// 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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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