@rbxts/ripple
Version:
Spring-driven animations and more
248 lines (184 loc) • 8.88 kB
Markdown
# 🎨 Ripple
**Ripple** is a simple, lightweight, and easy-to-use Roblox library for creating simple transitions and animations. It is inspired by [react-spring](https://react-spring.dev) and aims to provide an imperative API for general use.
## Installation
Ripple is available on [NPM](https://www.npmjs.com/package/@rbxts/ripple) and can be installed with the following commands:
```bash
npm install @rbxts/ripple
yarn add @rbxts/ripple
pnpm add @rbxts/ripple
```
```toml
# Wally
Ripple = "littensy/ripple@version"
```
## Reference
### Supported types
The following data types are supported for animation:
| Data type | [Converted type](./packages/ripple/src/utils/intermediate.luau) |
| -------------------------- | --------------------------------------------------------------- |
| number | `[number]` |
| vector | `[vector]` |
| Vector2 | `[vector]` |
| Vector3 | `[vector]` |
| Color3 | `[vector]` (Oklab) |
| UDim | `[vector]` |
| UDim2 | `[vector, number]` |
| CFrame | `[vector, vector, vector, vector]` |
| Rect | `[vector, number]` |
| Map<any, number \| vector> | `Map<any, number \| vector>` |
---
### `createSpring(initialValue, options)`
`createSpring` creates a spring object starting at the given value.
```lua
local spring = createSpring(0, {
tension = 170,
friction = 26,
start = true,
})
spring:setGoal(1)
spring:onChange(print) --> number, deltaTime
```
[Try the react-spring visualizer →](https://react-spring-visualizer.com)
#### Parameters
- `initialValue`: The value that the spring should start with.
- **optional** `options`: The physical properties of the spring.
#### Options
| Option | Type | Description |
| ---------------- | --------- | ---------------------------------------------------------------------------------------------- |
| tension[^1] | `number` | Influences the number of bounces in the animation. Defaults to `170`. |
| friction[^1] | `number` | Influences the level of spring in the animation. Defaults to `26`. |
| mass[^1] | `number` | Influences the speed of the spring and height of the bounce. Defaults to `1`. |
| frequency[^2] | `number` | How quickly the spring responds to changes. |
| dampingRatio[^2] | `number` | Dictates how the spring slows down. |
| precision | `number` | The distance to the goal before the spring is considered idle. Defaults to `0.001`. |
| restVelocity | `number` | The smallest velocity before the spring is considered idle. Derived from precision by default. |
| position | `T` | Set the position of the spring. |
| velocity | `T` | Set the velocity of the spring. |
| impulse | `T` | Add to the velocity of the spring. |
| start | `boolean` | Connect to Heartbeat while animating. Defaults to `false`. |
[^1]: Tension, friction, and mass are not compatible with frequency or damping ratio.
[^2]: Frequency and damping ratio are not compatible with tension, friction, or mass.
#### Returns
`createSpring` returns a spring object.
---
### `createTween(initialValue, options)`
`createTween` creates a tween object starting at the given value.
```lua
local tween = createTween(0, {
easing = "quadOut",
duration = 1,
start = true,
})
tween:setGoal(1)
tween:onChange(print) --> number, deltaTime
```
#### Parameters
- `initialValue`: The value that the spring should start with.
- **optional** `options`: The properties of the tween.
#### Options
| Option | Type | Description |
| -------- | --------- | -------------------------------------------------------------- |
| easing | `Easing` | The [easing function](#easing-functions) to use for animation. |
| duration | `number` | Duration of one repetition of the tween, in seconds. |
| repeats | `number` | Number of times the tween repeats. |
| reverses | `boolean` | Reverse directions when repeating. |
| position | `T` | Continue the rest of the tween from this position. |
| start | `boolean` | Connect to Heartbeat while animating. Defaults to `false`. |
#### Easing functions
| | | |
| ------------- | -------------- | ---------------- |
| `"linear"` | `"instant"` | `"smoothstep"` |
| `"sineIn"` | `"sineOut"` | `"sineInOut"` |
| `"backIn"` | `"backOut"` | `"backInOut"` |
| `"quadIn"` | `"quadOut"` | `"quadInOut"` |
| `"quartIn"` | `"quartOut"` | `"quartInOut"` |
| `"quintIn"` | `"quintOut"` | `"quintInOut"` |
| `"bounceIn"` | `"bounceOut"` | `"bounceInOut"` |
| `"elasticIn"` | `"elasticOut"` | `"elasticInOut"` |
| `"expoIn"` | `"expoOut"` | `"expoInOut"` |
| `"circIn"` | `"circOut"` | `"circInOut"` |
| `"cubicIn"` | `"cubicOut"` | `"cubicInOut"` |
[See examples of easing functions →](https://easings.net)
#### Returns
`createTween` returns a tween object.
---
### `createMotion(initialValue, options)`
`createMotion` creates an animation that switches between a spring and a tween.
```lua
local motion = createMotion(0, {
spring = { tension = 170, friction = 26 },
tween = { easing = "quadOut", duration = 1 },
start = true,
})
motion:onChange(print) --> number, deltaTime
motion:tween(1)
task.wait(1)
motion:spring(0)
```
> [!WARNING]
>
> This creates both a spring and a tween object, which can be wasteful if your animation uses only one or the other.
>
> Use [`createSpring`](#createspringinitialvalue-options) or [`createTween`](#createtweeninitialvalue-options) if you do not need to switch animation types.
#### Parameters
- `initialValue`: The value that the spring and tween should start with.
- **optional** `options`: The properties of the spring or tween.
#### Options
| Option | Type | Description |
| ------ | ------------------ | ------------------------------------------------------------ |
| spring | `SpringOptions<T>` | The [spring options](#options) to use for spring animations. |
| tween | `TweenOptions<T>` | The [tween options](#options-1) to use for tween animations. |
| start | `boolean` | Connect to Heartbeat while animating. Defaults to `false`. |
#### Returns
`createMotion` returns a motion object that controls a spring and a tween.
---
## Examples
### React Button
```luau
local function Button()
local binding, spring = useSpring(0, config.stiff)
return React.createElement("TextButton", {
[React.Change.GuiState] = function(rbx: TextButton)
if rbx.GuiState == Enum.GuiState.Hover then
spring:setGoal(20)
elseif rbx.GuiState == Enum.GuiState.Press then
spring:setGoal(-20, { impulse = -100 })
else
spring:setGoal(0)
end
end,
Text = "Button",
Size = binding:map(function(offset)
return UDim2.fromOffset(100 + offset, 50 + offset)
end),
})
end
```
### Vide Button
```luau
local function Button()
local getValue, spring = useSpring(0, config.stiff)
return create "TextButton" {
Text = "Button",
Size = function()
return UDim2.fromOffset(100 + getValue(), 50 + getValue())
end,
changed("GuiState", function(state: Enum.GuiState)
if state == Enum.GuiState.Hover then
spring:setGoal(20)
elseif state == Enum.GuiState.Press then
spring:setGoal(-20, { impulse = -100 })
else
spring:setGoal(0)
end
end),
}
end
```
---
<p align="center">
Ripple is licensed under the <a href="LICENSE.md">MIT License</a>.
</p>
<div align="center">
[](LICENSE.md)
</div>