Documentation Index
Fetch the complete documentation index at: https://mintlify.com/paper-design/shaders/llms.txt
Use this file to discover all available pages before exploring further.
This guide will help you create your first animated shader. We’ll build a beautiful mesh gradient background in both React and vanilla JavaScript.
React Quick Start
Install the package
If you haven’t already, install the React package:npm install @paper-design/shaders-react
Import and use a shader component
Import any shader component and add it to your React component:import { MeshGradient } from '@paper-design/shaders-react';
function App() {
return (
<div style={{ position: 'relative', width: '100vw', height: '100vh' }}>
<MeshGradient
colors={['#5100ff', '#00ff80', '#ffcc00', '#ea00ff']}
distortion={1}
swirl={0.8}
speed={0.2}
style={{ width: '100%', height: '100%' }}
/>
</div>
);
}
export default App;
Customize your shader
Adjust the parameters to customize the appearance:<MeshGradient
colors={['#e0eaff', '#241d9a', '#f75092', '#9f50d3']}
distortion={0.5} // Lower distortion for smoother shapes
swirl={0.1} // Reduce swirl effect
speed={1} // Faster animation
grainMixer={0.2} // Add grain texture
style={{ width: '100%', height: '100%' }}
/>
The shader automatically creates a <canvas> element that matches the dimensions of its parent container.
Vanilla JavaScript Quick Start
Install the package
Install the vanilla JavaScript package:npm install @paper-design/shaders
Create a container element
Add a container element in your HTML:<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Paper Shaders Demo</title>
<style>
body {
margin: 0;
padding: 0;
}
#shader-container {
position: relative;
width: 100vw;
height: 100vh;
}
</style>
</head>
<body>
<div id="shader-container"></div>
<script type="module" src="./main.js"></script>
</body>
</html>
Initialize the shader
Create a shader using the ShaderMount class:import {
ShaderMount,
meshGradientFragmentShader,
getShaderColorFromString,
ShaderFitOptions,
defaultObjectSizing
} from '@paper-design/shaders';
// Get the container element
const container = document.getElementById('shader-container');
// Define your shader uniforms
const uniforms = {
// Color configuration
u_colors: [
'#5100ff',
'#00ff80',
'#ffcc00',
'#ea00ff'
].map(getShaderColorFromString),
u_colorsCount: 4,
// Visual parameters
u_distortion: 1,
u_swirl: 0.8,
u_grainMixer: 0,
u_grainOverlay: 0,
// Sizing parameters
u_fit: ShaderFitOptions[defaultObjectSizing.fit],
u_rotation: 0,
u_scale: 1,
u_offsetX: 0,
u_offsetY: 0,
u_originX: 0.5,
u_originY: 0.5,
u_worldWidth: 1000,
u_worldHeight: 1000,
};
// Create the shader mount
const shader = new ShaderMount(
container,
meshGradientFragmentShader,
uniforms,
{}, // WebGL context attributes
0.2, // speed
0 // starting frame
);
// Clean up when done (e.g., on page navigation)
// shader.dispose();
Update shader parameters (optional)
You can dynamically update shader parameters:// Update colors
shader.setUniforms({
u_colors: [
'#e0eaff',
'#241d9a',
'#f75092',
'#9f50d3'
].map(getShaderColorFromString),
u_distortion: 0.5,
});
// Change animation speed
shader.setSpeed(1);
// Pause animation
shader.setSpeed(0);
Try Other Shaders
Paper Shaders includes many different effects. Here are some popular ones:
import { DotOrbit } from '@paper-design/shaders-react';
<DotOrbit
colors={['#d2822d', '#0c3b7e', '#b31a57', '#37a066']}
colorBack={'#000000'}
scale={0.3}
speed={0.5}
style={{ width: '100%', height: '100%' }}
/>
Common Patterns
Full-Page Background
import { MeshGradient } from '@paper-design/shaders-react';
function Layout({ children }) {
return (
<div style={{ position: 'relative', minHeight: '100vh' }}>
{/* Background shader */}
<MeshGradient
colors={['#5100ff', '#00ff80', '#ffcc00', '#ea00ff']}
distortion={1}
swirl={0.8}
speed={0.2}
style={{
position: 'fixed',
top: 0,
left: 0,
width: '100%',
height: '100%',
zIndex: -1,
}}
/>
{/* Content on top */}
<div style={{ position: 'relative', zIndex: 1 }}>
{children}
</div>
</div>
);
}
Static Shader (No Animation)
For better performance, set speed={0} to disable animation:
<MeshGradient
colors={['#5100ff', '#00ff80', '#ffcc00', '#ea00ff']}
distortion={1}
swirl={0.8}
speed={0} // No animation, zero performance cost
frame={42} // Frozen at a specific frame
style={{ width: '100%', height: '100%' }}
/>
Card Background
function Card({ children }) {
return (
<div style={{
position: 'relative',
width: 300,
height: 200,
borderRadius: 16,
overflow: 'hidden',
boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
}}>
<MeshGradient
colors={['#667eea', '#764ba2']}
distortion={0.5}
swirl={0.2}
speed={0.1}
style={{ width: '100%', height: '100%' }}
/>
<div style={{
position: 'absolute',
inset: 0,
padding: 24,
color: 'white',
}}>
{children}
</div>
</div>
);
}
Masked with Text
function HeroText() {
return (
<div style={{ position: 'relative', display: 'inline-block' }}>
<h1 style={{
fontSize: 120,
fontWeight: 900,
margin: 0,
background: 'linear-gradient(to bottom, #000, #000)',
backgroundClip: 'text',
WebkitBackgroundClip: 'text',
color: 'transparent',
position: 'relative',
zIndex: 2,
mixBlendMode: 'multiply',
}}>
HELLO
</h1>
<MeshGradient
colors={['#5100ff', '#00ff80', '#ffcc00', '#ea00ff']}
distortion={1}
swirl={0.8}
speed={0.3}
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
zIndex: 1,
}}
/>
</div>
);
}
Performance Tips
Set speed={0} for static shaders to completely eliminate animation overhead and achieve zero ongoing performance cost.
The shader automatically limits resolution based on device capabilities. You can adjust minPixelRatio and maxPixelCount props for fine-tuning.
Shaders pause automatically when the browser tab is hidden to save resources.
Next Steps
React Guide
Learn about all React shader components and their props
Vanilla JS Guide
Deep dive into the ShaderMount API for vanilla JavaScript
Shader Gallery
Explore all available shaders with live examples
API Reference
Complete API documentation and type definitions
Common Issues
Make sure the parent container has a defined width and height. The shader canvas matches its parent’s dimensions.{/* ❌ Parent has no height */}
<div>
<MeshGradient colors={['#ff0000', '#0000ff']} />
</div>
{/* ✅ Parent has explicit height */}
<div style={{ width: 400, height: 300 }}>
<MeshGradient colors={['#ff0000', '#0000ff']} />
</div>
WebGL not supported error
Paper Shaders requires WebGL2 support. Ensure you’re testing in a modern browser:
- Chrome 56+
- Firefox 51+
- Safari 15+
- Edge 79+
Colors not working as expected
Colors should be provided as CSS color strings. Valid formats:
- Hex:
'#ff0000' or '#f00'
- RGB:
'rgb(255, 0, 0)'
- RGBA:
'rgba(255, 0, 0, 0.5)'
- Named:
'red'
{/* ✅ Valid */}
<MeshGradient colors={['#ff0000', 'rgba(0, 255, 0, 0.8)', 'blue']} />
{/* ❌ Invalid */}
<MeshGradient colors={[0xff0000, [255, 0, 0]]} />