Last active
August 29, 2024 22:20
-
-
Save grilme99/cb59582ff40f3dbc5b465694d2a7d39a to your computer and use it in GitHub Desktop.
React-lua hooks for Ripple
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
Returns whether the given value is a binding. | |
@param value The value to check. | |
@return Whether the value is a binding. | |
]] | |
local function isBinding(value: unknown): boolean | |
return ReactIs.isBinding(value) | |
end | |
--[[ | |
Returns the value of a binding. If the given value is not a binding, it will | |
be returned as-is. | |
@param binding The binding to get the value of. | |
@return The value of the binding. | |
]] | |
local function getBindingValue<T>(value: T | Binding<T>): T | |
local value = value :: any | |
if isBinding(value) then | |
return value:getValue() | |
else | |
return value | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local RunService = game:GetService("RunService") | |
local React = require("@pkg/react") | |
local Ripple = require("@pkg/ripple") | |
local useEventConnection = require("@src/hooks/use-event-connection") | |
local useMemo = React.useMemo | |
local useBinding = React.useBinding | |
--[[ | |
Creates a memoized Motion object set to the given initial value. | |
Returns a binding that updates with the Motion, along with the Motion | |
object. | |
]] | |
local function useMotion<T>(initialValue: T) | |
local motion = useMemo(function() | |
return Ripple.createMotion(initialValue) | |
end, {}) | |
local binding, setValue = useBinding(initialValue) | |
useEventConnection(RunService.Heartbeat, function(delta) | |
local value = motion:step(delta) | |
if value ~= binding:getValue() then | |
setValue(value) | |
end | |
end) | |
return binding, motion | |
end | |
return useMotion |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local RunService = game:GetService("RunService") | |
local React = require("@pkg/react") | |
local Ripple = require("@pkg/ripple") | |
local BindingUtils = require("@src/utils/binding") | |
local getBindingValue = BindingUtils.getBindingValue | |
local useEventConnection = require("@src/hooks/use-event-connection") | |
local useMotion = require("@src/hooks/animation/use-motion") | |
local useRef = React.useRef | |
type Binding<T> = React.Binding<T> | |
type MotionGoal = Ripple.MotionGoal | |
export type SpringOptions = { | |
damping: number?, | |
frequency: number?, | |
mass: number?, | |
tension: number?, | |
friction: number?, | |
position: number?, | |
velocity: number?, | |
impulse: number?, | |
restingVelocity: number?, | |
restingPosition: number?, | |
} | |
type useSpringA = (goal: number | Binding<number>, options: SpringOptions?) -> Binding<number> | |
type useSpringB = <T>(goal: T | Binding<T>, options: SpringOptions?) -> Binding<T> | |
type useSpringC = (goal: MotionGoal | Binding<MotionGoal>, options: SpringOptions?) -> Binding<MotionGoal> | |
type useSpringFn = useSpringA & useSpringB & useSpringC | |
--[[ | |
Applies spring animations to the given value, and updates the goal with the | |
latest value on every re-render. Returns a binding that updates with the | |
Motion. | |
### Example | |
```lua | |
local color = useSpring(props.color, config.spring.stiff) | |
``` | |
]] | |
local function useSpring(goal: any, options: SpringOptions) | |
local binding, motion = useMotion(getBindingValue(goal)) | |
local previousValue = useRef(getBindingValue(goal)) | |
useEventConnection(RunService.Heartbeat, function() | |
local currentValue = getBindingValue(goal) | |
if currentValue ~= previousValue.current then | |
previousValue.current = currentValue | |
motion:spring(currentValue, options) | |
end | |
end) | |
return binding | |
end | |
return useSpring :: useSpringFn |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment