Added Easing library with its documentation

This commit is contained in:
Fabio
2025-04-27 09:25:16 +02:00
parent 40ddcbee52
commit 56c8b1c6d5
6 changed files with 1075 additions and 0 deletions

684
Easing.hws Normal file
View File

@@ -0,0 +1,684 @@
/********************************************************************
* EASING LIBRARY *
* Author : Fabio Falcucci (Allanon) *
* License : MIT *
* Version : 1.5 *
* Release : 26/04/2025 *
* Dependancies : - *
* *
* PayPal Support hijoe@tin.it *
* Support me on Patreon! https://www.patreon.com/Allanon71 *
* Bitcoin https://coindrop.to/allanon *
* *
* Github repo (leaving) https://github.com/Allanon71 *
* Gitea repo (updated) https://gitea.it/allanon/HollywoodLibs *
* *
* CREDITS *
* This library is based on the library 'tween.lua' v1.0.1 (2012-02)*
* by Enrique García Cota. I've ported the original code to *
* Hollywood in September 2013 and I've added some useful functions *
* as well. *
* Original source code -> https://github.com/kikito/tween.lua *
* ------------------------------------------------------------------
*/
/********************************************************************
* INTRODUCTION
* Easing library is an include file for Hollywood able to create
* very smooth transitions between values so that you can use it to
* animate almost anything like: graphical objects, colors, values,
* and any value you need to be smoothly changed into another value.
* ------------------------------------------------------------------
*/
Global tween = {}
tween.Version = "1.5"
tween.Build = "26/04/2025"
Local pi = 3.14159
/************************************************************************
* PRIVATE STUFF *
************************************************************************/
Local tweens ; Initialized by calling to tween.stopAll()
Local Function isCallable(f)
Local tf = GetType(f)
If tf = #FUNCTION Then Return(True)
If tf = #TABLE
Local mt = GetMetaTable(f)
Return(GetType(mt) = #TABLE And GetType(mt.__call) = #FUNCTION)
EndIf
Return(False)
EndFunction
Local Function copyTables(destination, keysTable, valuesTable)
valuesTable = valuesTable Or keysTable
Local mt = getmetatable(keysTable)
If mt and GetMetaTable(destination) = Nil
SetMetaTable(destination, mt)
EndIf
For k,v In Pairs(keysTable)
If GetType(v) = #TABLE
destination[k] = copyTables({}, v, valuesTable[k])
Else
destination[k] = valuesTable[k]
EndIf
Next
Return(destination)
EndFunction
Local Function checkSubjectAndTargetRecursively(subject, target, path)
path = path Or {}
Local targetType, newPath
For k,targetValue In Pairs(target)
targetType, newPath = GetType(targetValue), copyTables({}, path)
InsertItem(newPath, tostring(k))
If targetType = #NUMBER
;-- Assert(GetType(subject[k]) = #NUMBER, "Parameter '" .. Concat(newPath,"/") .. "' is missing from subject or isn't a number")
ElseIf targetType = #TABLE
checkSubjectAndTargetRecursively(subject[k], targetValue, newPath)
Else
;-- Assert(targetType = #NUMBER, "Parameter '" .. Concat(newPath,"/") .. "' must be a number or table of numbers")
EndIf
Next
EndFunction
Local Function checkStartParams(time, subject, target, easing, callback)
;-- Assert(GetType(time) = #NUMBER And time > 0, "time must be a positive number. Was " .. ToString(time))
Local tsubject = GetType(subject)
;-- Assert(tsubject = #TABLE Or tsubject = #USERDATA, "subject must be a table or userdata. Was " .. ToString(subject))
;-- Assert(GetType(target)= #TABLE, "target must be a table. Was " .. ToString(target))
;-- Assert(isCallable(easing), "easing must be a function or functable. Was " .. ToString(easing))
;-- Assert(callback = Nil Or isCallable(callback), "callback must be nil, a function or functable. Was " .. ToString(time))
checkSubjectAndTargetRecursively(subject, target)
EndFunction
Function getEasingFunction(easing)
easing = easing Or "linear"
If GetType(easing) = #STRING
Local name = easing
easing = tween.easing[name]
;-- Assert(GetType(easing) = #FUNCTION, "The easing function name '" .. name .. "' is invalid")
EndIf
Return(easing)
EndFunction
Local Function newTween(time, subject, target, easing, callback, args)
Local self = {
time = time,
subject = subject,
target = copyTables({},target),
easing = easing,
callback = callback,
args = args,
initial = copyTables({}, target, subject),
running = 0
}
tweens[self] = self
Return(self)
EndFunction
Local Function easeWithTween(self, subject, target, initial)
Local t,b,c,d
For k, v In Pairs(target)
If GetType(v) = #TABLE
easeWithTween(self, subject[k], v, initial[k])
Else
t, b, c, d = self.running, initial[k], v - initial[k], self.time
subject[k] = self.easing(t, b, c, d)
EndIf
Next
EndFunction
Local Function hasExpiredTween(self)
Return( self.running >= self.time)
EndFunction
Local Function updateTween(self, dt)
self.running = self.running + dt
easeWithTween(self, self.subject, self.target, self.initial)
EndFunction
Local Function itemExists(table, index)
If GetType(table) = #NIL Then Return(False)
If GetType(RawGet(table, index)) = #NIL Then Return(False) Else Return(True)
EndFunction
Local Function finishTween(self)
copyTables(self.subject, self.target)
If itemExists(self, "callback") Then self.callback(Unpack(self.args))
tween.stop(self)
EndFunction
Local Function resetTween(self)
copyTables(self.subject, self.initial)
EndFunction
;-------------------------------------------------------------------------------
;-- easing --
;-- --
;-- Adapted from https://github.com/EmmanuelOga/easing. See LICENSE.txt for --
;-- credits. --
;-- For all easing functions: --
;-- t = time ==> how much time has to pass for the tweening to complete --
;-- b = begin ==> starting property value --
;-- c = change ==> ending - beginning --
;-- d = duration ==> running time. How much time has passed *right now* --
;-------------------------------------------------------------------------------
;::: LINEAR :::
Local Function linear(t, b, c, d) Return(c * t / d + b) EndFunction
;::: QUAD :::
Local Function inQuad(t, b, c, d) Return(c * pow(t / d, 2) + b) EndFunction
;::: OUTQUAD :::
Local Function outQuad(t, b, c, d)
t = t / d
Return(-c * t * (t - 2) + b)
EndFunction
;::: INOUTQUAD :::
Local Function inOutQuad(t, b, c, d)
t = t / d * 2
If t < 1 Then Return(c / 2 * pow(t, 2) + b)
Return(-c / 2 * ((t - 1) * (t - 3) - 1) + b)
EndFunction
;::: OUTINQUAD :::
Local Function outInQuad(t, b, c, d)
If t < d / 2 Then Return(outQuad(t * 2, b, c / 2, d))
Return(inQuad((t * 2) - d, b + c / 2, c / 2, d))
EndFunction
;::: INCUBIC :::
Local Function inCubic (t, b, c, d) Return(c * pow(t / d, 3) + b) EndFunction
;::: OUTCUBIC :::
Local Function outCubic(t, b, c, d) Return(c * (pow(t / d - 1, 3) + 1) + b) EndFunction
;::: INOUTCUBIC :::
Local Function inOutCubic(t, b, c, d)
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
;:::OUTINCUBIC :::
Local Function outInCubic(t, b, c, d)
If t < d / 2 Then Return(outCubic(t * 2, b, c / 2, d))
Return(inCubic((t * 2) - d, b + c / 2, c / 2, d))
EndFunction
;::: INQUART :::
Local Function inQuart(t, b, c, d) Return(c * pow(t / d, 4) + b) EndFunction
;::: OUTQUART :::
Local Function outQuart(t, b, c, d) Return(-c * (pow(t / d - 1, 4) - 1) + b) EndFunction
;::: INOUTQUART :::
Local Function inOutQuart(t, b, c, d)
t = t / d * 2
If t < 1 Then Return(c / 2 * pow(t, 4) + b)
Return(-c / 2 * (pow(t - 2, 4) - 2) + b)
EndFunction
;::: OUTINQUART :::
Local Function outInQuart(t, b, c, d)
If t < d / 2 Then Return(outQuart(t * 2, b, c / 2, d))
Return(inQuart((t * 2) - d, b + c / 2, c / 2, d))
EndFunction
;::: INQUINT :::
Local Function inQuint(t, b, c, d) Return(c * pow(t / d, 5) + b) EndFunction
;::: OUTQUINT :::
Local Function outQuint(t, b, c, d) Return(c * (pow(t / d - 1, 5) + 1) + b) EndFunction
;::: INOUTQUINT :::
Local Function inOutQuint(t, b, c, d)
t = t / d * 2
If t < 1 Then Return(c / 2 * pow(t, 5) + b)
Return(c / 2 * (pow(t - 2, 5) + 2) + b)
EndFunction
;OUTINQUINT :::
Local Function outInQuint(t, b, c, d)
If t < d / 2 Then Return(outQuint(t * 2, b, c / 2, d))
Return(inQuint((t * 2) - d, b + c / 2, c / 2, d))
EndFunction
;::: INSINE :::
Local Function inSine(t, b, c, d) Return(-c * cos(t / d * (pi / 2)) + c + b) EndFunction
;::: OUTSINE :::
Local Function outSine(t, b, c, d) Return(c * sin(t / d * (pi / 2)) + b) EndFunction
;::: INOUTSINE :::
Local Function inOutSine(t, b, c, d) Return(-c / 2 * (cos(pi * t / d) - 1) + b) EndFunction
;::: OUTINSINE :::
Local Function outInSine(t, b, c, d)
If t < d / 2 Then Return(outSine(t * 2, b, c / 2, d))
Return(inSine((t * 2) -d, b + c / 2, c / 2, d))
EndFunction
;::: INEXPO :::
Local Function inExpo(t, b, c, d)
If t = 0 Then Return(b)
Return(c * pow(2, 10 * (t / d - 1)) + b - c * 0.001)
EndFunction
;::: OUTEXPO :::
Local Function outExpo(t, b, c, d)
If t = d Then Return(b + c)
Return(c * 1.001 * (-pow(2, -10 * t / d) + 1) + b)
EndFunction
;::: INOUTEXPO :::
Local Function inOutExpo(t, b, c, d)
If t = 0 Then Return(b)
If t = d Then Return(b + c)
t = t / d * 2
If t < 1 Then Return(c / 2 * pow(2, 10 * (t - 1)) + b - c * 0.0005)
Return(c / 2 * 1.0005 * (-pow(2, -10 * (t - 1)) + 2) + b)
EndFunction
;::: OUTINEXPO :::
Local Function outInExpo(t, b, c, d)
If t < d / 2 Then Return(outExpo(t * 2, b, c / 2, d))
Return(inExpo((t * 2) - d, b + c / 2, c / 2, d))
EndFunction
;::: INCIRC :::
Local Function inCirc(t, b, c, d) Return((-c * (sqrt(1 - pow(t / d, 2)) - 1) + b)) EndFunction
;::: OUTCIRC :::
Local Function outCirc(t, b, c, d) Return((c * sqrt(1 - pow(t / d - 1, 2)) + b)) EndFunction
;::: INOUTCIRC :::
Local Function inOutCirc(t, b, c, d)
t = t / d * 2
If t < 1 Then Return(-c / 2 * (Sqrt(1 - t * t) - 1) + b)
t = t - 2
Return(c / 2 * (sqrt(1 - t * t) + 1) + b)
EndFunction
;::: OUTINCIRC :::
Local Function outInCirc(t, b, c, d)
If t < d / 2 Then Return(outCirc(t * 2, b, c / 2, d))
Return(inCirc((t * 2) - d, b + c / 2, c / 2, d))
EndFunction
;::: ELASTIC :::
Local Function calculatePAS(p,a,c,d)
p, a = p Or d * 0.3, a Or 0
If a < Abs(c) Then Return(p, c, p / 4) ;-- p, a, s
/*
Local ca = 0
If Not(IsNil(a)) And a <> 0
ca = c/a
EndIf
*/
Return(p, a, p / (2 * pi) * ASin(ca)) ;-- p, a, s
EndFunction
;::: INELANSTIC :::
Local Function inElastic(t, b, c, d, a, p)
Local s
If t = 0 Then Return(b)
t = t / d
If t = 1 Then Return(b + c)
p, a, s = calculatePAS(p,a,c,d)
t = t - 1
Return(-(a * pow(2, 10 * t) * sin((t * d - s) * (2 * pi) / p)) + b)
EndFunction
;::: OUTELASTIC :::
Local Function outElastic(t, b, c, d, a, p)
Local s
If t = 0 Then Return(b)
t = t / d
If t = 1 Then Return(b + c)
p, a, s = calculatePAS(p,a,c,d)
Return(a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p) + c + b)
EndFunction
;::: INOUTELASTIC :::
Local Function inOutElastic(t, b, c, d, a, p)
Local s
If t = 0 Then Return(b)
t = t / d * 2
If t = 2 Then Return(b + c)
p, a, s = calculatePAS(p,a,c,d)
t = t - 1
If t < 0 Then Return(-0.5 * (a * pow(2, 10 * t) * sin((t * d - s) * (2 * pi) / p)) + b)
Return(a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p ) * 0.5 + c + b)
EndFunction
;:::OUTINELASTIC :::
Local Function outInElastic(t, b, c, d, a, p)
If t < d / 2 Then Return(outElastic(t * 2, b, c / 2, d, a, p))
Return(inElastic((t * 2) - d, b + c / 2, c / 2, d, a, p))
EndFunction
;::: INBACK :::
Local Function inBack(t, b, c, d, s)
s = s Or 1.70158
t = t / d
Return(c * t * t * ((s + 1) * t - s) + b)
EndFunction
;::: OUTBACK :::
Local Function outBack(t, b, c, d, s)
s = s Or 1.70158
t = t / d - 1
Return(c * (t * t * ((s + 1) * t + s) + 1) + b)
EndFunction
;:::INOUTBACK :::
Local Function inOutBack(t, b, c, d, s)
s = (s Or 1.70158) * 1.525
t = t / d * 2
If t < 1 Then Return(c / 2 * (t * t * ((s + 1) * t - s)) + b)
t = t - 2
Return(c / 2 * (t * t * ((s + 1) * t + s) + 2) + b)
EndFunction
;::: OUTINBACK :::
Local Function outInBack(t, b, c, d, s)
If t < d / 2 Then Return(outBack(t * 2, b, c / 2, d, s))
Return(inBack((t * 2) - d, b + c / 2, c / 2, d, s))
EndFunction
;::: OUTBOUNCE :::
Local Function outBounce(t, b, c, d)
t = t / d
If t < 1 / 2.75 Then Return(c * (7.5625 * t * t) + b)
If t < 2 / 2.75
t = t - (1.5 / 2.75)
Return(c * (7.5625 * t * t + 0.75) + b)
ElseIf t < 2.5 / 2.75
t = t - (2.25 / 2.75)
Return(c * (7.5625 * t * t + 0.9375) + b)
EndIf
t = t - (2.625 / 2.75)
Return(c * (7.5625 * t * t + 0.984375) + b)
EndFunction
;::: INBOUNCE :::
Local Function inBounce(t, b, c, d) Return(c - outBounce(d - t, 0, c, d) + b) EndFunction
;::: INOUTBOUNCE :::
Local Function inOutBounce(t, b, c, d)
If t < d / 2 Then Return(inBounce(t * 2, 0, c, d) * 0.5 + b)
Return(outBounce(t * 2 - d, 0, c, d) * 0.5 + c * .5 + b)
EndFunction
;::: OUTINBOUNCE :::
Local Function outInBounce(t, b, c, d)
If t < d / 2 Then Return(outBounce(t * 2, b, c / 2, d))
Return(inBounce((t * 2) - d, b + c / 2, c / 2, d))
EndFunction
tween.easing =
{
linear = linear,
inQuad = inQuad, outQuad = outQuad, inOutQuad = inOutQuad, outInQuad = outInQuad,
inCubic = inCubic, outCubic = outCubic, inOutCubic = inOutCubic, outInCubic = outInCubic,
inQuart = inQuart, outQuart = outQuart, inOutQuart = inOutQuart, outInQuart = outInQuart,
inQuint = inQuint, outQuint = outQuint, inOutQuint = inOutQuint, outInQuint = outInQuint,
inSine = inSine, outSine = outSine, inOutSine = inOutSine, outInSine = outInSine,
inExpo = inExpo, outExpo = outExpo, inOutExpo = inOutExpo, outInExpo = outInExpo,
inCirc = inCirc, outCirc = outCirc, inOutCirc = inOutCirc, outInCirc = outInCirc,
inElastic = inElastic, outElastic = outElastic, inOutElastic = inOutElastic, outInElastic = outInElastic,
inBack = inBack, outBack = outBack, inOutBack = inOutBack, outInBack = outInBack,
inBounce = inBounce, outBounce = outBounce, inOutBounce = inOutBounce, outInBounce = outInBounce,
}
/********************************************************************
* PUBLIC FUNCTIONS *
********************************************************************/
Function tween.start(time, subject, target, easing, callback, ...)
/******************************************************************************
| tweenId = tween.start(time, subject, target, easing, callback, ...)
|
| Start a new tween and returns its id.
|
| INPUT
| time : Transition time in milliseconds
| subject : Table where the transition target(s) are defined
| target : A table with one or more targets and their final values
| easing : String with the easing formula name
| callback : Function to call when the transition ends
| ... : Additional variables to pass to the callback function at
| the end of the transition
| OUTPUT
| tweenId : Id of the initialized tween
|
| NOTES
| Possible string values for the parameter <easing> are:
| - linear - inquad - outquad - inoutquad - outinquad
| - incubic - outcubic - inoutcubic - outincubic - inquart
| - outquart - inoutquart - outinquart - inquint - outquint
| - inoutquint - outinquint - insine - outsine - inoutsine
| - outinsine - inexpo - outexpo - inoutexpo - outinexpo
| - incirc - outcirc - inoutcirc - outincirc - inelastic
| - outelastic - inoutelastic - outinelastic - inback - outback
| - inoutback - outinback - inbounce - outbounce - inoutbounce
| - outinbounce.
******************************************************************************/
easing = getEasingFunction(easing)
checkStartParams(time, subject, target, easing, callback)
arg.n = Nil
Return(newTween(time, subject, target, easing, callback, arg))
EndFunction
SetMetaTable(tween, { __call = Function(t, ...) arg.n = Nil Return(tween.start(arg)) EndFunction })
Function tween.reset(id)
/******************************************************************************
| tween.reset(tweenId)
|
| Reset, and stop, the specified running tween.
|
| INPUT
| id : The id of the tween we want to reset
******************************************************************************/
Local tw = tweens[id]
If tw
resetTween(tw)
tween.stop(tw)
EndIf
EndFunction
Function tween.resetAll()
/******************************************************************************
| tween.resetAll()
|
| Reset, and stop, all running tweens.
******************************************************************************/
For _,tw In Pairs(tweens)
copyTables(tw.subject, tw.initial)
Next
tween.stopAll()
EndFunction
Function tween.update(dt)
/******************************************************************************
| tween.update(dt)
|
| Update all running tweens evaluating the given 'dt' delta time.
|
| INPUT
| dt : Delta time in milliseconds, it is the time passed between the last
| update and this exact moment.
******************************************************************************/
;-- Assert(GetType(dt) = #NUMBER And dt > 0, "dt must be a positive number")
Local expired = {}
For _,t In Pairs(tweens)
updateTween(t, dt)
If hasExpiredTween(t) Then InsertItem(expired, t)
Next
For i = 0, ListItems(expired) - 1
finishTween(expired[i])
Next
EndFunction
Function tween.stop(id, callback)
/******************************************************************************
| tween.stop(id, callback)
|
| Stops the given running tween.
|
| INPUT
| id : Id of the tween we want to stop
| callback : Set this argument to TRUE if you want to execute the associated
| callback function like if the tween was naturally ended.
******************************************************************************/
If callback Then finishTween(id)
If Not(IsNil(id)) Then tweens[id] = Nil
EndFunction
Function tween.stopAll(callback)
/******************************************************************************
| tween.stopAll(callback)
|
| Stops all running tweens
|
| INPUT
| callback : Set this argument to TRUE if you want to execute the associated
| callback function like if the tween was naturally ended.
******************************************************************************/
If tweens
For _,t In Pairs(tweens)
tween.stop(t, callback)
Next
EndIf
tweens = {}
EndFunction
Function tween.count()
/******************************************************************************
| count = tween.count()
|
| Returns how many tweens are running.
|
| OUTPUT
| count : Number of running tweens
******************************************************************************/
Local c = 0
For i, v In Pairs(tweens)
c = c + 1
Next
Return(c)
EndFunction
Function tween.TEST()
/******************************************************************************
This program shows how to use tweens and will test all tween functions
It also uses recursive callback functions to build tween chains.
******************************************************************************/
EscapeQuit(True)
; All available easing functions
Local easing =
{ "linear",
"inquad", "outquad", "inoutquad", "outinquad",
"incubic", "outcubic", "inoutcubic", "outincubic",
"inquart", "outquart", "inoutquart", "outinquart",
"inquint", "outquint", "inoutquint", "outinquint",
"insine", "outsine", "inoutsine", "outinsine",
"inexpo", "outexpo", "inoutexpo", "outinexpo",
"incirc", "outcirc", "inoutcirc", "outincirc",
"inelastic", "outelastic", "inoutelastic", "outinelastic",
"inback", "outback", "inoutback", "outinback",
"inbounce", "outbounce", "inoutbounce", "outinbounce" }
Local Items = {} ; Stores all items usend in our test
Local StartE = 0 ; First easing
Local EndE = ListItems(easing)-1 ; Last easing
Local Timer = StartTimer(Nil) ; Start a timer to track delta times
Local rate = 10 ; Update every 10ms
Local UpdateScreen = Function()
; This routine will update the screen, tween functions needs the delta time
; to be updated correctly so the first thing to do is calculate this value
; each time the screen is updated.
Local cTime = GetTimer(Timer) ; Current time
Local dTime = cTime - OldTime ; Delta time
; Updates all active tweens
Tween.Update(dTime)
; Clear the screen
SetFillStyle(#FILLCOLOR)
Box(0, 0, 640, 480, $A4000000)
; Display the objects, one for each defined tween
For Local i = StartE To EndE
TextOut(Items[i].x, Items[i].y, easing[i], { Color = Items[i].Color })
Next
; Message in the top-left screen corner
TextOut(10, 10, "(ESC to quit) - DT:" .. dTime, { Color = #RED })
OldTime = cTime
; Swap buffers without waiting for the vertical blank
Flip(True)
EndFunction
;*** CALLBACK FUNCTION used to restart the tween animations
;*** once they have ended.
Local fRepeat = {} ; Needed to make recursive callbacks
fRepeat = Function(id)
; Callback function used initialize and restart every item tween
Local id = id.id
Items[id].x = 0
Items[id].color = GetRandomColor()
tween.start(10000, Items[id], { x = 560 }, easing[id], fRepeat, { id = id })
EndFunction
; Initialize the tweens, one for each animation available
; Every tween get the callback function 'fRepeat()' that will
; be executed when the tween ends.
For Local i = StartE To EndE
Local b = i
Items[i] = { x = 0, y = 50 + i*8 }
Items[i].fun = Function(a)
Local a = b
Items[a].x = 0
tween.start(10000, Items[a], { x = 560 }, easing[a], fRepeat, { id = a })
EndFunction
Next
; Setup the renderer at the specified refresh rate
Local Renderer = SetInterval(Nil, UpdateScreen, rate)
; Initialize the previous time for the first delta time
; calculation
Local OldTime = GetTimer(Timer)
; Create text colors and start all defined tweens
For Local i = StartE To EndE
Items[i].color = GetRandomColor()
Items[i].fun(i)
Next
BeginDoubleBuffer()
; Infinite loop
Repeat
WaitEvent()
Forever
EndFunction
tween.stopAll() ; Nedeed to initialize the tween system
; tween.TEST()

21
Easing_license.txt Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017-2025 Fabio Falcucci
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

187
Easing_readme.md Normal file
View File

@@ -0,0 +1,187 @@
# EASING LIBRARY
```plain
Author : Fabio Falcucci (Allanon)
License : MIT (see Easing_license.txt)
Version : 1.7
Release : 03/11/2024
Dependancies : -
PayPal Support : hijoe@tin.it
Patreon Support : https://www.patreon.com/Allanon71
Repositories
- GitHub : https://github.com/Allanon71 (old versions)
- Gitea : https://gitea.it/allanon/HollywoodLibs
Contacts
- email : fabio.falcucci@alice.it
- Mastodon : @allanon@mastodon.uno
- Links : https://linksta.cc/@Allanon
- WebSite : https://a-mc.biz
```
## CREDITS
This library is based on the library `tween.lua` v1.0.1 (2012-02) by Enrique García Cota. I've ported the original code to Hollywood in September 2013 and I've added some useful functions as well.
[Click here for the original source code](https://github.com/kikito/tween.lua)
---
## WHAT IS
[![EASING Lib: Test program in action](images/Easing.jpg)]()
The Easing library is an include file for Hollywood MAL suited to create very smooth transitions between values so you can use it to animate almost anything like graphical objects, colors, coordinates, and any value you need to be smoothly changed into another one.
Please note that this library is based on the library `tween.lua` v1.0.1 (2012-02) by Enrique Garcia Cota.
I've started the port of the original code to Hollywood in 2013 and I've added some new useful features during time.
You can get the original code here -> [https://github.com/kikito/tween.lua](https://github.com/kikito/tween.lua)
---
## EXAMPLES
You can find the sollowing examples in the [Examples/Easing](Examples/Easing) folder:
- `Easing.hws` : This example is embedded in the source code, just include the library and call the function `tween.TEST()` to see how it works.
- [BasicUsage.hws](Examples/Easing/BasicUsage.hws) : This is a very simple program that shows how to use tweens with only one animation running.
- [WorkingWithTweens.hws](Examples/Easing/WorkingWithTween.hws) : It's almost the same example embedded in the library source code under the function `tween.TEST()`.
---
## EASING FUNCTIONS
All Easing functions are mapped into the `tween` table.
- [tween.start()](#tween_start)
- [tween.reset()](#tween_reset)
- [tween.resetAll()](#tween_resetall)
- [tween.update()](#tween_update)
- [tween.stop()](#tween_stop)
- [tween.stopAll()](#tween_stopall)
- [tween.count()](#tween_count)
- [tween.TEST()](#tween_test)
---
<a id="available_transitions"></a>
## AVAILABLE TRANSITIONS
```plain
linear inquad outquad inoutquad
outinquad incubic outcubic inoutcubic
outincubic inquart outquart inoutquart
outinquart inquint outquint inoutquint
outinquint insine outsine inoutsine
outinsine inexpo outexpo inoutexpo
outinexpo incirc outcirc inoutcirc
outincirc inelastic outelastic inoutelastic
outinelastic inback outback inoutback
outinback inbounce outbounce inoutbounce
outinbounce
```
---
<a id="functions"></a>
## FUNCTIONS
<a id="tween_start"></a>
## tween.start(time, subject, target, easing, callback, ...)
Start a new tween and returns its id.
**INPUT**
- `time` : (NUM) Transition time in milliseconds
- `subject` : (TABLE) Table where the transition target(s) are defined
- `target` : (TABLE) A table with one or more targets and their final values
- `easing` : (STR) String with the easing formula name
- `callback` : (FUNC) Function to call when the transition ends
- `...` : (ANY) Additional variables to pass to the callback function at the end of the transition
**OUTPUT**
- `tweenId` : (NUM) Id of the initialized tween
**NOTES**
For the possible string values of the `easing` parameter [click here](#available_transitions)
---
<a id="tween_reset"></a>
## tween.reset(tweenId)
Resets and stop, the specified running tween.
**INPUT**
`id` : (NUM) The id of the tween we want to reset returned by `tween.start()`.
---
<a id="tween_resetall"></a>
## tween.resetAll()
Resets and stop, all running tweens.
---
<a id="tween_update"></a>
## tween.update(dt)
Update all running tweens evaluating the given `dt` delta time.
**INPUT**
- `dt` : (NUM) Delta time in milliseconds, it is the time passed between the last update and this exact moment.
---
<a id="tween_stop"></a>
## tween.stop(id, callback)
Stops the given running tween.
**INPUT**
- `id` : (NUM) The Id, returned by `tween.start()`, of the tween we want to stop
- `callback` : (BOOL) Set this argument to `True` if you want to execute the associated callback function like if the tween was naturally ended.
---
<a id="tween_stopall"></a>
## tween.stopAll(callback)
Stops all running tweens.
**INPUT**
- `callback` : (BOOL) Set this argument to `True` if you want to execute the associated callback function like if the tween was naturally ended.
---
<a id="tween_count"></a>
## tween.count()
Returns how many tweens are running.
**OUTPUT**
- `count` : (NUM) Number of running tweens.
---
<a id="tween_test"></a>
## tween.TEST()
This program shows how to use tweens testing all tween functions.
It also uses recursive callback functions to build tween chains.
Have a look at it to see how to use this library, especially to build chained animations.

View File

@@ -0,0 +1,73 @@
/********************************************************************
* EASING Example, Basic usage *
* ---------------------------------------------------------------- *
* Author : Fabio Falcucci (Allanon) *
* License : Freeware *
* Version : 1.0 *
* Release : - *
* Dependancies : Easing.hws *
* *
* PayPal Support hijoe@tin.it *
* Support me on Patreon! https://www.patreon.com/Allanon71 *
* Bitcoin https://coindrop.to/allanon *
* *
* Github repo (leaving) https://github.com/Allanon71 *
* Gitea repo (updated) https://gitea.it/allanon/HollywoodLibs *
* ---------------------------------------------------------------- *
*/
; 1. Include the Easing library
@INCLUDE "../../+Includes.hws"
@INCLUDE #INC_EASING
; @INCLUDE "Easing.hws"
; 2. Setup a tween for a text string that will cross the screen in 10 seconds
; We need a table to hold the text position
Local textPos = { x = 0, y = 320 }
; Let's start the transition
tween.start(10000, ; 10 seconds = 10*1000 milliseconds
textPos, ; The table where we have our variable we want to smoothly change
{ x = 600 }, ; One or more targets : in this case we want to reach x=640 in 10 seconds
"inoutelastic", ; The name of the easing function we want to use
Function() ; A function to call when the transition ends, here we are using an anonymous function to print a message
NPrint("Transition Ended! Click Left Mouse Button")
WaitLeftMouse()
End
EndFunction
)
; 3. We need a function we will call regurarly to update and render
; the scene, we also need a variable to store the previous execution
; time so we can calculate the delta time.
Local previousTime = 0
Local timer = StartTimer(Nil)
Function renderer()
; Calculate the delta time
Local currentTime = GetTimer(timer)
Local deltaTime = currentTime - previousTime
; Update previousTime variable
previousTime = currentTime
; Clear the screen
Cls()
; Update the tweens
tween.update(deltaTime)
; Render the object
TextOut(textPos.x, textPos.y, "HELLO!")
EndFunction
; 4. Setup a Interval function to update & render the tweens @ 100FPS
; meaning every 10 milliseconds.
Local rendererInterval = SetInterval(Nil, renderer, 10)
; 5. Setup an infinite loop and watch the result
Repeat
WaitEvent()
Forever

View File

@@ -0,0 +1,110 @@
/********************************************************************
* EASING Example, Working with tweens *
* ---------------------------------------------------------------- *
* Author : Fabio Falcucci (Allanon) *
* License : Freeware *
* Version : 1.0 *
* Release : 26/03/2014 *
* Dependancies : Easing.hws *
* *
* PayPal Support hijoe@tin.it *
* Support me on Patreon! https://www.patreon.com/Allanon71 *
* Bitcoin https://coindrop.to/allanon *
* *
* Github repo (leaving) https://github.com/Allanon71 *
* Gitea repo (updated) https://gitea.it/allanon/HollywoodLibs *
* ---------------------------------------------------------------- *
*/
@INCLUDE "../../+Includes.hws"
@INCLUDE #INC_EASING
; @INCLUDE "Easing.hws"
; Setup some variables
Items = {} ; Each item will show a differen easing function
StartE = 0 ; First easing
EndE = 40 ; Last easing
Function UpdateScreen()
; This routine will update the screen, tween functions needs the delta time
; to be updated so the first thing to do is calculate this value.
Local cTime = GetTimer(Timer)
Local dTime = cTime - OldTime
; Updates all active tweens
Tween.Update(dTime)
; Update the background color
Box(0, 0, 640, 480, #BLACK)
; Display the objects, one for each defined tween
For Local i = StartE To EndE
TextOut(Items[i].x, Items[i].y, easing[i], { Color = Items[i].Color })
Next
TextOut(10, 10, "(left click to quit) DT:" .. cTime - OldTime)
OldTime = cTime
Flip()
EndFunction
Timer = StartTimer(Nil) ; Start a timer to track delta times
Renderer = SetInterval(Nil, UpdateScreen, 10) ; Call the UpdateScreen every 10ms
OldTime = GetTimer(Timer) ; Initialize the time for the delta times calc
; To make a cross chain betweens the to callback functions we need
; to define an empty function so that the first one does not reference
; a nil value.
Local fBackard = Function() EndFunction
Function fForward(id)
; Define the forward movement
Local id = id.id
Items[id].x = 0
; Look at the callaback function, we are referencing to fBackward that in this
; exact moment point to the empty function defined above
tween.start(10000+Rnd(5000), Items[id], { x = 560 }, easing[id], fBackward, { id = id })
EndFunction
; But now we are redefining the fBackward function replacing the
; empty one.
Function fBackward(id)
; Callback function used initialize and restart every item
Local id = id.id
; Look at the callback function : it points to fForward so that
; when this transition finishes the loop will be started again
tween.start(10000+Rnd(5000), Items[id], { x = 0 }, easing[id], fForward, { id = id })
EndFunction
; Table with all available easing animations
easing =
{ "linear",
"inquad", "outquad", "inoutquad", "outinquad",
"incubic", "outcubic", "inoutcubic", "outincubic",
"inquart", "outquart", "inoutquart", "outinquart",
"inquint", "outquint", "inoutquint", "outinquint",
"insine", "outsine", "inoutsine", "outinsine",
"inexpo", "outexpo", "inoutexpo", "outinexpo",
"incirc", "outcirc", "inoutcirc", "outincirc",
"inelastic", "outelastic", "inoutelastic", "outinelastic",
"inback", "outback", "inoutback", "outinback",
"inbounce", "outbounce", "inoutbounce", "outinbounce" }
; Initialize the tweens, one for each animation available
For Local i = StartE To EndE
Local b = i
Items[i] = { x = 0, y = 50 + i*8, color = GetRandomColor() }
fForward({ id = i })
Next
BeginDoubleBuffer()
SetFillStyle(#FILLCOLOR)
While Not(IsLeftMouse())
WaitEvent()
Wend

BIN
images/Easing.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB