GLBasic forum

Codesnippets => Math => Topic started by: bigsofty on 2014-Oct-29

Title: Tweening/Easing Library
Post by: bigsofty 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
Title: Re: Tweening/Easing Library
Post by: erico 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.
Title: Re: Tweening/Easing Library
Post by: mentalthink 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:
Title: Re: Tweening/Easing Library
Post by: bigsofty on 2014-Nov-09
Your welcome guys, drop a line here if you have any problems with it.  ;)