Author Topic: Tweening/Easing Library  (Read 1573 times)

Offline bigsofty

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 2448
    • View Profile
Tweening/Easing Library
« on: 2014-Oct-29 »
Here is an Easing library, handy for motion, animation etc.

1st a quick example:

Code: GLBasic [Select]
        // --------------------------------- //
        SETSCREEN 1024,768,FALSE
        TweenInit()

        LOCAL tween AS TTween
        LOCAL endtime = GETTIMERALL()+5000
        LOCAL time

        WHILE time < endtime

                time = GETTIMERALL()

                LOCAL x#=tween.Call(LINEAR_TWEEN, time, 512, 502, endtime)
                LOCAL y#=tween.Call(EASE_OUT_BOUNCE, time, 0, 758 , endtime)

                DRAWRECT x#,y#,10,10,0xffffffff

                SHOWSCREEN
        WEND
        END

Add the Tweening lib to your project, call "TweenInit()" and your good to go.

Each tween is a type and it has 3 fields, "Power", "Amplitude" and "Bounce". You can set these ("tween.Amplitude=2.0") and it will have an effect on the relative tween algorithm.

Cheers,


Ian


P.S. Look at the list of tween constants at the top of the library file to select a specific tween algorithm for tween.Call().

Code: GLBasic [Select]
// --------------------------------- //
// Project: tween
// Start: Saturday, October 18, 2014
// IDE Version: 12.308
// Bigsofty aka Ian Thompson


INLINE
/*
---------------------------------------------------------------------------
Disclaimer FOR Robert Penner's Easing Equations license:

TERMS OF USE - EASING EQUATIONS

Open source under the BSD License.

Copyright ? 2001 Robert Penner
Monkey version by Shinriko
All rights reserved.

Redistribution AND use IN source AND binary forms, with OR without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list of conditions AND the following disclaimer.
* Redistributions IN binary form must reproduce the above copyright notice,
this list of conditions AND the following disclaimer IN the documentation AND/OR other materials provided with the distribution.
* Neither the name of the author nor the names of contributors may be used TO endorse OR
promote products derived from this software without specific prior written permission.

this SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF this SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

---------------------------------------------------------------------------
FOR all easing functions:
t = elapsed time
b = begin
c = change = ending - beginning
d = duration (total time)
---------------------------------------------------------------------------
*/

ENDINLINE


INLINE
/*

---------------------------------------------------------------------------

        CALLBACK API built on top of Robert Penners Functions

        Simply call Tweening() function every Update()

        - TYPE: one of the constantants below (LINEAR_TWEEN, EASE_IN_QUAD, ...)
        - Returns: A float value which represents the current progress

---------------------------------------------------------------------------
*/

ENDINLINE

CONSTANT PI#=3.14159265

PROTOTYPE TweenProto#: t#, b#, c#, d#, tw AS TTween

GLOBAL TweenArray[] AS TweenProto

CONSTANT LINEAR_TWEEN%  = 0

CONSTANT EASE_IN_QUAD%  = 1
CONSTANT EASE_OUT_QUAD%  = 2
CONSTANT EASE_IN_OUT_QUAD%  = 3

CONSTANT EASE_IN_CUBIC%  = 4
CONSTANT EASE_OUT_CUBIC%  = 5
CONSTANT EASE_IN_OUT_CUBIC%  = 6

CONSTANT EASE_IN_QUART%  = 7
CONSTANT EASE_OUT_QUART%  = 8
CONSTANT EASE_IN_OUT_QUART%  = 9

CONSTANT EASE_IN_QUINT%  = 10
CONSTANT EASE_OUT_QUINT%  = 11
CONSTANT EASE_IN_OUT_QUINT%  = 12

CONSTANT EASE_IN_SINE%  = 13
CONSTANT EASE_OUT_SINE%  = 14
CONSTANT EASE_IN_OUT_SINE%  = 15

CONSTANT EASE_IN_EXPO%  = 16
CONSTANT EASE_OUT_EXPO%  = 17
CONSTANT EASE_IN_OUT_EXPO%  = 18

