flowshapes
Version:
A React component for rendering procedural shapes and text with WebGL-powered GLSL shaders
213 lines (174 loc) • 5.92 kB
Markdown
# FlowShapes
A powerful React component for rendering procedural shapes and text with WebGL-powered GLSL shaders. Create stunning animated graphics with custom fragment shaders.
## Features
- 🎨 **Procedural Shapes**: Rectangle, Ellipse, Polygon, Star, and Text
- ⚡ **WebGL Powered**: High-performance rendering using GLSL shaders
- 🎬 **Flexible Animation**: Built-in animation support with time control
- 📝 **Text Animation**: Animate text by character, word, or line with keyframe animations
- 🎯 **Custom Shaders**: Write your own GLSL fragment shaders for unique effects
- 🔧 **TypeScript Support**: Fully typed API
## Installation
```bash
npm install flowshapes
```
## Quick Start
```tsx
import { ProceduralShapeRenderer } from 'flowshapes';
function App() {
return (
<ProceduralShapeRenderer
shapeType="rectangle"
width={400}
height={400}
script={`
vec3 color = vec3(x/width, y/height, 0.5);
gl_FragColor = vec4(color, 1.0);
`}
autoAnimate={true}
/>
);
}
```
## API Reference
### Props
#### Basic Props
- **`shapeType`** (`'rectangle' | 'ellipse' | 'polygon' | 'star' | 'text'`): The type of shape to render
- **`width`** (`number`): Canvas width in pixels
- **`height`** (`number`): Canvas height in pixels
- **`script`** (`string`): GLSL fragment shader code for procedural effects
#### Time Control
- **`time`** (`number`, optional): Manual time control (overrides animation)
- **`startTime`** (`number`, default: `0`): Animation start time in seconds
- **`endTime`** (`number`, default: `5`): Animation end time in seconds
- **`fps`** (`number`, default: `60`): Target frames per second
- **`autoAnimate`** (`boolean`, default: `false`): Enable automatic animation
- **`loop`** (`boolean`, default: `true`): Loop animation between startTime and endTime
#### Shape-Specific Props
- **`rotation`** (`number`, default: `0`): Rotation in degrees
- **`radius`** (`number`, default: `0`): Corner radius for rounded rectangles
- **`numberOfPoints`** (`number`, default: `5`): Number of points for polygons/stars
- **`innerRadius`** (`number`, default: `25`): Inner radius for stars
- **`outerRadius`** (`number`, default: `50`): Outer radius for stars
#### Text-Specific Props
- **`text`** (`string`, default: `'Hello'`): Text content to render
- **`fontSize`** (`number`, default: `48`): Font size in pixels
- **`fontFamily`** (`string`, default: `'Arial'`): Font family
- **`fontWeight`** (`string | number`, default: `'normal'`): Font weight
- **`fontStyle`** (`string`, default: `'normal'`): Font style
- **`textAlign`** (`'left' | 'center' | 'right'`, default: `'center'`): Text alignment
- **`letterSpacing`** (`number`, default: `0`): Letter spacing in pixels
- **`textSelector`** (`TextSelector`, optional): Text animation configuration
#### Style Props
- **`backgroundColor`** (`string`, default: `'transparent'`): Canvas background color
- **`className`** (`string`, optional): CSS class name
- **`style`** (`React.CSSProperties`, optional): Inline styles
## Examples
### Basic Rectangle with Gradient
```tsx
<ProceduralShapeRenderer
shapeType="rectangle"
width={300}
height={300}
script={`
float gradient = y / height;
gl_FragColor = vec4(gradient, 0.5, 1.0 - gradient, 1.0);
`}
/>
```
### Animated Circle with Noise
```tsx
<ProceduralShapeRenderer
shapeType="ellipse"
width={400}
height={400}
autoAnimate={true}
script={`
float n = noise(x * 0.01, y * 0.01, time);
vec3 color = vec3(n, n * 0.5, 1.0 - n);
gl_FragColor = vec4(color, 1.0);
`}
/>
```
### Animated Text
```tsx
<ProceduralShapeRenderer
shapeType="text"
width={800}
height={200}
text="Hello World"
fontSize={72}
autoAnimate={true}
textSelector={{
type: 'character',
animateSequentially: true,
delay: 0.1,
properties: {
opacity: {
type: 'animated',
keyframes: [
{ time: 0, value: 0 },
{ time: 1, value: 100, easing: 'easeOut' }
]
},
scale: {
type: 'animated',
keyframes: [
{ time: 0, value: 0 },
{ time: 1, value: 100, easing: 'easeOutBack' }
]
}
}
}}
script={`
float gradient = x / width;
gl_FragColor = vec4(gradient, 0.5, 1.0 - gradient, 1.0);
`}
/>
```
## Shader API
Your GLSL fragment shader has access to these built-in variables and functions:
### Variables
- `float x, y` - Current pixel position
- `float width, height` - Canvas dimensions
- `float time` - Current time in seconds
- `float currentRotation` - Current rotation in degrees
- `vec2 pos` - Current pixel position as vec2
### Functions
- `float noise(float x, float y, float z)` - 3D Simplex noise
- `float snoise(vec2 v)` - 2D Simplex noise
- `float lerp(float a, float b, float t)` - Linear interpolation
- `float map(float val, float min1, float max1, float min2, float max2)` - Remap value
## Text Animation
The `textSelector` prop allows you to animate text by character, word, or line:
```tsx
textSelector={{
type: 'character', // 'character' | 'word' | 'line'
animateSequentially: true, // Animate each unit with delay
delay: 0.1, // Delay between units in seconds
properties: {
opacity: { /* animation config */ },
scale: { /* animation config */ },
rotation: { /* animation config */ },
position: { /* animation config */ }
}
}}
```
### Animation Properties
Each property can be `static` or `animated`:
```tsx
// Static value
opacity: { type: 'static', value: 100 }
// Animated with keyframes
opacity: {
type: 'animated',
keyframes: [
{ time: 0, value: 0, easing: 'linear' },
{ time: 1, value: 100, easing: 'easeOut' }
]
}
```
### Available Easings
- `linear`
- `easeIn`, `easeInQuad`, `easeInCubic`
- `easeOut`, `easeOutQuad`, `easeOutCubic`, `easeOutBack`
- `easeInOut`, `easeInOutQuad`, `easeInOutCubic`