React
Canvas sizing, full core options, mutable props, Strict Mode cleanup, and imperative refs.
FlagCloth is a thin wrapper around the framework-independent core. It creates a container and core instance after mount, applies mutable options through setOptions(), and destroys the instance during cleanup.
import { useRef } from 'react';
import {
FlagCloth,
type Attachment,
type FlagClothInstance,
} from 'flag-cloth/react';
const attachment = {
points: [[0, 0], [0, 8], [0, 16], [0, 24]],
} satisfies Attachment;
export function Banner() {
const flag = useRef<FlagClothInstance>(null);
return (
<FlagCloth
ref={flag}
texture="/flag.webp"
width={3}
height={2}
segments={{ x: 40, y: 24 }}
attachment={attachment}
canvasWidth="100%"
canvasHeight={560}
wind={{ strength: 7, turbulence: 0.35 }}
interaction={{ enabled: true, dragRadius: 1 }}
onReady={(instance) => console.log(instance.stats)}
onError={(error) => console.error(error)}
/>
);
}Canvas size versus cloth size
These are separate measurements:
| Props | Purpose |
|---|---|
width and height | Physical cloth dimensions in simulation units. They control rest lengths and aspect ratio. |
canvasWidth and canvasHeight | CSS dimensions of the React-owned canvas container. They accept normal React CSS values such as 720, '100%', '60vh', or 'min(100%, 900px)'. |
The canvas fills that container. ResizeObserver updates its CSS viewport and GPU backing store without recreating the simulation. The backing-store resolution is additionally capped by renderer.maxPixelRatio.
You can use className or style instead when layout belongs in CSS:
<FlagCloth
className="flagViewport"
style={{ width: '100%', aspectRatio: '3 / 2' }}
texture="/flag.webp"
/>.flagViewport {
width: min(100%, 900px);
height: clamp(320px, 55vw, 600px);
}When both are supplied, canvasWidth and canvasHeight override the corresponding style dimensions. The container must resolve to a non-zero width and height before the renderer can draw.
Props
FlagClothProps contains every FlagClothOptions property except the vanilla-only container, plus:
| Prop | Type | Purpose |
|---|---|---|
className | string | Class on the canvas container. |
style | CSSProperties | Inline CSS on the canvas container. |
canvasWidth | CSSProperties['width'] | Explicit container width. |
canvasHeight | CSSProperties['height'] | Explicit container height. |
onReady | (instance) => void | Called after the initial texture is ready. |
onError | (error) => void | Receives initial texture or mutable-update errors. |
The full attachment union—including partial edges and custom points—is described in Attachments and pinning. Every other core default is listed in Configuration.
Mutable props
Changes to these props use the existing instance:
texture,attachment,wind,simulation,interaction,renderer,material,lighting,camera,visibility, anddebugwidth,height, andsegmentsrebuild cloth topology while preserving the canvas and WebGL2 contextcanvasWidth,canvasHeight,className, andstyleresize through normal browser layout andResizeObserver
advanced and autoStart are construction-time options. The four WebGL2 context attributes—renderer.alpha, antialias, desynchronized, and powerPreference—are also construction-time settings.
Particle positions and the animation loop never enter React state, so cloth animation does not cause React renders. Passing stable nested option objects with useMemo can avoid redundant setOptions() calls in frequently rerendering parents, but it is not required for correctness.
Imperative ref
The forwarded ref is the same FlagClothInstance returned by createFlagCloth():
<button onClick={() => flag.current?.reset()}>Reset</button>
<button onClick={() => flag.current?.pause()}>Pause</button>
<button onClick={() => flag.current?.resume()}>Resume</button>Use the ref for imperative events. Ordinary configuration should stay in props so React remains the source of truth.
Strict Mode
React Strict Mode's development mount/cleanup/mount cycle is safe. Every core instance owns and removes its animation frame, observers, Pointer Event listeners, GPU resources, optional debug panel, and library-created canvas during cleanup.