CONSTANT EASE_IN_CIRC%  = 19
CONSTANT EASE_OUT_CIRC%  = 20
CONSTANT EASE_IN_OUT_CIRC%  = 21

CONSTANT EASE_IN_BACK%  = 22
CONSTANT EASE_OUT_BACK%  = 23
CONSTANT EASE_IN_OUT_BACK%  = 24

CONSTANT EASE_IN_BOUNCE%  = 25
CONSTANT EASE_OUT_BOUNCE%  = 26
CONSTANT EASE_IN_OUT_BOUNCE% = 27

CONSTANT EASE_IN_ELASTIC%  = 28
CONSTANT EASE_OUT_ELASTIC%  = 29
CONSTANT EASE_IN_OUT_ELASTIC% = 30


//--------------------------------------------------------------------------


        //--------------------------------------------------------------------------
        // * Linear
        //--------------------------------------------------------------------------
        FUNCTION LinearTween#:t#, b#, c#, d#, tw AS TTween
                        RETURN c*t/d + b
        ENDFUNCTION



        //--------------------------------------------------------------------------
        // * Quad
        //--------------------------------------------------------------------------
        FUNCTION EaseInQuad#:t#, b#, c#, d#, tw AS TTween
                        t = t / d
                        RETURN c*t*t + b
        ENDFUNCTION

        FUNCTION EaseOutQuad#:t#, b#, c#, d#, tw AS TTween
                        t = t / d
                        RETURN -c * t*(t-2) + b
        ENDFUNCTION

        FUNCTION EaseInOutQuad#:t#, b#, c#, d#, tw AS TTween
                        t = t / (d/2)
                        IF (t < 1) THEN RETURN c/2*t*t + b
                        t = t - 1
                        RETURN -c/2 * (t*(t-2) - 1) + b
        ENDFUNCTION



        //--------------------------------------------------------------------------
        // * Cubic
        //--------------------------------------------------------------------------
        FUNCTION EaseInCubic#:t#, b#, c#, d#, tw AS TTween
                        t = t / d
                        RETURN c*t*t*t + b
        ENDFUNCTION

        FUNCTION EaseOutCubic#:t#, b#, c#, d#, tw AS TTween
                        t = t / d
                        t = t - 1
                        RETURN c*(t*t*t + 1) + b
        ENDFUNCTION

        FUNCTION EaseInOutCubic#:t#, b#, c#, d#, tw AS TTween
                        t = t / (d/2)
                        IF (t < 1) THEN RETURN c/2*t*t*t + b
                        t = t - 2
                        RETURN c/2*(t*t*t + 2) + b
        ENDFUNCTION


        //--------------------------------------------------------------------------
        // * Quart
        //--------------------------------------------------------------------------
        FUNCTION EaseInQuart#:t#, b#, c#, d#, tw AS TTween
                        t = t / d
                        RETURN c*t*t*t*t + b
        ENDFUNCTION

        FUNCTION EaseOutQuart#:t#, b#, c#, d#, tw AS TTween
                        t = t / d
                        t = t - 1
                        RETURN -c * (t*t*t*t - 1) + b
        ENDFUNCTION

        FUNCTION EaseInOutQuart#:t#, b#, c#, d#, tw AS TTween
                        t = t / (d/2)
                        IF (t < 1) THEN RETURN c/2*t*t*t*t + b
                        t = t - 2
                        RETURN -c/2 * (t*t*t*t - 2) + b
        ENDFUNCTION



        //--------------------------------------------------------------------------
        // * Quintic
        //--------------------------------------------------------------------------
        FUNCTION EaseInQuint#:t#, b#, c#, d#, tw AS TTween
                        t = t / d
                        RETURN c*t*t*t*t*t + b
        ENDFUNCTION

        FUNCTION EaseOutQuint#:t#, b#, c#, d#, tw AS TTween
                        t = t / d
                        t = t - 1
                        RETURN c*(t*t*t*t*t + 1) + b
        ENDFUNCTION

        FUNCTION EaseInOutQuint#:t#, b#, c#, d#, tw AS TTween
                        t = t / (d/2)
                        IF (t < 1)
                                RETURN c/2*t*t*t*t*t + b
                        ENDIF
                        t = t - 2
                        RETURN c/2*(t*t*t*t*t + 2) + b
        ENDFUNCTION



        //--------------------------------------------------------------------------
        // * Sinus
        //--------------------------------------------------------------------------
        FUNCTION EaseInSine#:t#, b#, c#, d#, tw AS TTween
                        RETURN -c * COS((t/d * (PI/2)) * 57.2957795) + c + b
        ENDFUNCTION

        FUNCTION EaseOutSine#:t#, b#, c#, d#, tw AS TTween
                        RETURN c * SIN((t/d * (PI/2)) * 57.2957795) + b
        ENDFUNCTION

        FUNCTION EaseInOutSine#:t#, b#, c#, d#, tw AS TTween
                        RETURN -c/2 * (COS((PI*t/d) * 57.2957795) - 1) + b
        ENDFUNCTION



        //--------------------------------------------------------------------------
        // * Exponential
        //--------------------------------------------------------------------------
        FUNCTION EaseInExpo#:t#, b#, c#, d#, tw AS TTween
                        RETURN c * POW( 2, 10 * (t/d - 1) ) + b
        ENDFUNCTION

        FUNCTION EaseOutExpo#:t#, b#, c#, d#, tw AS TTween
                        RETURN c * ( -POW( 2, -10 * t/d ) + 1 ) + b
        ENDFUNCTION

        FUNCTION EaseInOutExpo#:t#, b#, c#, d#, tw AS TTween
                        t = t / (d/2)
                        IF (t < 1)
                                RETURN c/2 * POW( 2, 10 * (t - 1) ) + b
                        ENDIF
                        t = t - 1
                        RETURN c/2 * ( -POW( 2, -10 * t) + 2 ) + b
        ENDFUNCTION



        //--------------------------------------------------------------------------
        // * Circ
        //--------------------------------------------------------------------------
        FUNCTION EaseInCirc#:t#, b#, c#, d#, tw AS TTween
                        t = t / d
                        RETURN -c * (SQR(1 - t*t) - 1) + b
        ENDFUNCTION

        FUNCTION EaseOutCirc#:t#, b#, c#, d#, tw AS TTween
                        t = t / d
                        t = t - 1
                        RETURN c * SQR(1 - t*t) + b
        ENDFUNCTION

        FUNCTION EaseInOutCirc#:t#, b#, c#, d#, tw AS TTween
                        t = t / (d/2)
                        IF (t < 1)
                                RETURN -c/2 * (SQR(1 - t*t) - 1) + b
                        ENDIF
                        t = t - 2
                        RETURN c/2 * (SQR(1 - t*t) + 1) + b
        ENDFUNCTION



        //--------------------------------------------------------------------------
        // * Back
        //--------------------------------------------------------------------------
        FUNCTION EaseInBack#:t#, b#, c#, d#, tw AS TTween
                        t = t / d
                        RETURN c * t * t * ((tw.Bounce + 1) * t - tw.Bounce) + b
        ENDFUNCTION

        FUNCTION EaseOutBack#:t#, b#, c#, d#, tw AS TTween
                        t = t / d - 1
                        RETURN c * (t * t * ((tw.Bounce + 1) * t + tw.Bounce) + 1) + b
        ENDFUNCTION

        FUNCTION EaseInOutBack#:t#, b#, c#, d#, tw AS TTween
                        t = t / (d / 2)
                        IF ((t) < 1)
                                tw.Bounce=tw.Bounce*1.525+1
                                RETURN c/2*(t*t*(tw.Bounce*t - tw.Bounce)) + b
                        ENDIF
                        t = t -2
                        tw.Bounce=tw.Bounce*1.525+1
                        RETURN c/2*(t*t*(tw.Bounce*t + tw.Bounce) + 2) + b
        ENDFUNCTION



        //--------------------------------------------------------------------------
        // * Bounce
        //--------------------------------------------------------------------------
        FUNCTION EaseInBounce#:t#, b#, c#, d#, tw AS TTween
                        RETURN c - EaseOutBounce(d - t, 0, c, d, tw) + b
        ENDFUNCTION

        FUNCTION EaseOutBounce#:t#, b#, c#, d#, tw AS TTween
                        t = t / d
                        IF (t < (1 / 2.75))
                                RETURN c * (7.5625 * t * t) + b
                        ELSEIF (t < (2 / 2.75))
                                t = t - (1.5 / 2.75)
                                RETURN c * (7.5625 * t * t + .75) + b
                        ELSEIF (t < (2.5 / 2.75))
                                t = t - (2.25 / 2.75)
                                RETURN c * (7.5625 * t  * t + .9375) + b
                        ENDIF
                        t = t - (2.625 / 2.75)
                        RETURN c * (7.5625 * t * t + .984375) + b
        ENDFUNCTION

        FUNCTION EaseInOutBounce#:t#, b#, c#, d#, tw AS TTween
                        IF (t < d/2)
                                RETURN EaseInBounce(t*2, 0, c, d, tw) * .5 + b
                        ENDIF
                        RETURN EaseOutBounce(t*2-d, 0, c, d, tw) * .5 + c*.5 + b
        ENDFUNCTION



        //--------------------------------------------------------------------------
        // * Elastic
        //--------------------------------------------------------------------------
        FUNCTION EaseInElastic#:t#, b#, c#, d#, tw AS TTween
                        LOCAL s#
                        IF (t = 0)
                                RETURN b
                        ENDIF
                        t = t / d
                        IF (t = 1)
                                RETURN b+c
                        ENDIF

                        IF (NOT tw.Power)
                                tw.Power = d * .3
                        ENDIF
                        IF (NOT tw.Amplitude) OR tw.Amplitude < ABS(c)
                                tw.Amplitude = c
                                s = tw.Power/4
                        ELSE
                                s = tw.Power/(2*PI) * ASIN(c/tw.Amplitude)
                        ENDIF
                        t = t -1
                        RETURN -(tw.Amplitude*POW(2,10*(t)) * SIN((t*d-s)*(2*PI)/tw.Power)) + b
        ENDFUNCTION

        FUNCTION EaseOutElastic#:t#, b#, c#, d#, tw AS TTween
                        LOCAL s#
                        IF (t = 0)
                                RETURN b
                        ENDIF
                        t = t / d
                        IF (t = 1)
                                RETURN b+c
                        ENDIF

                        IF (NOT tw.Power)
                                tw.Power = d * .3
                        ENDIF
                        IF (NOT tw.Amplitude) OR tw.Amplitude < ABS(c)
                                tw.Amplitude = c
                                s = tw.Power/4
                        ELSE
                                s = tw.Power/(2*PI) * ASIN(c/tw.Amplitude)
                        ENDIF
                        RETURN (tw.Amplitude*POW(2,-10*t) * SIN((t*d-s)*(2*PI)/tw.Power)+c+b)
        ENDFUNCTION

        FUNCTION EaseInOutElastic#:t#, b#, c#, d#, tw AS TTween
                        LOCAL s#
                        IF (t = 0)
                                RETURN b
                        ENDIF
                        t = t / (d / 2)
                        IF (t = 2)
                                RETURN b+c
                        ENDIF

                        IF (NOT tw.Power)
                                tw.Power = d * 0.3 * 1.5
                        ENDIF
                        IF (NOT tw.Amplitude) OR tw.Amplitude < ABS(c)
                                tw.Amplitude = c
                                s = tw.Power/4
                        ELSE
                                s = tw.Power/(2*PI) * ASIN(c/tw.Amplitude)
                        ENDIF

                        IF (t < 1)
                                t = t - 1
                                RETURN -0.5*(tw.Amplitude*POW(2,10*(t)) * SIN((t*d-s)*(2*PI)/tw.Power)) + b
                        ENDIF

                        t = t - 1
                        RETURN (tw.Amplitude*POW(2,-10*t) * SIN((t*d-s)*(2*PI)/tw.Power)*0.5 +c+b)
        ENDFUNCTION


        FUNCTION TweenInit:
                DIM TweenArray[31]

                TweenArray[LINEAR_TWEEN] = LinearTween

                TweenArray[EASE_IN_QUAD] = EaseInQuad
                TweenArray[EASE_OUT_QUAD] = EaseOutQuad
                TweenArray[EASE_IN_OUT_QUAD] = EaseInOutQuad

                TweenArray[EASE_IN_CUBIC] = EaseInCubic
                TweenArray[EASE_OUT_CUBIC] = EaseOutCubic
                TweenArray[EASE_IN_OUT_CUBIC] = EaseInOutCubic

                TweenArray[EASE_IN_QUART] = EaseInQuart
                TweenArray[EASE_OUT_QUART] = EaseOutQuart
                TweenArray[EASE_IN_OUT_QUART] = EaseInOutQuart

                TweenArray[EASE_IN_QUINT] = EaseInQuint
                TweenArray[EASE_OUT_QUINT] = EaseOutQuint
                TweenArray[EASE_IN_OUT_QUINT] = EaseInOutQuint

                TweenArray[EASE_IN_SINE] = EaseInSine
                TweenArray[EASE_OUT_SINE] = EaseOutSine
                TweenArray[EASE_IN_OUT_SINE] = EaseInOutSine

                TweenArray[EASE_IN_EXPO] = EaseInExpo
                TweenArray[EASE_OUT_EXPO] = EaseOutExpo
                TweenArray[EASE_IN_OUT_EXPO] = EaseInOutExpo

                TweenArray[EASE_IN_CIRC] = EaseInCirc
                TweenArray[EASE_OUT_CIRC] = EaseOutCirc
                TweenArray[EASE_IN_OUT_CIRC] = EaseInOutCirc

                TweenArray[EASE_IN_BACK] = EaseInBack
                TweenArray[EASE_OUT_BACK] = EaseOutBack
                TweenArray[EASE_IN_OUT_BACK] = EaseInOutBack

                TweenArray[EASE_IN_BOUNCE] = EaseInBounce
                TweenArray[EASE_OUT_BOUNCE] = EaseOutBounce
                TweenArray[EASE_IN_OUT_BOUNCE] = EaseInOutBounce

                TweenArray[EASE_IN_ELASTIC] = EaseInElastic
                TweenArray[EASE_OUT_ELASTIC] = EaseOutElastic
                TweenArray[EASE_IN_OUT_ELASTIC] = EaseInOutElastic

        ENDFUNCTION

