Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local module = {}
- functions = {
- Linear = {
- In = function(t) return t end,
- Out = function(t) return t end,
- InOut = function(t) return t end
- },
- Sine = {
- In = function(t) return 1 - math.cos((t * math.pi) / 2) end,
- Out = function(t) return math.sin((t * math.pi) / 2) end,
- InOut = function(t) return -(math.cos(math.pi * t) - 1) / 2 end
- },
- Quad = {
- In = function(t) return t * t end,
- Out = function(t) return 1 - (1 - t) * (1 - t) end,
- InOut = function(t) return t < 0.5 and 2 * t * t or 1 - 2 * (1 - t) * (1 - t) end
- },
- Cubic = {
- In = function(t) return t * t * t end,
- Out = function(t) return 1 - (1 - t) * (1 - t) * (1 - t) end,
- InOut = function(t) return t < 0.5 and 4 * t * t * t or 1 - 4 * (1 - t) * (1 - t) * (1 - t) end
- },
- Quart = {
- In = function(t) return t * t * t * t end,
- Out = function(t) return 1 - (1 - t) * (1 - t) * (1 - t) * (1 - t) end,
- InOut = function(t) return t < 0.5 and 8 * t * t * t * t or 1 - 8 * (1 - t) * (1 - t) * (1 - t) * (1 - t) end
- },
- Quint = {
- In = function(t) return t * t * t * t * t end,
- Out = function(t) return 1 - (1 - t) * (1 - t) * (1 - t) * (1 - t) * (1 - t) end,
- InOut = function(t) return t < 0.5 and 16 * t * t * t * t * t or 1 - 16 * (1 - t) * (1 - t) * (1 - t) * (1 - t) * (1 - t) end
- },
- Exponential = {
- In = function(t) return t == 0 and 0 or 2^(10 * (t - 1)) end,
- Out = function(t) return t == 1 and 1 or 1 - 2^(-10 * t) end,
- InOut = function(t)
- if t == 0 then return 0 end
- if t == 1 then return 1 end
- return t < 0.5 and 2^(20 * t - 10) / 2 or (2 - 2^(-20 * t + 10)) / 2
- end
- },
- Circular = {
- In = function(t) return 1 - math.sqrt(1 - t * t) end,
- Out = function(t) return math.sqrt(1 - (t - 1) * (t - 1)) end,
- InOut = function(t)
- return t < 0.5 and (1 - math.sqrt(1 - 4 * t * t)) / 2 or (math.sqrt(1 - (-2 * t + 2)^2) + 1) / 2
- end
- },
- Elastic = {
- In = function(t)
- if t == 0 then return 0 end
- if t == 1 then return 1 end
- return -2^(10 * t - 10) * math.sin((t * 10 - 10.75) * (2 * math.pi) / 3)
- end,
- Out = function(t)
- if t == 0 then return 0 end
- if t == 1 then return 1 end
- return 2^(-10 * t) * math.sin((t * 10 - 0.75) * (2 * math.pi) / 3) + 1
- end,
- InOut = function(t)
- if t == 0 then return 0 end
- if t == 1 then return 1 end
- t = t * 2
- if t < 1 then return -0.5 * 2^(10 * t - 10) * math.sin((t * 10 - 10.75) * 2 * math.pi / 3) end
- return 0.5 * 2^(-10 * (t - 1)) * math.sin((t * 10 - 10.75) * 2 * math.pi / 3) + 1
- end
- },
- Back = {
- In = function(t)
- local s = 1.70158
- return t * t * ((s + 1) * t - s)
- end,
- Out = function(t)
- local s = 1.70158
- t = t - 1
- return t * t * ((s + 1) * t + s) + 1
- end,
- InOut = function(t)
- local s = 1.70158 * 1.525
- t = t * 2
- if t < 1 then return 0.5 * (t * t * ((s + 1) * t - s)) end
- t = t - 2
- return 0.5 * (t * t * ((s + 1) * t + s) + 2)
- end
- },
- Bounce = {
- Out = function(t)
- if t < 4/11 then
- return (121 * t * t) / 16
- elseif t < 8/11 then
- return (363/40 * t * t) - (99/10 * t) + 17/5
- elseif t < 9/10 then
- return (4356/361 * t * t) - (35442/1805 * t) + 16061/1805
- else
- return (54/5 * t * t) - (513/25 * t) + 268/25
- end
- end,
- In = function(t)
- return 1 - functions.Bounce.Out(1 - t)
- end,
- InOut = function(t)
- if t < 0.5 then
- return (1 - functions.Bounce.Out(1 - 2 * t)) / 2
- else
- return (1 + functions.Bounce.Out(2 * t - 1)) / 2
- end
- end
- }
- }
- local runs = game:GetService("RunService")
- function module.tween(obj, prop, opts)
- opts = opts or {}
- local duration = opts.duration or 1
- local style = opts.style or "Linear"
- local direction = opts.direction or "In"
- local loop = opts.loop or false
- if not functions[style] then
- style = "Linear"
- warn("Invalid easing style, defaulting to Linear")
- end
- if not functions[style][direction] then
- direction = "In"
- warn("Invalid easing direction, defaulting to In")
- end
- local ease = functions[style][direction]
- local init = {}
- local target = {}
- for p, v in pairs(prop) do
- init[p] = obj[p]
- target[p] = v
- end
- local controller = {
- Pause = false,
- SpeedMultiplier = 1,
- Completed = false,
- }
- controller.Cancel = function()
- controller.Completed = true
- end
- local function do_tween(from, to)
- local start = os.clock()
- local last = start
- local scaled = 0
- local paused = false
- while not controller.Completed do
- while controller.Pause do
- task.wait(0.05)
- local now = os.clock()
- last = now
- end
- local time_scale = workspace:GetAttribute("TimeScale") or 1
- if runs:IsStudio() and time_scale == 0 then
- time_scale = 1
- end
- if time_scale == 0.001 then
- if not paused then
- paused = true
- last = os.clock()
- end
- task.wait(0.05)
- else
- if paused then
- paused = false
- last = os.clock()
- end
- local combined = controller.SpeedMultiplier * math.max(0.001, time_scale)
- local current = os.clock()
- local delta = current - last
- last = current
- scaled += delta * combined
- local prog = ease(math.clamp(scaled / duration, 0, 1))
- for p, i in pairs(from) do
- local tv = to[p]
- local cv
- if typeof(tv) == "number" then
- cv = i + (tv - i) * prog
- elseif typeof(tv) == "Vector3" then
- cv = i:Lerp(tv, prog)
- elseif typeof(tv) == "Color3" then
- cv = i:Lerp(tv, prog)
- elseif typeof(tv) == "CFrame" then
- local pos = i.Position:Lerp(tv.Position, prog)
- local rot = i.Rotation:Lerp(tv.Rotation, prog)
- cv = CFrame.new(pos) * rot
- end
- obj[p] = cv
- end
- if scaled >= duration then
- break
- end
- task.wait()
- end
- end
- for p, tv in pairs(to) do
- obj[p] = tv
- end
- end
- coroutine.wrap(function()
- while not controller.Completed do
- do_tween(init, target)
- if not loop or controller.Completed then break end
- do_tween(target, init)
- end
- controller.Completed = true
- end)()
- return controller
- end
- function module.wait(t)
- local e = 0
- while e < t do
- local timescale = workspace:GetAttribute("TimeScale") or 1
- timescale = math.clamp(timescale, 0.001, 10)
- local step = 0.05
- task.wait(step)
- e += step * timescale
- end
- end
- return module
Advertisement
Add Comment
Please, Sign In to add comment