Loading component…
Components /Fluid Morph Background
Organic fluid shape morphing animation
"use client";
import React from "react";
import { motion } from "framer-motion";
import { cn } from "@/lib/utils";
interface FluidMorphBgProps {
/**
* Additional CSS classes for the container.
*/
className?: string;
/**
* The duration of the morphing animation in seconds.
*/
duration?: number;
/**
* The base color palette to use for the shapes.
* Array of hex colors for each path.
*/
colors?: string[];
/**
* Optional background color for the scene container.
*/
backgroundColor?: string;
}
export function FluidMorphBg({
className,
duration = 4,
colors = [
"#4f4fea",
"#0c27cf",
"#13269c",
"#242468",
"#2648e6",
"#2c31b0",
"#262689",
],
backgroundColor = "#282886",
}: FluidMorphBgProps) {
// SVG viewbox dimensions
const viewBox = "0 0 1440 800";
// Data for each morphing path
// path[0]: original "d", path[1]: "pathdata:id" (target morph shape)
const pathsData = [
[
"M -84.52,-81.13 C -94.62,-73.4 -88.88,-59.55 -90.33,-48.91 -89.29,27.31 -89.61,103.5 -88.33,179.8 -85.99,416.1 -81.32,888.9 -81.32,888.9 -81.32,888.9 974.5,888.7 1587,891.9 1518,719.9 1487,644 1429,533 1388,437.7 1447,259.7 1400,187 1362,132 1270,90.53 1207,39.93 1161,2.932 1071,-74.45 1071,-74.45 1071,-74.45 914.5,-77.77 848.2,-80.17 537.6,-80.84 227,-81.38 -83.6,-81.6 -83.91,-81.44 -84.21,-81.29 -84.52,-81.13 Z",
"M -84.52,-81.13 C -94.62,-73.4 -88.88,-59.55 -90.33,-48.91 -89.29,27.31 -89.61,103.5 -88.33,179.8 -85.99,416.1 -81.32,888.9 -81.32,888.9 -81.32,888.9 974.5,888.7 1587,891.9 1576,704.7 1517,625.7 1459,514.7 1418,419.4 1430,288.5 1382,187 1349,116.3 1296,54.47 1240,0.3429 1205,-33.51 1120,-83.59 1120,-83.59 1120,-83.59 914.5,-77.77 848.2,-80.17 537.6,-80.84 227,-81.38 -83.6,-81.6 -83.91,-81.44 -84.21,-81.29 -84.52,-81.13 Z",
],
[
"M 665.2,-83.08 C 413.7,-81.89 162.2,-82.43 -89.29,-81.61 -90.35,164.3 -85.06,410.2 -84.09,656.1 -83.37,733.7 -82.64,811.3 -81.92,888.9 442.4,889.8 966.7,890.7 1491,891.6 1253,747.5 1417,429.4 1286,245.4 1227,163.2 1107,142.1 1043,64.54 1009,24.41 973,-76.01 973,-76.01 973,-76.01 706.6,-83.67 665.2,-83.08 Z",
"M 665.2,-83.08 C 413.7,-81.89 162.2,-82.43 -89.29,-81.61 -90.35,164.3 -85.06,410.2 -84.09,656.1 -83.37,733.7 -82.64,811.3 -81.92,888.9 442.4,889.8 966.7,890.7 1491,891.6 1253,747.5 1349,460.4 1243,260.6 1199,176.6 1145,96.92 1083,24.95 1050,-12.63 973,-76.01 973,-76.01 973,-76.01 706.6,-83.67 665.2,-83.08 Z",
],
[
"M -85.01,-74.02 C -92.39,-66.64 -85.37,-55.79 -87.81,-46.91 -86.65,265.1 -84.66,577.2 -83.18,889.2 317.2,888.3 717.5,885.8 1118,890.4 1152,890.6 1187,890.9 1221,890 1219,768.3 1224,643.6 1187,526 1153,417 1091,319.3 1029,224.1 998.8,178.5 968.8,132.6 936.6,88.23 891.7,27.39 772.2,-78.96 772.2,-78.96 772.2,-78.96 222.1,-81.07 -85.01,-74.02 Z",
"M -85.01,-74.02 C -92.39,-66.64 -85.37,-55.79 -87.81,-46.91 -86.65,265.1 -84.66,577.2 -83.18,889.2 317.2,888.3 717.5,885.8 1118,890.4 1152,890.6 1187,890.9 1221,890 1219,768.3 1175,659.3 1150,544.3 1128,438.4 1143,312.6 1081,227.1 1004,121.1 925.8,114.8 851.3,54.73 762,-17.34 772.2,-78.96 772.2,-78.96 772.2,-78.96 222.1,-81.07 -85.01,-74.02 Z",
],
[
"M -92.42,-79.11 C -89.97,243.8 -87.52,566.7 -85.07,889.6 201.8,889.9 488.7,889.9 775.5,895.6 880.4,896.9 985.2,894 1090,892.5 1064,773.3 1037,651.6 976.1,544.8 946.7,495.8 914.6,448.3 882,401.3 820.9,314.4 742.3,252 666.4,177.4 583.2,98.01 496.5,12.18 386.7,-23.38 328.4,-45.64 232.6,-81.38 232.6,-81.38 232.6,-81.38 9.82,-84.94 -92.42,-79.11 Z",
"M -92.42,-79.11 C -89.97,243.8 -87.52,566.7 -85.07,889.6 201.8,889.9 488.7,889.9 775.5,895.6 880.4,896.9 1063,889.5 1063,889.5 1063,889.5 1081,768.2 997.4,608.7 958.5,534.8 969.9,436.8 918.5,370.8 848.4,280.8 717,260.3 629.9,186.5 552.6,121.2 491.5,38.73 426.3,-38.61 412.9,-54.44 387.9,-87.47 387.9,-87.47 387.9,-87.47 9.82,-84.94 -92.42,-79.11 Z",
],
[
"M -88.6,95.54 C -90.38,166.1 -88.23,236.7 -88.68,307.4 L -86.19,890 C 229.7,890.2 939.8,892.4 939.8,892.4 855.2,767 831,639.4 721.4,519.4 634.7,424.5 526.4,360.9 428.8,281.8 332.7,204 251.6,102.3 140.1,48.9 70.75,15.73 -24.82,24.2 -85.28,0.03 Z",
"M -88.6,95.54 C -90.38,166.1 -88.23,236.7 -88.68,307.4 L -86.19,890 C 229.7,890.2 939.8,892.4 939.8,892.4 906.9,734.7 779.3,676 721.4,519.4 676.8,398.8 566.5,307.1 458.9,236.6 355.2,168.7 220.3,165.7 107.8,113.5 40.05,82.12 -24.82,24.2 -85.28,0.03 Z",
],
[
"M -95.69,252.3 -87.65,890.4 698.1,892 C 698.1,892 599.1,687.7 518.9,610.6 348,446.2 131.4,466.5 -95.69,252.3 Z",
"M -95.69,252.3 -87.65,890.4 698.1,892 C 698.1,892 569.8,587.1 448.9,482.7 299.7,353.9 131.4,466.5 -95.69,252.3 Z",
],
[
"M -85.59,444.4 -85.59,890.6 489,895.6 C 489,895.6 436.8,745.3 382.5,690.8 258.1,565.8 57.98,629.2 -85.59,444.4 Z",
"M -85.59,444.4 -85.59,890.6 546.9,895.6 C 546.9,895.6 517.4,695.4 339.9,593.4 187.7,505.9 57.98,629.2 -85.59,444.4 Z",
],
];
return (
<div
className={cn("relative overflow-hidden w-full h-full", className)}
style={{ backgroundColor }}
>
<svg
className="absolute inset-0 w-full h-full object-cover"
preserveAspectRatio="none"
viewBox={viewBox}
>
{pathsData.map((dList, index) => {
// Each path gets a random duration variation for more organic feel (like original script did)
// To keep it simple in React/Framer Motion and avoid hydration issues,
// we use the duration prop as a base and vary slightly based on index.
const variance = (index % 3) * 0.5; // add 0, 0.5, or 1 sec
const pathDuration = duration + variance;
const delay = (index % 4) * 0.2; // slight delay offsets
return (
<motion.path
key={index}
d={dList[0]}
fill={colors[index % colors.length]}
animate={{
d: dList,
}}
transition={{
duration: pathDuration,
repeat: Infinity,
repeatType: "mirror",
ease: "easeInOut",
delay: delay,
}}
/>
);
})}
</svg>
</div>
);
}
Run the following command
npx shadcn@latest add https://vengeance-ui-v2.vercel.app/r/fluid-morph-bg.json1import { FluidMorphBg } from "@/components/ui/fluid-morph-bg"23export function FluidMorphBgDemo() {4 return (5 <div className="relative w-full h-[500px] flex items-center justify-center">6 <FluidMorphBg className="absolute inset-0" />7 <h2 className="relative z-10 text-white text-5xl font-serif">Fluid Life</h2>8 </div>9 )10}
| Prop Name | Type | Default | Description |
|---|---|---|---|
| className | string | - | Additional CSS classes for the container. |
| duration | number | 4 | The duration of the morphing animation in seconds. |
| colors | string[] | ['#4f4fea', '#0c27cf', ...] | The base color palette to use for the morphing shapes. |
| backgroundColor | string | '#282886' | Background color for the scene container. |