Skip to content

Commit

Permalink
feat(legacy): On-Press animations for Keystrokes. (#5666)
Browse files Browse the repository at this point in the history
  • Loading branch information
mems01 authored Feb 20, 2025
1 parent b89f1dc commit d4bf9a5
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import net.ccbluex.liquidbounce.ui.font.GameFontRenderer
import net.ccbluex.liquidbounce.utils.extensions.lerpWith
import net.ccbluex.liquidbounce.utils.extensions.safeDiv
import net.ccbluex.liquidbounce.utils.render.ColorSettingsInteger
import net.ccbluex.liquidbounce.utils.render.ColorUtils
import net.ccbluex.liquidbounce.utils.render.RenderUtils
import net.ccbluex.liquidbounce.utils.render.RenderUtils.withOutline
import java.awt.Color
import kotlin.math.nextDown

Expand All @@ -26,9 +28,11 @@ class Keystrokes : Element("Keystrokes", 2.0, 34.0) {
private val renderBorder by boolean("RenderBorder", false)
private val borderColors = ColorSettingsInteger(this, "Border") { renderBorder }.with(Color.BLUE)
private val borderWidth by float("BorderWidth", 1.5F, 0.5F..5F) { renderBorder }
private val shrinkOnPress by boolean("ShrinkOnPress", true)
private val shrinkPercentage by int("ShrinkPercentage", 90, 50..100, suffix = "%") { shrinkOnPress }
private val shrinkSpeed by int("ShrinkSpeed", 2, 0..5, suffix = "Ticks") { shrinkOnPress }
private val onPressAnimation by choices(
"OnPressAnimationMode", arrayOf("None", "Shrink", "Fill", "ReverseFill"), "Shrink"
)
private val shrinkPercentage by int("ShrinkPercentage", 90, 50..100, suffix = "%") { onPressAnimation == "Shrink" }
private val shrinkSpeed by int("ShrinkSpeed", 2, 0..5, suffix = "Ticks") { onPressAnimation == "Shrink" }

private var shadow by boolean("Text-Shadow", true)
private val font by font("Font", Fonts.fontSemibold35)
Expand All @@ -45,32 +49,33 @@ class Keystrokes : Element("Keystrokes", 2.0, 34.0) {
private val borderColor
get() = borderColors.color()

private val nonFillModes = arrayOf("None", "Shrink")

data class GridKey(
val row: Int,
val column: Int,
val text: String,
var scale: Float = 1f,
val keystrokes: Keystrokes,
var color: Color = keystrokes.rectColor
var color: Color = keystrokes.rectColor,
var normalT: Float = 0F
) {
fun updateState(isPressed: Boolean) {
val min = (keystrokes.shrinkPercentage / 100f).nextDown()
val targetScale = if (isPressed && keystrokes.shrinkOnPress) min else 1f
val targetScale = if (isPressed && keystrokes.onPressAnimation in keystrokes.nonFillModes) min else 1f
val deltaTime = RenderUtils.deltaTimeNormalized(keystrokes.shrinkSpeed).takeIf { it != 0.0 } ?: 1F

normalT = (normalT..if (isPressed) 0f else 1f).lerpWith(RenderUtils.deltaTimeNormalized())

scale = (scale..targetScale).lerpWith(deltaTime)

val t = 1f - (scale - min safeDiv 1f - min)

val baseColor = keystrokes.rectColor
val targetColor = keystrokes.pressColor

val r = (baseColor.red + (targetColor.red - baseColor.red) * t).toInt()
val g = (baseColor.green + (targetColor.green - baseColor.green) * t).toInt()
val b = (baseColor.blue + (targetColor.blue - baseColor.blue) * t).toInt()
val a = (baseColor.alpha + (targetColor.alpha - baseColor.alpha) * t).toInt()

color = Color(r, g, b, a)
color = if (keystrokes.onPressAnimation !in keystrokes.nonFillModes) {
keystrokes.rectColor
} else {
ColorUtils.interpolateColor(keystrokes.rectColor, keystrokes.pressColor, t)
}
}
}

Expand All @@ -81,7 +86,7 @@ class Keystrokes : Element("Keystrokes", 2.0, 34.0) {
private val gridLayout = arrayOf(
GridKey(1, 1, "W", keystrokes = this),
GridKey(2, 0, "A", keystrokes = this),
GridKey(2, 1, "S", keystrokes = this),
GridKey(2, 1, "S", keystrokes = this),
GridKey(2, 2, "D", keystrokes = this),
GridKey(3, 1, "Space", keystrokes = this)
)
Expand Down Expand Up @@ -118,7 +123,7 @@ class Keystrokes : Element("Keystrokes", 2.0, 34.0) {
val isPressed = movementKeys[key]?.isKeyDown == true
gridKey.updateState(isPressed)

val scaledBoxSize = boxSize * scale
val scaledBoxSize = boxSize * if (onPressAnimation == "None") 1f else scale
val scaledPadding = (boxSize - scaledBoxSize) / 2

val adjustedStartX = startX + scaledPadding
Expand All @@ -129,6 +134,37 @@ class Keystrokes : Element("Keystrokes", 2.0, 34.0) {
adjustedStartX, adjustedY, adjustedEndX, adjustedY + scaledBoxSize, color.rgb, radius
)

if (onPressAnimation !in nonFillModes) {
val reverse = onPressAnimation != "Fill"

withOutline(main = {
val size = boxSize * gridKey.normalT.let { if (!reverse) 1 - it else it }
val padding1 = (boxSize - size) / 2

val adjustedStartX1 = startX + padding1
val adjustedEndX1 = endX - padding1
val adjustedY1 = currentY + padding1

RenderUtils.drawRoundedRect(
adjustedStartX1,
adjustedY1,
adjustedEndX1,
adjustedY1 + size,
if (reverse) 0 else pressColor.rgb,
radius
)
}, toOutline = {
RenderUtils.drawRoundedRect(
adjustedStartX,
adjustedY,
adjustedEndX,
adjustedY + scaledBoxSize,
if (reverse) pressColor.rgb else 0,
radius
)
})
}

if (renderBorder) {
RenderUtils.drawRoundedBorder(
adjustedStartX,
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/net/ccbluex/liquidbounce/utils/render/RenderUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,31 @@ object RenderUtils : MinecraftInstance {
glPopMatrix()
}

inline fun withOutline(main: () -> Unit, toOutline: () -> Unit) {
disableFastRender()
OutlineUtils.checkSetupFBO()
glPushMatrix()
glDisable(GL_ALPHA_TEST)
glEnable(GL_STENCIL_TEST)
glClear(GL_STENCIL_BUFFER_BIT)

glStencilFunc(GL_ALWAYS, 1, 1)
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE)
glStencilMask(1)

main()

glStencilFunc(GL_EQUAL, 0, 1)
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)
glStencilMask(0)

toOutline()

glStencilMask(0xFF)
glDisable(GL_STENCIL_TEST)
glEnable(GL_ALPHA_TEST)
glPopMatrix()
}

fun deltaTimeNormalized(ticks: Int = 1) = (deltaTime safeDivD ticks * 50.0).coerceAtMost(1.0)

Expand Down

0 comments on commit d4bf9a5

Please sign in to comment.