--- name: remotion-character-design description: How to build and animate 2D (SVG) and 3D (@remotion/three) characters and mascots for FlatRender Remotion templates. Use when a template needs a character — a mascot, Haji Firuz, animals (goldfish, butterflies), people, or any articulated figure. Covers construction from primitives, rigging via grouped transforms, animation cycles (walk/dance/idle), facial expression, and the 2D-vs-3D / GLTF trade-offs. --- # Character design for Remotion We have NO rigged 3D model assets and the asset CDNs are geo-blocked, so characters are built from **primitives** — SVG shapes (2D) or Three.js geometries (3D) — and animated off `useCurrentFrame()`. Reference implementations: `NowruzGreeting.tsx` (2D Haji Firuz, goldfish, butterflies) and `Nowruz3D.tsx` (3D scene). ## Core principle: build in parts, rig with groups A character = a tree of grouped parts, each animated by transforming its group around a PIVOT. - 2D: nested ``. Put the pivot at the joint (e.g. shoulder) by translating the group there, drawing the limb from origin, and rotating the group. - 3D: nested ``. Same idea — position the group at the joint, model the limb from there, rotate the group. ## 2D characters (SVG) Construction kit: - Head = ``; body = `` trapezoid (`M.. Q..`); limbs = `` (rounded) or ``; hands/feet = small ellipses; hat = `` triangle/cone. - Face (friendly/stylized): two dot eyes, a `Q` curve smile, rosy `circle` cheeks at low opacity. Keep it simple — over-detailing reads worse, not better. - Skin/clothing: flat fills + one darker shade for a soft AO at edges (`fillOpacity` overlay). Animating cycles (all from `frame`): - **Idle/breathe:** body `scale.y = 1 + 0.02*sin(frame/30)`. - **Dance/bounce:** whole body `translateY = -abs(sin(frame/7))*H`, plus a small `rotate(sin(frame/7)*4)` sway; legs counter-rotate. - **Limb swing:** `rotate(amp*sin(frame/period))` around the joint pivot. - **Hop-in entrance:** `spring()` from off-frame X to the target, then switch to the idle/dance loop. - **Prop shake (tambourine, flag):** `rotate(sin(frame/3.2)*18)` + sparkle accents on peaks. ## 3D characters (primitives) Build the figure from: `sphereGeometry` (head/joints), `cylinderGeometry`/`capsule` (limbs/torso), `coneGeometry` (hat/skirt), `RoundedBox` (blocky bodies), `torusGeometry` (rings/mouth). Group per limb for articulation. Material: `meshStandardMaterial` (roughness ~0.5 for cloth, lower for shiny). Light with `three-kit` StudioLights; add a soft contact shadow (a dark blurred plane or `shadows` + a floor). - 3D animation is the SAME math (rotate/translate groups by `frame`), just in 3D space and you can also move the camera/scene for parallax. - Faces in 3D are hard — keep them simple (sphere eyes, a small torus/curve mouth) or face the character slightly away. ## Animation principles (what makes it not look stiff) - **Anticipation:** dip before a jump, wind-up before a throw. - **Squash & stretch:** scale on impacts/landings (subtle: ±8%). - **Overlap / secondary motion:** hat ball, scarf, string, ears, tambourine lag behind the body — offset their phase. - **Easing:** `Easing.out(Easing.cubic)` for arrivals, `spring()` for bouncy pops, never linear for organic motion. - **Hold:** let a pose read for a beat before the next move. ## Cultural / brand-safety notes - Default to a **modern stylized** look (friendly, non-realistic) unless the user asks otherwise. Specifically for Haji Firuz: red costume + conical hat + tambourine, but a friendly non-blackface face (avoids the blackface connotation). - Confirm a storyboard with the user BEFORE building complex characters (the project convention) — list the cast, the beats, and the look. ## When NOT to hand-build - Photoreal humans or complex rigged motion → out of scope without GLTF assets; propose a stylized take or a non-character design instead. - If a GLTF model IS provided, load with drei `useGLTF` and animate transforms by `frame` (no `useFrame`). ## Workflow Storyboard → build parts → rig groups → animate cycles → **render stills at 3-4 beats and LOOK** → refine → render all 3 aspects (see `remotion-aspect-ratios` — characters must sit in the safe zone in 9:16 too). Related: `remotion-design-styles`, `remotion-aspect-ratios`, `remotion-template-catalog`.