From 94223e3265b21a55cdf7e38ab3204e70aa8600bb Mon Sep 17 00:00:00 2001 From: Nic Barker Date: Tue, 31 Mar 2026 22:26:14 +1100 Subject: [PATCH] Add Clay_EaseOut to clay.h --- clay.h | 59 ++++++++++++++++++++++++++++++ examples/raylib-transitions/main.c | 54 --------------------------- 2 files changed, 59 insertions(+), 54 deletions(-) diff --git a/clay.h b/clay.h index ec9dd52..fbb8760 100644 --- a/clay.h +++ b/clay.h @@ -1021,6 +1021,8 @@ CLAY_DLL_EXPORT int32_t Clay_GetMaxMeasureTextCacheWordCount(void); CLAY_DLL_EXPORT void Clay_SetMaxMeasureTextCacheWordCount(int32_t maxMeasureTextCacheWordCount); // Resets Clay's internal text measurement cache. Useful if font mappings have changed or fonts have been reloaded. CLAY_DLL_EXPORT void Clay_ResetMeasureTextCache(void); +// A built in transition function that uses the "Ease Out" curve +CLAY_DLL_EXPORT bool Clay_EaseOut(Clay_TransitionCallbackArguments arguments); // Internal API functions required by macros ---------------------- @@ -4825,6 +4827,63 @@ void Clay_ResetMeasureTextCache(void) { context->measureTextHashMapInternal.length = 1; // Reserve the 0 value to mean "no next element" } +#define CLAY__LERP(from, to, mix) from + (to - from) * mix + +CLAY_DLL_EXPORT bool Clay_EaseOut(Clay_TransitionCallbackArguments arguments) { + float ratio = 1; + if (arguments.duration > 0) { + ratio = CLAY__MIN(arguments.elapsedTime / arguments.duration, 1); + } + float inverse = 1.0f - ratio; + float lerpAmount = 1.0f - (inverse * inverse * inverse); + if (arguments.properties & CLAY_TRANSITION_PROPERTY_X) { + arguments.current->boundingBox.x = CLAY__LERP(arguments.initial.boundingBox.x, arguments.target.boundingBox.x, lerpAmount); + } + if (arguments.properties & CLAY_TRANSITION_PROPERTY_Y) { + arguments.current->boundingBox.y = CLAY__LERP(arguments.initial.boundingBox.y, arguments.target.boundingBox.y, lerpAmount); + } + if (arguments.properties & CLAY_TRANSITION_PROPERTY_WIDTH) { + arguments.current->boundingBox.width = CLAY__LERP(arguments.initial.boundingBox.width, arguments.target.boundingBox.width, lerpAmount); + } + if (arguments.properties & CLAY_TRANSITION_PROPERTY_HEIGHT) { + arguments.current->boundingBox.height = CLAY__LERP(arguments.initial.boundingBox.height, arguments.target.boundingBox.height, lerpAmount); + } + if (arguments.properties & CLAY_TRANSITION_PROPERTY_BACKGROUND_COLOR) { + arguments.current->backgroundColor = CLAY__INIT(Clay_Color) { + .r = CLAY__LERP(arguments.initial.backgroundColor.r, arguments.target.backgroundColor.r, lerpAmount), + .g = CLAY__LERP(arguments.initial.backgroundColor.g, arguments.target.backgroundColor.g, lerpAmount), + .b = CLAY__LERP(arguments.initial.backgroundColor.b, arguments.target.backgroundColor.b, lerpAmount), + .a = CLAY__LERP(arguments.initial.backgroundColor.a, arguments.target.backgroundColor.a, lerpAmount), + }; + } + if (arguments.properties & CLAY_TRANSITION_PROPERTY_OVERLAY_COLOR) { + arguments.current->overlayColor = CLAY__INIT(Clay_Color) { + .r = CLAY__LERP(arguments.initial.overlayColor.r, arguments.target.overlayColor.r, lerpAmount), + .g = CLAY__LERP(arguments.initial.overlayColor.g, arguments.target.overlayColor.g, lerpAmount), + .b = CLAY__LERP(arguments.initial.overlayColor.b, arguments.target.overlayColor.b, lerpAmount), + .a = CLAY__LERP(arguments.initial.overlayColor.a, arguments.target.overlayColor.a, lerpAmount), + }; + } + if (arguments.properties & CLAY_TRANSITION_PROPERTY_BORDER_COLOR) { + arguments.current->borderColor = CLAY__INIT(Clay_Color) { + .r = CLAY__LERP(arguments.initial.borderColor.r, arguments.target.borderColor.r, lerpAmount), + .g = CLAY__LERP(arguments.initial.borderColor.g, arguments.target.borderColor.g, lerpAmount), + .b = CLAY__LERP(arguments.initial.borderColor.b, arguments.target.borderColor.b, lerpAmount), + .a = CLAY__LERP(arguments.initial.borderColor.a, arguments.target.borderColor.a, lerpAmount), + }; + } + if (arguments.properties & CLAY_TRANSITION_PROPERTY_BORDER_WIDTH) { + arguments.current->borderWidth = CLAY__INIT(Clay_BorderWidth) { + .left = CLAY__LERP(arguments.initial.borderWidth.left, arguments.target.borderWidth.left, lerpAmount), + .right = CLAY__LERP(arguments.initial.borderWidth.right, arguments.target.borderWidth.right, lerpAmount), + .top = CLAY__LERP(arguments.initial.borderWidth.top, arguments.target.borderWidth.top, lerpAmount), + .bottom = CLAY__LERP(arguments.initial.borderWidth.bottom, arguments.target.borderWidth.bottom, lerpAmount), + .betweenChildren = CLAY__LERP(arguments.initial.borderWidth.betweenChildren, arguments.target.borderWidth.betweenChildren, lerpAmount), + }; + } + return ratio >= 1; +} + #endif // CLAY_IMPLEMENTATION /* diff --git a/examples/raylib-transitions/main.c b/examples/raylib-transitions/main.c index 66f84b6..491e29f 100644 --- a/examples/raylib-transitions/main.c +++ b/examples/raylib-transitions/main.c @@ -70,60 +70,6 @@ typedef struct { Arena frameArena = {}; -bool Clay_EaseOut(Clay_TransitionCallbackArguments arguments) { - float ratio = 1; - if (arguments.duration > 0) { - ratio = arguments.elapsedTime / arguments.duration; - } - float lerpAmount = (1 - powf(1 - CLAY__MIN(ratio, 1.f), 3.0f)); - if (arguments.properties & CLAY_TRANSITION_PROPERTY_X) { - arguments.current->boundingBox.x = Lerp(arguments.initial.boundingBox.x, arguments.target.boundingBox.x, lerpAmount); - } - if (arguments.properties & CLAY_TRANSITION_PROPERTY_Y) { - arguments.current->boundingBox.y = Lerp(arguments.initial.boundingBox.y, arguments.target.boundingBox.y, lerpAmount); - } - if (arguments.properties & CLAY_TRANSITION_PROPERTY_WIDTH) { - arguments.current->boundingBox.width = Lerp(arguments.initial.boundingBox.width, arguments.target.boundingBox.width, lerpAmount); - } - if (arguments.properties & CLAY_TRANSITION_PROPERTY_HEIGHT) { - arguments.current->boundingBox.height = Lerp(arguments.initial.boundingBox.height, arguments.target.boundingBox.height, lerpAmount); - } - if (arguments.properties & CLAY_TRANSITION_PROPERTY_BACKGROUND_COLOR) { - arguments.current->backgroundColor = CLAY__INIT(Clay_Color) { - .r = Lerp(arguments.initial.backgroundColor.r, arguments.target.backgroundColor.r, lerpAmount), - .g = Lerp(arguments.initial.backgroundColor.g, arguments.target.backgroundColor.g, lerpAmount), - .b = Lerp(arguments.initial.backgroundColor.b, arguments.target.backgroundColor.b, lerpAmount), - .a = Lerp(arguments.initial.backgroundColor.a, arguments.target.backgroundColor.a, lerpAmount), - }; - } - if (arguments.properties & CLAY_TRANSITION_PROPERTY_OVERLAY_COLOR) { - arguments.current->overlayColor = CLAY__INIT(Clay_Color) { - .r = Lerp(arguments.initial.overlayColor.r, arguments.target.overlayColor.r, lerpAmount), - .g = Lerp(arguments.initial.overlayColor.g, arguments.target.overlayColor.g, lerpAmount), - .b = Lerp(arguments.initial.overlayColor.b, arguments.target.overlayColor.b, lerpAmount), - .a = Lerp(arguments.initial.overlayColor.a, arguments.target.overlayColor.a, lerpAmount), - }; - } - if (arguments.properties & CLAY_TRANSITION_PROPERTY_BORDER_COLOR) { - arguments.current->borderColor = CLAY__INIT(Clay_Color) { - .r = Lerp(arguments.initial.borderColor.r, arguments.target.borderColor.r, lerpAmount), - .g = Lerp(arguments.initial.borderColor.g, arguments.target.borderColor.g, lerpAmount), - .b = Lerp(arguments.initial.borderColor.b, arguments.target.borderColor.b, lerpAmount), - .a = Lerp(arguments.initial.borderColor.a, arguments.target.borderColor.a, lerpAmount), - }; - } - if (arguments.properties & CLAY_TRANSITION_PROPERTY_BORDER_WIDTH) { - arguments.current->borderWidth = CLAY__INIT(Clay_BorderWidth) { - .left = Lerp(arguments.initial.borderWidth.left, arguments.target.borderWidth.left, lerpAmount), - .right = Lerp(arguments.initial.borderWidth.right, arguments.target.borderWidth.right, lerpAmount), - .top = Lerp(arguments.initial.borderWidth.top, arguments.target.borderWidth.top, lerpAmount), - .bottom = Lerp(arguments.initial.borderWidth.bottom, arguments.target.borderWidth.bottom, lerpAmount), - .betweenChildren = Lerp(arguments.initial.borderWidth.betweenChildren, arguments.target.borderWidth.betweenChildren, lerpAmount), - }; - } - return ratio >= 1; -} - Clay_TransitionData EnterExitSlideUp(Clay_TransitionData initialState, Clay_TransitionProperty properties) { Clay_TransitionData targetState = initialState; if (properties & CLAY_TRANSITION_PROPERTY_Y) {