experiment: animation curve functions
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
package org.saturnclient.ui2;
|
package org.saturnclient.ui2;
|
||||||
|
|
||||||
public class Element {
|
public class Element {
|
||||||
protected int x;
|
public int x;
|
||||||
protected int y;
|
public int y;
|
||||||
public int width;
|
public int width;
|
||||||
public int height;
|
public int height;
|
||||||
public boolean focused;
|
public boolean focused;
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
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 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.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;
|
||||||
@@ -19,9 +25,41 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
// if (elapsedMs > duration) {
|
||||||
|
// running = false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// float progress = animation.tick(tick, element);
|
||||||
|
|
||||||
|
// SaturnClient.LOGGER.info("ms: " + curve.apply(progress) + ", Progress: " + progress);
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// Thread.sleep(30);
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// }
|
||||||
|
// tick++;
|
||||||
|
// } else {
|
||||||
|
// running = false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package org.saturnclient.ui2.anim;
|
||||||
|
|
||||||
|
import org.saturnclient.ui2.Element;
|
||||||
|
|
||||||
|
public abstract class Animation {
|
||||||
|
public abstract float tick(int tick, Element element);
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
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 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,20 +19,20 @@ 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));
|
||||||
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
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