Advertisement
Vzurxy

Tween

Dec 30th, 2019
364
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.81 KB | None | 0 0
  1. --[[
  2.     function CreateCircleTween()
  3.     TSize.Circle = Tween.new(1 / 2, {
  4.         Radius = shared.iDrawings.FOV_Circle.Radius;
  5.     }, {
  6.         Radius = 100;
  7.     }, 'outBounce');
  8.     end
  9. ]]--
  10.  
  11. local tween = {
  12.   _VERSION     = 'tween 2.1.1',
  13.   _DESCRIPTION = 'tweening for lua',
  14.   _URL         = 'https://github.com/kikito/tween.lua',
  15.   _LICENSE     = [[
  16.     MIT LICENSE
  17.  
  18.     Copyright (c) 2014 Enrique García Cota, Yuichi Tateno, Emmanuel Oga
  19.  
  20.     Permission is hereby granted, free of charge, to any person obtaining a
  21.     copy of this software and associated documentation files (the
  22.     "Software"), to deal in the Software without restriction, including
  23.     without limitation the rights to use, copy, modify, merge, publish,
  24.     distribute, sublicense, and/or sell copies of the Software, and to
  25.     permit persons to whom the Software is furnished to do so, subject to
  26.     the following conditions:
  27.  
  28.     The above copyright notice and this permission notice shall be included
  29.     in all copies or substantial portions of the Software.
  30.  
  31.     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  32.     OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  33.     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  34.     IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  35.     CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  36.     TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  37.     SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  38.   ]]
  39. }
  40.  
  41. -- easing
  42.  
  43. -- Adapted from https://github.com/EmmanuelOga/easing. See LICENSE.txt for credits.
  44. -- For all easing functions:
  45. -- t = time == how much time has to pass for the tweening to complete
  46. -- b = begin == starting property value
  47. -- c = change == ending - beginning
  48. -- d = duration == running time. How much time has passed *right now*
  49.  
  50. local pow, sin, cos, pi, sqrt, abs, asin = math.pow, math.sin, math.cos, math.pi, math.sqrt, math.abs, math.asin
  51.  
  52. -- linear
  53. local function linear(t, b, c, d) return c * t / d + b end
  54.  
  55. -- quad
  56. local function inQuad(t, b, c, d) return c * pow(t / d, 2) + b end
  57. local function outQuad(t, b, c, d)
  58.   t = t / d
  59.   return -c * t * (t - 2) + b
  60. end
  61. local function inOutQuad(t, b, c, d)
  62.   t = t / d * 2
  63.   if t < 1 then return c / 2 * pow(t, 2) + b end
  64.   return -c / 2 * ((t - 1) * (t - 3) - 1) + b
  65. end
  66. local function outInQuad(t, b, c, d)
  67.   if t < d / 2 then return outQuad(t * 2, b, c / 2, d) end
  68.   return inQuad((t * 2) - d, b + c / 2, c / 2, d)
  69. end
  70.  
  71. -- cubic
  72. local function inCubic (t, b, c, d) return c * pow(t / d, 3) + b end
  73. local function outCubic(t, b, c, d) return c * (pow(t / d - 1, 3) + 1) + b end
  74. local function inOutCubic(t, b, c, d)
  75.   t = t / d * 2
  76.   if t < 1 then return c / 2 * t * t * t + b end
  77.   t = t - 2
  78.   return c / 2 * (t * t * t + 2) + b
  79. end
  80. local function outInCubic(t, b, c, d)
  81.   if t < d / 2 then return outCubic(t * 2, b, c / 2, d) end
  82.   return inCubic((t * 2) - d, b + c / 2, c / 2, d)
  83. end
  84.  
  85. -- quart
  86. local function inQuart(t, b, c, d) return c * pow(t / d, 4) + b end
  87. local function outQuart(t, b, c, d) return -c * (pow(t / d - 1, 4) - 1) + b end
  88. local function inOutQuart(t, b, c, d)
  89.   t = t / d * 2
  90.   if t < 1 then return c / 2 * pow(t, 4) + b end
  91.   return -c / 2 * (pow(t - 2, 4) - 2) + b
  92. end
  93. local function outInQuart(t, b, c, d)
  94.   if t < d / 2 then return outQuart(t * 2, b, c / 2, d) end
  95.   return inQuart((t * 2) - d, b + c / 2, c / 2, d)
  96. end
  97.  
  98. -- quint
  99. local function inQuint(t, b, c, d) return c * pow(t / d, 5) + b end
  100. local function outQuint(t, b, c, d) return c * (pow(t / d - 1, 5) + 1) + b end
  101. local function inOutQuint(t, b, c, d)
  102.   t = t / d * 2
  103.   if t < 1 then return c / 2 * pow(t, 5) + b end
  104.   return c / 2 * (pow(t - 2, 5) + 2) + b
  105. end
  106. local function outInQuint(t, b, c, d)
  107.   if t < d / 2 then return outQuint(t * 2, b, c / 2, d) end
  108.   return inQuint((t * 2) - d, b + c / 2, c / 2, d)
  109. end
  110.  
  111. -- sine
  112. local function inSine(t, b, c, d) return -c * cos(t / d * (pi / 2)) + c + b end
  113. local function outSine(t, b, c, d) return c * sin(t / d * (pi / 2)) + b end
  114. local function inOutSine(t, b, c, d) return -c / 2 * (cos(pi * t / d) - 1) + b end
  115. local function outInSine(t, b, c, d)
  116.   if t < d / 2 then return outSine(t * 2, b, c / 2, d) end
  117.   return inSine((t * 2) -d, b + c / 2, c / 2, d)
  118. end
  119.  
  120. -- expo
  121. local function inExpo(t, b, c, d)
  122.   if t == 0 then return b end
  123.   return c * pow(2, 10 * (t / d - 1)) + b - c * 0.001
  124. end
  125. local function outExpo(t, b, c, d)
  126.   if t == d then return b + c end
  127.   return c * 1.001 * (-pow(2, -10 * t / d) + 1) + b
  128. end
  129. local function inOutExpo(t, b, c, d)
  130.   if t == 0 then return b end
  131.   if t == d then return b + c end
  132.   t = t / d * 2
  133.   if t < 1 then return c / 2 * pow(2, 10 * (t - 1)) + b - c * 0.0005 end
  134.   return c / 2 * 1.0005 * (-pow(2, -10 * (t - 1)) + 2) + b
  135. end
  136. local function outInExpo(t, b, c, d)
  137.   if t < d / 2 then return outExpo(t * 2, b, c / 2, d) end
  138.   return inExpo((t * 2) - d, b + c / 2, c / 2, d)
  139. end
  140.  
  141. -- circ
  142. local function inCirc(t, b, c, d) return(-c * (sqrt(1 - pow(t / d, 2)) - 1) + b) end
  143. local function outCirc(t, b, c, d)  return(c * sqrt(1 - pow(t / d - 1, 2)) + b) end
  144. local function inOutCirc(t, b, c, d)
  145.   t = t / d * 2
  146.   if t < 1 then return -c / 2 * (sqrt(1 - t * t) - 1) + b end
  147.   t = t - 2
  148.   return c / 2 * (sqrt(1 - t * t) + 1) + b
  149. end
  150. local function outInCirc(t, b, c, d)
  151.   if t < d / 2 then return outCirc(t * 2, b, c / 2, d) end
  152.   return inCirc((t * 2) - d, b + c / 2, c / 2, d)
  153. end
  154.  
  155. -- elastic
  156. local function calculatePAS(p,a,c,d)
  157.   p, a = p or d * 0.3, a or 0
  158.   if a < abs(c) then return p, c, p / 4 end -- p, a, s
  159.   return p, a, p / (2 * pi) * asin(c/a) -- p,a,s
  160. end
  161. local function inElastic(t, b, c, d, a, p)
  162.   local s
  163.   if t == 0 then return b end
  164.   t = t / d
  165.   if t == 1  then return b + c end
  166.   p,a,s = calculatePAS(p,a,c,d)
  167.   t = t - 1
  168.   return -(a * pow(2, 10 * t) * sin((t * d - s) * (2 * pi) / p)) + b
  169. end
  170. local function outElastic(t, b, c, d, a, p)
  171.   local s
  172.   if t == 0 then return b end
  173.   t = t / d
  174.   if t == 1 then return b + c end
  175.   p,a,s = calculatePAS(p,a,c,d)
  176.   return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p) + c + b
  177. end
  178. local function inOutElastic(t, b, c, d, a, p)
  179.   local s
  180.   if t == 0 then return b end
  181.   t = t / d * 2
  182.   if t == 2 then return b + c end
  183.   p,a,s = calculatePAS(p,a,c,d)
  184.   t = t - 1
  185.   if t < 0 then return -0.5 * (a * pow(2, 10 * t) * sin((t * d - s) * (2 * pi) / p)) + b end
  186.   return a * pow(2, -10 * t) * sin((t * d - s) * (2 * pi) / p ) * 0.5 + c + b
  187. end
  188. local function outInElastic(t, b, c, d, a, p)
  189.   if t < d / 2 then return outElastic(t * 2, b, c / 2, d, a, p) end
  190.   return inElastic((t * 2) - d, b + c / 2, c / 2, d, a, p)
  191. end
  192.  
  193. -- back
  194. local function inBack(t, b, c, d, s)
  195.   s = s or 1.70158
  196.   t = t / d
  197.   return c * t * t * ((s + 1) * t - s) + b
  198. end
  199. local function outBack(t, b, c, d, s)
  200.   s = s or 1.70158
  201.   t = t / d - 1
  202.   return c * (t * t * ((s + 1) * t + s) + 1) + b
  203. end
  204. local function inOutBack(t, b, c, d, s)
  205.   s = (s or 1.70158) * 1.525
  206.   t = t / d * 2
  207.   if t < 1 then return c / 2 * (t * t * ((s + 1) * t - s)) + b end
  208.   t = t - 2
  209.   return c / 2 * (t * t * ((s + 1) * t + s) + 2) + b
  210. end
  211. local function outInBack(t, b, c, d, s)
  212.   if t < d / 2 then return outBack(t * 2, b, c / 2, d, s) end
  213.   return inBack((t * 2) - d, b + c / 2, c / 2, d, s)
  214. end
  215.  
  216. -- bounce
  217. local function outBounce(t, b, c, d)
  218.   t = t / d
  219.   if t < 1 / 2.75 then return c * (7.5625 * t * t) + b end
  220.   if t < 2 / 2.75 then
  221.     t = t - (1.5 / 2.75)
  222.     return c * (7.5625 * t * t + 0.75) + b
  223.   elseif t < 2.5 / 2.75 then
  224.     t = t - (2.25 / 2.75)
  225.     return c * (7.5625 * t * t + 0.9375) + b
  226.   end
  227.   t = t - (2.625 / 2.75)
  228.   return c * (7.5625 * t * t + 0.984375) + b
  229. end
  230. local function inBounce(t, b, c, d) return c - outBounce(d - t, 0, c, d) + b end
  231. local function inOutBounce(t, b, c, d)
  232.   if t < d / 2 then return inBounce(t * 2, 0, c, d) * 0.5 + b end
  233.   return outBounce(t * 2 - d, 0, c, d) * 0.5 + c * .5 + b
  234. end
  235. local function outInBounce(t, b, c, d)
  236.   if t < d / 2 then return outBounce(t * 2, b, c / 2, d) end
  237.   return inBounce((t * 2) - d, b + c / 2, c / 2, d)
  238. end
  239.  
  240. tween.easing = {
  241.   linear    = linear,
  242.   inQuad    = inQuad,    outQuad    = outQuad,    inOutQuad    = inOutQuad,    outInQuad    = outInQuad,
  243.   inCubic   = inCubic,   outCubic   = outCubic,   inOutCubic   = inOutCubic,   outInCubic   = outInCubic,
  244.   inQuart   = inQuart,   outQuart   = outQuart,   inOutQuart   = inOutQuart,   outInQuart   = outInQuart,
  245.   inQuint   = inQuint,   outQuint   = outQuint,   inOutQuint   = inOutQuint,   outInQuint   = outInQuint,
  246.   inSine    = inSine,    outSine    = outSine,    inOutSine    = inOutSine,    outInSine    = outInSine,
  247.   inExpo    = inExpo,    outExpo    = outExpo,    inOutExpo    = inOutExpo,    outInExpo    = outInExpo,
  248.   inCirc    = inCirc,    outCirc    = outCirc,    inOutCirc    = inOutCirc,    outInCirc    = outInCirc,
  249.   inElastic = inElastic, outElastic = outElastic, inOutElastic = inOutElastic, outInElastic = outInElastic,
  250.   inBack    = inBack,    outBack    = outBack,    inOutBack    = inOutBack,    outInBack    = outInBack,
  251.   inBounce  = inBounce,  outBounce  = outBounce,  inOutBounce  = inOutBounce,  outInBounce  = outInBounce
  252. }
  253.  
  254.  
  255.  
  256. -- private stuff
  257.  
  258. local function copyTables(destination, keysTable, valuesTable)
  259.   valuesTable = valuesTable or keysTable
  260.   local mt = getmetatable(keysTable)
  261.   if mt and getmetatable(destination) == nil then
  262.     setmetatable(destination, mt)
  263.   end
  264.   for k,v in pairs(keysTable) do
  265.     if type(v) == 'table' then
  266.       destination[k] = copyTables({}, v, valuesTable[k])
  267.     else
  268.       destination[k] = valuesTable[k]
  269.     end
  270.   end
  271.   return destination
  272. end
  273.  
  274. local function checkSubjectAndTargetRecursively(subject, target, path)
  275.   path = path or {}
  276.   local targetType, newPath
  277.   for k,targetValue in pairs(target) do
  278.     targetType, newPath = type(targetValue), copyTables({}, path)
  279.     table.insert(newPath, tostring(k))
  280.     if targetType == 'number' then
  281.       assert(type(subject[k]) == 'number', "Parameter '" .. table.concat(newPath,'/') .. "' is missing from subject or isn't a number")
  282.     elseif targetType == 'table' then
  283.       checkSubjectAndTargetRecursively(subject[k], targetValue, newPath)
  284.     else
  285.       assert(targetType == 'number', "Parameter '" .. table.concat(newPath,'/') .. "' must be a number or table of numbers")
  286.     end
  287.   end
  288. end
  289.  
  290. local function checkNewParams(duration, subject, target, easing)
  291.   assert(type(duration) == 'number' and duration > 0, "duration must be a positive number. Was " .. tostring(duration))
  292.   local tsubject = type(subject)
  293.   assert(tsubject == 'table' or tsubject == 'userdata', "subject must be a table or userdata. Was " .. tostring(subject))
  294.   assert(type(target)== 'table', "target must be a table. Was " .. tostring(target))
  295.   assert(type(easing)=='function', "easing must be a function. Was " .. tostring(easing))
  296.   checkSubjectAndTargetRecursively(subject, target)
  297. end
  298.  
  299. local function getEasingFunction(easing)
  300.   easing = easing or "linear"
  301.   if type(easing) == 'string' then
  302.     local name = easing
  303.     easing = tween.easing[name]
  304.     if type(easing) ~= 'function' then
  305.       error("The easing function name '" .. name .. "' is invalid")
  306.     end
  307.   end
  308.   return easing
  309. end
  310.  
  311. local function performEasingOnSubject(subject, target, initial, clock, duration, easing)
  312.   local t,b,c,d
  313.   for k,v in pairs(target) do
  314.     if type(v) == 'table' then
  315.       performEasingOnSubject(subject[k], v, initial[k], clock, duration, easing)
  316.     else
  317.       t,b,c,d = clock, initial[k], v - initial[k], duration
  318.       subject[k] = easing(t,b,c,d)
  319.     end
  320.   end
  321. end
  322.  
  323. -- Tween methods
  324.  
  325. local Tween = {}
  326. local Tween_mt = {__index = Tween}
  327.  
  328. function Tween:set(clock)
  329.   assert(type(clock) == 'number', "clock must be a positive number or 0")
  330.  
  331.   self.initial = self.initial or copyTables({}, self.target, self.subject)
  332.   self.clock = clock
  333.  
  334.   if self.clock <= 0 then
  335.  
  336.     self.clock = 0
  337.     copyTables(self.subject, self.initial)
  338.  
  339.   elseif self.clock >= self.duration then -- the tween has expired
  340.  
  341.     self.clock = self.duration
  342.     copyTables(self.subject, self.target)
  343.  
  344.   else
  345.  
  346.     performEasingOnSubject(self.subject, self.target, self.initial, self.clock, self.duration, self.easing)
  347.  
  348.   end
  349.  
  350.   return self.clock >= self.duration
  351. end
  352.  
  353. function Tween:reset()
  354.   return self:set(0)
  355. end
  356.  
  357. function Tween:update(dt)
  358.   assert(type(dt) == 'number', "dt must be a number")
  359.   return self:set(self.clock + dt)
  360. end
  361.  
  362.  
  363. -- Public interface
  364.  
  365. function tween.new(duration, subject, target, easing)
  366.   easing = getEasingFunction(easing)
  367.   checkNewParams(duration, subject, target, easing)
  368.   return setmetatable({
  369.     duration  = duration,
  370.     subject   = subject,
  371.     target    = target,
  372.     easing    = easing,
  373.     clock     = 0
  374.   }, Tween_mt)
  375. end
  376.  
  377. return tween
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement