Animation for yall

As always, pros do better, but beginners may find it useful
Add a new kt file to your project and copy following code to it



fun backEaseInOut(e: Float, t: Float=0f, n: Float=100f, r: Float=100f):Float {

    if (e < r / 2) return backEaseIn(e * 2f, 0f, n, r) * 0.5f + t;
    else return backEaseOut(e * 2f - r, 0f, n, r) * 0.5f + n * 0.5f + t

}
fun backEaseOut(e: Float, t: Float=0f, n: Float=100f, r: Float=100f):Float {
    return 100-backEaseIn(100-e)

}
fun backEaseIn(e: Float, t: Float=0f, n: Float=100f, r: Float=100f):Float {
    var i = 1.70158f
    var de=e/r
    return (n * de * de * ((i + 1) * de - i) + t)

}
fun EaseInOut(e: Float, t: Float=0f, n: Float=100f, r: Float=100f):Float {

    if (e < r / 2) return EaseIn(e * 2f, 0f, n, r) * 0.5f + t;
    else return EaseOut(e * 2f - r, 0f, n, r) * 0.5f + n * 0.5f + t

}
fun EaseOut(e: Float, t: Float=0f, n: Float=100f, r: Float=100f):Float {
    return 100-EaseIn(100-e)
}
fun EaseIn(e: Float, t: Float=0f, n: Float=100f, r: Float=100f):Float {
    return n * e / r + t
}
fun  strongEaseInOut(de: Float, t: Float=0f, n: Float=100f, r: Float=100f):Float {
    var e=de
    if (e < r / 2) return strongEaseIn(e * 2f, 0f, n, r) * 0.5f + t;
    else return strongEaseOut(e * 2f - r, 0f, n, r) * 0.5f + n * 0.5f + t

}
fun strongEaseOut(e: Float, t: Float=0f, n: Float=100f, r: Float=100f):Float {
    if(e>99){return 100f}
    var de=e/r

    return 100-strongEaseIn(100-e)
}
fun strongEaseIn(e: Float, t: Float=0f, n: Float=100f, r: Float=100f):Float {
    var de=e
    de /= r
    return (n * de * e * e * e * e + t)/100000000
}

fun  regularEaseInOut(de: Float, t: Float=0f, n: Float=100f, r: Float=100f):Float {
    var e=de
    if (e < r / 2) return regularEaseIn(e * 2f, 0f, n, r) * 0.5f + t;
    else return regularEaseOut(e * 2f - r, 0f, n, r) * 0.5f + n * 0.5f + t

}
fun  regularEaseOut(de: Float, t: Float=0f, n: Float=100f, r: Float=100f):Float {
    var e=de
    e /= r
    return (- n * de * (e - 2) + t)/100
}
fun regularEaseIn(de: Float, t: Float=0f, n: Float=100f, r: Float=100f):Float {
    var e=de
    e /= r
    return (n * e * de + t)/100
}

fun elasticIn(dt: Float): Float {
    if(dt>99){return 100f}
    var t=dt
    t /= 100
    if (t == 0f || t == 1f) return t
    val pi2 = Math.PI * 2
    val s = .3 / pi2 * Math.asin(1.0)
    val o = t - 1f
    return -(1 * Math.pow(2.0, 10.0 * o) * Math.sin((o - s) * pi2 / .3)).toFloat()*100
}
fun elasticOut(dt: Float): Float {
    if(dt>99){return 100f}
    var t=dt
    t /= 100
    if (t == 0f || t == 1f) return t
    val pi2 = Math.PI * 2
    val s = .3 / pi2 * Math.asin(1.0)
    return (Math.pow(2.0, (-10 * t).toDouble()) * Math.sin((t - s) * pi2 / .3) + 1).toFloat()*100

}
fun elasticEaseInOut(dt:Float, e:Float=0f, n:Float=100f, r:Float=100f):Float {
    if(dt>99){return 100f}
    var t=dt
    t /= r
    val pi2 = Math.PI * 2
    val s = .45 / pi2 * Math.asin(1.0)
    var o = t * 2f
    return if (o < 1) {
        o -= 1f
        (-0.5f * (Math.pow(2.0, (10 * o).toDouble()) * Math.sin((o - s) * pi2 / .45))).toFloat()*100
    } else {
        o -= 1f
        (Math.pow(2.0, (-10 * o).toDouble()) * Math.sin((o - s) * pi2 / .45) * 0.5 + 1).toFloat()*100
    }
}
fun bounceEaseInOut(e:Float, t:Float=0f, n:Float=100f, r:Float=100f):Float {
    if (e < r / 2) return bounceEaseIn(e * 2f, 0f, n, r) * 0.5f + t;
    else return bounceEaseOut(e * 2f - r, 0f, n, r) * 0.5f + n * 0.5f + t
}
fun bounceEaseIn(e:Float, t:Float=0f, n:Float=100f, r:Float=100f):Float {
    return n - bounceEaseOut(r - e, 0f, n, r) + t
}
fun bounceEaseOut(dt:Float, b:Float=0f, c:Float=100f, d:Float=100f):Float {
    var t=dt
    t /= d
    if (t < (1/2.75f)) {
        return c*(7.5625f*t*t) + b
    } else if (t < (2/2.75f)) {
        var dt=t-(1.5f/2.75f)
        return c*(7.5625f*(dt)*dt + .75f) + b
    } else if (t < (2.5/2.75)) {
        var dt=t-(2.25f/2.75f)
        return c*(7.5625f*(dt)*dt + .9375f) + b
    } else {
        var dt=t-(2.625f/2.75f)
        return c*(7.5625f*(dt)*dt + .984375f) + b
    }
}
class AC (ele: View){
    var time: Long =800
    var x: Float? = null
    var y: Float? = null
    var rotation: Float? = null
    var rotationx: Float? = null
    var rotationy: Float? = null
    var element = ele
    var perc:Float?=null
    var onFinish:()->(Unit)?= { }
    var onAnimation:()->(Unit)?= { }

}
fun prepareAnimation(ob: AC,el: Any) : MutableList<Any>{
    var back:MutableList<Any> = mutableListOf()
    var type : String ="NULL"
    var start : Float? = null
    var end : Float? = null
    var o=el
    if (ob.x != null) {
        type="X"
        start=ob.element.x
        end = ob.x
        back.add("$type|$start|$end")
    }
    if (ob.y != null) {
        type="Y"
        start=ob.element.y
        end = ob.y
        back.add("$type|$start|$end")
    }
    if (ob.rotation != null) {
        type="rotation"
        start=ob.element.rotation
        end = ob.rotation
        back.add("$type|$start|$end")
    }
    if (ob.rotationy != null) {
        type="rotationy"
        start=ob.element.rotationY
        end = ob.rotationy
        back.add("$type|$start|$end")
    }
    if (ob.rotationx != null) {
        type="rotationx"
        start=ob.element.rotationX
        end = ob.rotationx
        back.add("$type|$start|$end")
    }
    return back
}
fun valback(e:Float, t:Float, n:Float = 0f):Float {
    var r =e
    var i = t
    var s = abs(i - r)
    var o = (s / 100 * n)

    if (r > i) {
        return (r - o)
    } else {
        return (r + o)
    }

}
fun <T :Any> T.CLICK(function:()->(Unit)):T{
    var ob = this as View
    ob.setOnClickListener{
        function()
    }
    return this
}
fun <T : Any> T.jmation(function:(ob:AC)->(Unit),ease: (Float)->(Float) = :: noEase): T {
    var ob:AC=AC(this as View)
    function(ob)
    mation(this, ob,ease)
    return this
}
fun positionSet(i: Any, ob: AC,aPz:Float){
    var s:String = i as String
    var arr = s.split("|").toTypedArray()
    var typ=arr[0]

    if(typ=="X") {
        var sx = arr[1].toFloat()
        var ex = arr[2].toFloat()
        var posX = valback(sx, ex, aPz)
        ob.element.x = posX
    }
    if(typ=="Y") {
        var sy = arr[1].toFloat()
        var ey = arr[2].toFloat()
        var posY = valback(sy, ey, aPz)
        ob.element.y = posY
    }
    if(typ=="rotation") {
        var sy = arr[1].toFloat()
        var ey = arr[2].toFloat()
        var posY = valback(sy, ey, aPz)
        ob.element.setRotation(posY)
    }
    if(typ=="rotationy") {
        var sy = arr[1].toFloat()
        var ey = arr[2].toFloat()
        var posY = valback(sy, ey, aPz)
        ob.element.setRotationY(posY)
    }
    if(typ=="rotationx") {
        var sy = arr[1].toFloat()
        var ey = arr[2].toFloat()
        var posY = valback(sy, ey, aPz)
        ob.element.setRotationX(posY)
    }
}
fun noEase(f:Float):Float{
    return f
}
fun mation(el: Any, ob: AC,ease: (Float)->(Float) = :: noEase) = GlobalScope.launch {
    var perc:Float =0F

    var timer:Long =(ob.time/100)
    var animation=prepareAnimation(ob,el)
    while(perc<101){
        var aPz=ease(perc)
        var rotation:Float=valback(0f,360f,aPz)
        ob.perc=perc

        for(i in animation){
            positionSet(i,ob,aPz)
        }
        ob.onAnimation()
        if(perc>=100){
            println("Durch")
            ob.perc=perc
            ob.onFinish()

            for(i in animation){
                positionSet(i,ob,100f)
            }
        }

        perc++
        delay(timer)
    }

}

How to use:
jmation can handle all types of Views (TextView, Editable, Buttons, ImageViews and so on.

To animate your View Element just use this

yourViewElement.jmation({
                    it.x = 900f //optional to animate it on X Axis to 900f
                    it.y = 800f //optional to animate it on Y Axis to 800f
                    it.time = 1800 //optional time in millisecconds, default is 800
                    it.rotationx = 180f //optional rotate on X Axis to 180f
                    it.rotationy = 180f //optional rotate on Y Axis to 180f
                    it.rotation = 180f //optional just rotate for 180F
                    it.onAnimation = { //optional If you want to do some more with while animation
                        println("Current percentage of animation " + it.perc)
                    }
                    it.onFinish = {//optional If you want to do something when animation has finished
                        println("Im done on " + it.perc)
                    }
                },::elasticEaseInOut) //parameter is optional. No parameter means no easing. Or add an function from above for easing as in this case elasticEaseInOut
            })

Another usefull functions included

valback(from float, to float, by percentage as float 0..100)

//returns the needed value between those arguments


yourElement.CLICK({//do something with it
})

//same as yourElement.setOnClickListener, but shorter and chainable

So yourElement.CLICK({/*whatever*/}).jmation(args) should work as well
1 Like