TYPE TTween

        Bounce# = 1.70158
        Power# = 1
        Amplitude# = 1

        FUNCTION Call#: tw%, t#, b#, c#, d#
                ALIAS tween AS TweenArray[tw%]
                RETURN tween(t#, b#, c#, d#, self)
        ENDFUNCTION

ENDTYPE
Cheers,

Ian.

“It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration.”
(E. W. Dijkstra)

Offline erico

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 4017
    • View Profile
    • Portfolio
Re: Tweening/Easing Library
« Reply #1 on: 2014-Nov-09 »
I so far hard coded all my easy in-out.

Interesting to think that this exact action can be pushed into a lib.
Thanks for the code :good: I will check it out.

Offline mentalthink

  • Prof. Inline
  • *****
  • Posts: 3317
  • Integrated Brain
    • View Profile
Re: Tweening/Easing Library
« Reply #2 on: 2014-Nov-09 »
Thanks Ian sure this will be very interesting, I rebembe I put a link make some years ago, about something similar, and like a lot of people... Now all the work it's done... Thanks a lot, this it's really interesting, and more when you come new to programming and don't have practically nothing of Maths,
 :nw:

Offline bigsofty

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 2448
    • View Profile
Re: Tweening/Easing Library
« Reply #3 on: 2014-Nov-09 »
Your welcome guys, drop a line here if you have any problems with it.  ;)
Cheers,

Ian.

“It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration.”
(E. W. Dijkstra)