Craft / Animation
Waving Flag
Cut one flag into columns, stagger the motion, and make a flat image behave like cloth.
Demo
InteractiveThis is the finished component. Copy both files, keep the SVG in public, and change the three constants to tune the cloth.
import type { CSSProperties } from "react"
const COLUMNS = 24
const BILLOW = 0.8
const STAGGER = 50
export function WavingFlag() {
const firstDelay = -COLUMNS * STAGGER
return (
<span
className="waving-flag"
style={{ "--columns": COLUMNS } as CSSProperties}
role="img"
aria-label="Flag of India"
>
{Array.from({ length: COLUMNS }, (_, index) => (
<span
key={index}
className="waving-flag__column"
style={{
"--billow": `${index * BILLOW}px`,
animationDelay: `${firstDelay + index * STAGGER}ms`,
} as CSSProperties}
>
<img
src="/india-flag.svg"
alt=""
className="waving-flag__slice"
style={{ left: `${-index * 100}%` }}
/>
</span>
))}
</span>
)
}.waving-flag { display: inline-flex; width: 192px; height: 128px; }
.waving-flag__column { position: relative; flex: 1 0 0; overflow: hidden; }
.waving-flag__slice {
position: absolute;
top: 0;
height: 100%;
width: calc(var(--columns) * 100%);
max-width: none;
}
.waving-flag__column {
animation: wave 500ms ease-in-out infinite alternate backwards;
}
@keyframes wave {
from { transform: translateY(var(--billow)); }
to { transform: translateY(calc(var(--billow) * -1)); }
}The component has no runtime dependency. Use any rectangular image; the technique is not specific to a flag.