Props and reactivity
Bind props to your framework's state so effects update when it changes, and animate props with an animation library.
Setting a prop
Props work like the props on any other component in your framework:
Binding a prop to state
Pass state instead of a fixed value, and the effect updates when the state changes. Most props are uniforms: values the GPU reads every frame, like a CSS variable the shader can see. Changing a uniform doesn't recompile the effect.
Here three buttons rotate a gradient inside a circular mask:
Click the buttons and the gradient rotates on the next frame. In plain JavaScript there's no framework state, so call shader.update() with the component's id instead.
Numbers, colors and positions can all be bound the same way. Tie them to sliders, scroll position, the mouse, or any other changing value:
Knowing which props recompile
A few props change the structure of the effect rather than a value in it, so changing them recompiles the effect. These include blendMode, maskSource, maskType, visible, and select-style props such as colorSpace on many components. A recompile costs far more than a uniform update, so don't change these props every frame.
Animating props
Any animation library that produces a changing number can drive a prop. This example uses the animate() function from Motion, which is plain JavaScript, so the same pattern works in every framework:
import { useState } from 'react'
import { animate } from 'motion'
import { Shader, LinearGradient, Circle } from 'shaders/react'
function MyComponent() {
const [radius, setRadius] = useState(0.6)
async function pulse() {
// Grow, then shrink back
await animate(radius, 1, {
duration: 0.5,
ease: 'easeOut',
onUpdate: (latest) => setRadius(latest)
})
await animate(1, 0.6, {
duration: 0.5,
ease: 'easeIn',
onUpdate: (latest) => setRadius(latest)
})
}
return (
<>
<button onClick={pulse}>Pulse</button>
<Shader>
<Circle id="mask" radius={radius} visible={false} />
<LinearGradient maskSource="mask" />
</Shader>
</>
)
}
radius is a uniform, so updating it on every animation frame doesn't recompile the effect.
Next steps
- Dynamic props: drive props from the mouse or animate them without writing animation code.
- Hooks and events: respond to compilation and readiness events.
- Performance: what each layer costs and how to keep effects fast.