Create stunning, animated 3D gradients with hardware-accelerated performance using WebGL and three.js.
β¨ Try the Interactive Editor β¨
Design your perfect gradient with our visual editor, featuring 20+ presets and real-time preview. Export the config and use it in your project instantly.
npm install @firecms/neat threeor
yarn add @firecms/neat threeImportant: Install
three(notthree.js- that's a different, incompatible package)
import { NeatGradient } from "@firecms/neat";
const gradient = new NeatGradient({
ref: document.getElementById("canvas"),
colors: [
{ color: "#FF5772", enabled: true },
{ color: "#4CB4BB", enabled: true },
{ color: "#FFC600", enabled: true },
{ color: "#8B6AE6", enabled: true },
{ color: "#2E0EC7", enabled: true }
],
speed: 4,
waveAmplitude: 5,
backgroundColor: "#003FFF",
backgroundAlpha: 1
});
// Clean up when done (important for React, Vue, etc.)
gradient.destroy();import { useEffect, useRef } from "react";
import { NeatGradient, NeatConfig } from "@firecms/neat";
function BackgroundGradient() {
const canvasRef = useRef<HTMLCanvasElement>(null);
const gradientRef = useRef<NeatGradient | null>(null);
useEffect(() => {
if (!canvasRef.current) return;
gradientRef.current = new NeatGradient({
ref: canvasRef.current,
colors: [
{ color: "#FF5772", enabled: true },
{ color: "#4CB4BB", enabled: true },
{ color: "#FFC600", enabled: true }
],
speed: 3,
waveAmplitude: 5
});
return () => gradientRef.current?.destroy();
}, []);
return (
<canvas
ref={canvasRef}
style={{
position: "fixed",
top: 0,
left: 0,
width: "100%",
height: "100%",
zIndex: -1
}}
/>
);
}| Property | Type | Default | Range | Description |
|---|---|---|---|---|
speed |
number |
4 |
0-10 |
Animation speed (0 = static) |
waveAmplitude |
number |
5 |
0-10 |
Wave height intensity |
waveFrequencyX |
number |
2 |
0-10 |
Horizontal wave frequency |
waveFrequencyY |
number |
3 |
0-10 |
Vertical wave frequency |
| Property | Type | Default | Description |
|---|---|---|---|
colors |
NeatColor[] |
Required | Array of color objects (up to 6) |
colorBlending |
number |
5 |
How colors mix together (0-10) |
colorBrightness |
number |
1 |
Overall brightness multiplier |
colorSaturation |
number |
0 |
Color saturation adjustment (-10 to 10) |
horizontalPressure |
number |
3 |
Horizontal color distribution (0-10) |
verticalPressure |
number |
3 |
Vertical color distribution (0-10) |
Color Object:
{
color: string; // Hex color (e.g., "#FF5772")
enabled: boolean; // Toggle color on/off
influence?: number; // Color strength (0-1, optional)
}| Property | Type | Default | Description |
|---|---|---|---|
shadows |
number |
0 |
Shadow intensity (0-10) |
highlights |
number |
5 |
Highlight intensity (0-10) |
grainIntensity |
number |
0 |
Film grain amount (0-1) |
grainScale |
number |
2 |
Grain size |
grainSpeed |
number |
1 |
Grain animation speed |
wireframe |
boolean |
false |
Show wireframe mesh |
| Property | Type | Default | Description |
|---|---|---|---|
backgroundColor |
string |
"#FFFFFF" |
Background color (hex) |
backgroundAlpha |
number |
1 |
Background opacity (0-1) |
| Property | Type | Default | Description |
|---|---|---|---|
resolution |
number |
1 |
Mesh resolution (0.1-2, lower = better performance) |
| Property | Type | Default | Description |
|---|---|---|---|
yOffset |
number |
0 |
Vertical scroll offset |
yOffsetWaveMultiplier |
number |
4 |
How much scroll affects waves (0-20) |
yOffsetColorMultiplier |
number |
4 |
How much scroll affects colors (0-20) |
yOffsetFlowMultiplier |
number |
4 |
How much scroll affects flow field (0-20) |
Example: Parallax Scrolling
window.addEventListener("scroll", () => {
gradient.yOffset = window.scrollY;
});| Property | Type | Default | Description |
|---|---|---|---|
flowEnabled |
boolean |
true |
Enable flow field distortion |
flowDistortionA |
number |
0 |
Primary distortion amplitude |
flowDistortionB |
number |
0 |
Secondary distortion frequency |
flowScale |
number |
1 |
Overall flow field scale |
flowEase |
number |
0 |
Flow field smoothing (0-1) |
| Property | Type | Default | Description |
|---|---|---|---|
mouseDistortionStrength |
number |
0 |
Mouse ripple intensity (0-1) |
mouseDistortionRadius |
number |
0.25 |
Mouse effect radius |
mouseDecayRate |
number |
0.96 |
How fast mouse trails fade (0.9-0.99) |
mouseDarken |
number |
0 |
Darken area under mouse (0-1) |
| Property | Type | Default | Description |
|---|---|---|---|
enableProceduralTexture |
boolean |
false |
Enable texture overlay |
textureVoidLikelihood |
number |
0.45 |
Gap frequency in texture (0-1) |
textureVoidWidthMin |
number |
200 |
Minimum gap width |
textureVoidWidthMax |
number |
486 |
Maximum gap width |
textureBandDensity |
number |
2.15 |
Texture band density |
textureColorBlending |
number |
0.01 |
Color mixing in texture (0-1) |
textureSeed |
number |
333 |
Random seed for texture |
textureEase |
number |
0.5 |
Flow/Image blend (0=flow, 1=image) |
proceduralBackgroundColor |
string |
"#000000" |
Texture void color |
textureShapeTriangles |
number |
20 |
Number of triangle shapes |
textureShapeCircles |
number |
15 |
Number of circle shapes |
textureShapeBars |
number |
15 |
Number of bar shapes |
textureShapeSquiggles |
number |
10 |
Number of squiggle shapes |
All properties can be updated in real-time:
// Animation
gradient.speed = 6;
gradient.waveAmplitude = 8;
// Colors
gradient.colors = [
{ color: "#FF0000", enabled: true },
{ color: "#00FF00", enabled: true }
];
// Effects
gradient.grainIntensity = 0.5;
gradient.mouseDistortionStrength = 0.3;
// Texture
gradient.enableProceduralTexture = true;
gradient.textureEase = 0.7;-
Lower resolution for better FPS:
resolution: 0.5 // Half resolution = ~4x faster
-
Disable features you don't need:
speed: 0, // Static gradient grainIntensity: 0, // No grain effect flowEnabled: false, // No flow distortion
-
Use fewer colors:
- 3-4 colors = best performance
- 6 colors = more complex but slower
- Subtle animations:
speed: 2-3,waveAmplitude: 3-5 - Dramatic effects:
speed: 5-8,waveAmplitude: 8-10 - Smooth blending: Higher
colorBlendingvalues (7-10) - Sharp contrasts: Lower
colorBlendingvalues (3-5)
Hero Background:
{
colors: [/* your brand colors */],
speed: 3,
waveAmplitude: 5,
shadows: 2,
highlights: 7,
grainIntensity: 0.1
}Subtle Page Background:
{
colors: [/* muted pastels */],
speed: 1,
waveAmplitude: 2,
colorBlending: 9,
backgroundAlpha: 0.7
}Interactive Section:
{
colors: [/* vibrant colors */],
speed: 4,
mouseDistortionStrength: 0.2,
mouseDistortionRadius: 0.3,
mouseDarken: 0.1
}Create depth by making different elements move at different speeds:
const gradient = new NeatGradient({
ref: canvas,
colors: [/* ... */],
yOffsetWaveMultiplier: 8, // Waves move faster
yOffsetColorMultiplier: 4, // Colors move slower
yOffsetFlowMultiplier: 6 // Flow in between
});
window.addEventListener("scroll", () => {
gradient.yOffset = window.scrollY;
});Add complex patterns over your gradient:
{
enableProceduralTexture: true,
textureEase: 0.3, // More topographic
textureVoidLikelihood: 0.3, // Fewer gaps
textureBandDensity: 1.5, // Wider bands
textureShapeTriangles: 30, // More shapes
proceduralBackgroundColor: "#000033" // Dark voids
}{
mouseDistortionStrength: 0.3, // Strong effect
mouseDistortionRadius: 0.4, // Large area
mouseDecayRate: 0.94, // Long trails
mouseDarken: 0.2 // Subtle darkening
}Full TypeScript definitions included:
import { NeatGradient, NeatConfig, NeatColor, NeatController } from "@firecms/neat";
const config: NeatConfig = {
// ... fully typed config
};
const gradient: NeatController = new NeatGradient(config);Neat uses WebGL shaders and three.js to render dynamic 3D gradients entirely on the GPU:
- Mesh Generation: Creates a subdivided plane geometry
- Vertex Shader: Displaces vertices to create waves using Perlin noise
- Fragment Shader: Blends colors, applies flow fields, lighting, and effects
- Hardware Acceleration: All computations run on the GPU for smooth 60fps animations
The result is a performant, beautiful gradient that can run on any modern device.
Neat is released under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
You can:
- β Use freely in personal projects
- β Modify and redistribute (with attribution)
- β Use in open-source projects
Commercial use requires a license.
For commercial projects without attribution, become a sponsor and contact us at [email protected] for a license key.
Created by FireCMS with β€οΈ
Built with three.js
Found a bug or have a feature request?
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- π Website & Editor
- π¦ npm Package
- π» GitHub Repository
- π¬ Discord Community
Made with β¨ by the FireCMS team
