Docs
→Animated Gradient With SVG
Animated Gradient With SVG
An animated multi-color gradient background effect with SVG elements.
Total Revenue
$1,234,567
15% increase from last month
New Users
1234
Daily signups
Conversion Rate
3.45%
0.5% increase from last week
Active Projects
42
8 completed this month
Customer Satisfaction
4.8/5
Based on 1,000+ reviews from verified customers across all product categories
Source code
Add this hook for querying the dimensions of an element:
import { useState, useEffect, RefObject } from 'react';
interface Dimensions {
width: number;
height: number;
}
export function useDimensions(ref: RefObject<HTMLElement | SVGElement>): Dimensions {
const [dimensions, setDimensions] = useState<Dimensions>({ width: 0, height: 0 });
useEffect(() => {
let timeoutId: NodeJS.Timeout;
const updateDimensions = () => {
if (ref.current) {
const { width, height } = ref.current.getBoundingClientRect();
setDimensions({ width, height });
}
};
const debouncedUpdateDimensions = () => {
clearTimeout(timeoutId);
timeoutId = setTimeout(updateDimensions, 250); // Wait 250ms after resize ends
};
// Initial measurement
updateDimensions();
window.addEventListener('resize', debouncedUpdateDimensions);
return () => {
window.removeEventListener('resize', debouncedUpdateDimensions);
clearTimeout(timeoutId);
};
}, [ref]);
return dimensions;
}
Update your tailwind.config.ts
file to include the animation keyframes:
module.exports = {
// ...
theme: {
// ...
animation: {
...
"background-gradient":
"background-gradient var(--background-gradient-speed, 15s) cubic-bezier(0.445, 0.05, 0.55, 0.95) infinite"
},
keyframes: {
...
"background-gradient": {
"0%, 100%": {
transform: "translate(0, 0)",
animationDelay: "var(--background-gradient-delay, 0s)",
},
"20%": {
transform:
"translate(calc(100% * var(--tx-1, 1)), calc(100% * var(--ty-1, 1)))",
},
"40%": {
transform:
"translate(calc(100% * var(--tx-2, -1)), calc(100% * var(--ty-2, 1)))",
},
"60%": {
transform:
"translate(calc(100% * var(--tx-3, 1)), calc(100% * var(--ty-3, -1)))",
},
"80%": {
transform:
"translate(calc(100% * var(--tx-4, -1)), calc(100% * var(--ty-4, -1)))",
},
},
},
},
};
Then, copy and paste the following code into your project:
Understanding the component
Animated gradients can be achieved with many different techniques (shaders, CSS gradients, etc.), this component uses simple SVG circles with a blur filter to create the effect.
- For each color in the
colors
prop array, the component creates an SVG circle element - Each circle is given a random initial position using percentage values
- The movement of each circle is controlled by 8 CSS variables that define target positions:
--tx-1
and--ty-1
for the first position--tx-2
and--ty-2
for the second position- And so on for positions 3 and 4
- These variables are set to random values between -0.5 and 0.5.
...
style={
{
...
"--tx-1": (Math.random() - 0.5),
"--ty-1": (Math.random() - 0.5),
"--tx-2": (Math.random() - 0.5),
"--ty-2": (Math.random() - 0.5),
"--tx-3": (Math.random() - 0.5),
"--ty-3": (Math.random() - 0.5),
"--tx-4": (Math.random() - 0.5),
"--ty-4": (Math.random() - 0.5),
} as React.CSSProperties
}
...
- The
background-gradient
animation keyframes are used to animate the circles between these positions - Lastly, we blur the container element which holds the circles, to create a smooth effect.
If you would like to achieve a more complex animation, you have to edit the component directly, for example:
- Add more keyframe positions by increasing the number of
--tx
and--ty
variables - Use cubic-bezier timing functions to create non-linear movement
- Add rotation or scaling transforms
and so on.
Props
Prop | Type | Default | Description |
---|---|---|---|
colors* | string[] | - | Array of color strings to be used in the gradient |
speed | number | 5 | Speed of the animation (this is somewhat an arbitrary number, refer tothe source code for more details) |
blur | "light" | "medium" | "heavy" | "light" | Intensity of the blur effect |