All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.teamwizardry.librarianlib.math.Easing.kt Maven / Gradle / Ivy

There is a newer version: 5.0.0-alpha.10
Show newest version
package com.teamwizardry.librarianlib.math

import net.minecraft.util.math.MathHelper
import kotlin.math.pow

/**
 * An easing function. Used to make more natural transitions.
 */
public interface Easing {
    /**
     * @param progress A progress value from 0-1
     * @return A float value for interpolation. This value **is not** guaranteed to be between 0 and 1. If your
     *           interpolation algorithm requires a 0-1 value you **must** clamp this to that range.
     */
    public fun ease(progress: Float): Float

    public val reversed: Easing
        get() = object: Easing {
            override fun ease(progress: Float): Float {
                return [email protected](1 - progress)
            }

            override val reversed: Easing
                get() = this@Easing
        }

    private abstract class PenningEasing: Easing {
        // variables used in the penning formulas
        val b = 0f
        val c = 1f
        val d = 1f
    }

    @Suppress("unused")
    public companion object {
        @JvmField
        public val linear: Easing = object: Easing {
            override fun ease(progress: Float): Float {
                return progress
            }
        }

        /** http://easings.net/#easeInSine */
        @JvmField
        public val easeInSine: Easing = BezierEasing(0.47, 0, 0.745, 0.715)

        /** http://easings.net/#easeOutSine */
        @JvmField
        public val easeOutSine: Easing = BezierEasing(0.39, 0.575, 0.565, 1)

        /** http://easings.net/#easeInOutSine */
        @JvmField
        public val easeInOutSine: Easing = BezierEasing(0.445, 0.05, 0.55, 0.95)

        /** http://easings.net/#easeInQuad */
        @JvmField
        public val easeInQuad: Easing = BezierEasing(0.55, 0.085, 0.68, 0.53)

        /** http://easings.net/#easeOutQuad */
        @JvmField
        public val easeOutQuad: Easing = BezierEasing(0.25, 0.46, 0.45, 0.94)

        /** http://easings.net/#easeInOutQuad */
        @JvmField
        public val easeInOutQuad: Easing = BezierEasing(0.455, 0.03, 0.515, 0.955)

        /** http://easings.net/#easeInCubic */
        @JvmField
        public val easeInCubic: Easing = BezierEasing(0.55, 0.055, 0.675, 0.19)

        /** http://easings.net/#easeOutCubic */
        @JvmField
        public val easeOutCubic: Easing = BezierEasing(0.215, 0.61, 0.355, 1)

        /** http://easings.net/#easeInOutCubic */
        @JvmField
        public val easeInOutCubic: Easing = BezierEasing(0.645, 0.045, 0.355, 1)

        /** http://easings.net/#easeInQuart */
        @JvmField
        public val easeInQuart: Easing = BezierEasing(0.895, 0.03, 0.685, 0.22)

        /** http://easings.net/#easeOutQuart */
        @JvmField
        public val easeOutQuart: Easing = BezierEasing(0.165, 0.84, 0.44, 1)

        /** http://easings.net/#easeInOutQuart */
        @JvmField
        public val easeInOutQuart: Easing = BezierEasing(0.77, 0, 0.175, 1)

        /** http://easings.net/#easeInQuint */
        @JvmField
        public val easeInQuint: Easing = BezierEasing(0.755, 0.05, 0.855, 0.06)

        /** http://easings.net/#easeOutQuint */
        @JvmField
        public val easeOutQuint: Easing = BezierEasing(0.23, 1, 0.32, 1)

        /** http://easings.net/#easeInOutQuint */
        @JvmField
        public val easeInOutQuint: Easing = BezierEasing(0.86, 0, 0.07, 1)

        /** http://easings.net/#easeInExpo */
        @JvmField
        public val easeInExpo: Easing = BezierEasing(0.95, 0.05, 0.795, 0.035)

        /** http://easings.net/#easeOutExpo */
        @JvmField
        public val easeOutExpo: Easing = BezierEasing(0.19, 1, 0.22, 1)

        /** http://easings.net/#easeInOutExpo */
        @JvmField
        public val easeInOutExpo: Easing = BezierEasing(1, 0, 0, 1)

        /** http://easings.net/#easeInCirc */
        @JvmField
        public val easeInCirc: Easing = BezierEasing(0.6, 0.04, 0.98, 0.335)

        /** http://easings.net/#easeOutCirc */
        @JvmField
        public val easeOutCirc: Easing = BezierEasing(0.075, 0.82, 0.165, 1)

        /** http://easings.net/#easeInOutCirc */
        @JvmField
        public val easeInOutCirc: Easing = BezierEasing(0.785, 0.135, 0.15, 0.86)

        /** http://easings.net/#easeInBack */
        @JvmField
        public val easeInBack: Easing = BezierEasing(0.6, -0.28, 0.735, 0.045)

        /** http://easings.net/#easeOutBack */
        @JvmField
        public val easeOutBack: Easing = BezierEasing(0.175, 0.885, 0.32, 1.275)

        /** http://easings.net/#easeInOutBack */
        @JvmField
        public val easeInOutBack: Easing = BezierEasing(0.68, -0.55, 0.265, 1.55)

        /** http://easings.net/#easeInElastic */
        @JvmField
        public val easeInElastic: Easing = object: PenningEasing() {
            override fun ease(progress: Float): Float {
                var t = progress / d
                if (t == 0f) return b
                if (t == 1f) return b + c
                val p = d * .3f
                val a = c
                val s = p / 4
                t -= 1
                return -(a * 2.0.pow((10 * t).toDouble()).toFloat() * MathHelper.sin((t * d - s) * (2 * Math.PI.toFloat()) / p)) + b
            }
        }

        /** http://easings.net/#easeOutElastic */
        @JvmField
        public val easeOutElastic: Easing = object: PenningEasing() {
            override fun ease(progress: Float): Float {
                val t = progress / d
                if (t == 0f) return b
                if (t == 1f) return b + c
                val p = d * .3f
                val a = c
                val s = p / 4
                return a * 2.0.pow((-10 * t).toDouble()).toFloat() * MathHelper.sin((t * d - s) * (2 * Math.PI.toFloat()) / p) + c + b
            }
        }

        /** http://easings.net/#easeInOutElastic */
        @JvmField
        public val easeInOutElastic: Easing = object: PenningEasing() {
            override fun ease(progress: Float): Float {
                var t = progress / (d / 2)
                if (t == 0f) return b
                if (t == 2f) return b + c
                val p = d * (.3f * 1.5f)
                val a = c
                val s = p / 4
                t -= 1
                if (t < 1) return -.5f * (a * 2.0.pow((10 * t).toDouble()).toFloat() * MathHelper.sin((t * d - s) * (2 * Math.PI.toFloat()) / p)) + b
                t -= 1
                return a * 2.0.pow((-10 * t).toDouble()).toFloat() * MathHelper.sin((t * d - s) * (2 * Math.PI.toFloat()) / p) * .5f + c + b
            }
        }

        /** http://easings.net/#easeInBounce */
        @JvmField
        public val easeInBounce: Easing = object: PenningEasing() {
            @Suppress("RemoveRedundantQualifierName") // Without the `Easing.` the compiler wigs out
            override fun ease(progress: Float): Float {
                val t = progress / d
                return c - Easing.easeOutBounce.ease(d - t) + b
            }
        }

        /** http://easings.net/#easeOutBounce */
        @JvmField
        public val easeOutBounce: Easing = object: PenningEasing() {
            override fun ease(progress: Float): Float {
                var t = progress / d
                if (t < (1 / 2.75f)) {
                    return c * (7.5625f * t * t) + b
                } else if (t < (2 / 2.75f)) {
                    t -= (1.5f / 2.75f)
                    return c * (7.5625f * t * t + .75f) + b
                } else if (t < (2.5 / 2.75)) {
                    t -= (2.25f / 2.75f)
                    return c * (7.5625f * t * t + .9375f) + b
                } else {
                    t -= (2.625f / 2.75f)
                    return c * (7.5625f * t * t + .984375f) + b
                }
            }
        }

        /** http://easings.net/#easeInOutBounce */
        @JvmField
        public val easeInOutBounce: Easing = object: PenningEasing() {
            @Suppress("RemoveRedundantQualifierName") // Without the `Easing.` the compiler wigs out
            override fun ease(progress: Float): Float {
                val t = progress
                return if (t < d / 2) Easing.easeInBounce.ease(t * 2) * .5f + b
                else Easing.easeOutBounce.ease(t * 2 - d) * .5f + c * .5f + b
            }
        }

        /**
         * Creates an easing for a basic linear fade in, hold, fade out progression. Proportionally the easing will
         * linearly fade from 0 to 1 over [fadeIn] units of time, hold 1 for [hold] units of time, then linearly
         * fade out over [fadeOut] units of time.
         */
        @JvmStatic
        public fun easeInOutLinear(fadeIn: Float, hold: Float, fadeOut: Float): Easing = easeInOut(fadeIn, hold, fadeOut, linear, linear)

        /**
         * Creates an easing for a fade in, hold, fade out progression. Proportionally the easing will go through
         * [fadeInEasing] over [fadeIn] units of time, hold 1 for [hold] units of time, then go through [fadeOutEasing]
         * over [fadeOut] units of time (`fadeOutEasing` is inverted so it goes from 1 to 0).
         */
        @JvmStatic
        public fun easeInOut(fadeIn: Float, hold: Float, fadeOut: Float, fadeInEasing: Easing, fadeOutEasing: Easing): Easing {
            val totalUnits = fadeIn + hold + fadeOut
            val fadeInFraction = fadeIn / totalUnits
            val holdFraction = hold / totalUnits
            val fadeOutStart = fadeInFraction + holdFraction
            val fadeOutFraction = fadeOut / totalUnits

            return object: Easing {
                override fun ease(progress: Float): Float {
                    return when (progress) {
                        in 0f..fadeInFraction -> fadeInEasing.ease(progress / fadeInFraction)
                        in fadeInFraction..fadeOutStart -> 1f
                        in fadeOutStart..1f -> 1f - fadeOutEasing.ease((progress - fadeOutStart) / fadeOutFraction)
                        else -> 0f
                    }
                }
            }
        }

        @JvmStatic
        public fun compound(initialValue: Float): CompoundEasingBuilder {
            return CompoundEasingBuilder(initialValue)
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy