Overview
This is a lightweight easing module designed for developers who need manual, frame-based interpolation using RunService.
While TweenService works well for property-based animations, there are many situations where direct tween objects are either too restrictive or unnecessary — such as:
- Custom animation systems
- UI scaling and procedural effects
- Interpolating non-tweenable values
- frame-based updates
This module provides:
- Full support for all standard EasingStyle types
- Support for all EasingDirection modes
- Strict Luau typing
- Defensive argument validation
- Manual interpolation via
Heartbeat
*Other useful methods
Why Not Just Use TweenService?
TweenService is excellent for property tweening, but it:
- Requires Tween objects
- Only works on tweenable properties
- Does not provide direct eased progress per frame
- Adds object overhead
This module instead exposes eased progress values directly, allowing you to apply interpolation however you want.
Grab the module: https://create.roblox.com/store/asset/137705773869840/Easing
Examples:
local Easing = require(path.to.Easing)
--a number to test in this example, in a real game this value might come from a
--heartbeat loop or a tween or whatever, should be between 0 and 1.
local number = 0.5
--get a eased value from a easing function
local easedValue = Easing.InOutSine(number)
--get a eased value from enums
local easedValue2 = Easing:FromEnum(Enum.EasingStyle.Elastic,Enum.EasingDirection.InOut,number)
-- get an eased value from a TweenInfo.
-- Note: TweenInfo.Time is treated as the normalized progress (0–1),
-- not duration in seconds.
local easedValue3 = Easing:FromTweenInfo(TweenInfo.new(
number,
Enum.EasingStyle.Elastic,
Enum.EasingDirection.InOut
))
--get a eased value from a lerp function, this is the equivalent of doing
--local lerped = math.lerp(1,100)
--local EasedLerped = Easing:FromEnum(Enum.EasingStyle.Elastic,Enum.EasingDirection.InOut,lerped)
local EasedLerpedValue = Easing:Lerp(1,100,number,Enum.EasingStyle.Sine,Enum.EasingDirection.InOut)
--smooth interpolate for animations or testing
local StartedAt = workspace:GetServerTimeNow()
--[[
StartedAt here can be a timestamp from the server to sync animations for new players.
this argument is optional, if not provided it will use the current time using workspace:GetServerTimeNow()
]]
Easing:SmoothInterpolate(Enum.EasingStyle.Quad,Enum.EasingDirection.InOut,10,function(easedProgress:number,RawProgress:number)
--do whatever animation or thing that requires easing!
end,StartedAt)
print(`Easing Testing: {easedValue}, {easedValue2}, {easedValue3}, {EasedLerpedValue}`)
Bugs:
for now i have not encountered any errors with Easing, and i hope it stays that way, if you see any bugs/errors or have improvements ideas, please let me know!
i hope my module helps!