Skip to content

Transforms & Composition

Every primitive in Elucim accepts the same set of spatial and animation props. This uniform model means you learn the pattern once and apply it everywhere.

rotated groupzIndex: 2
0.00s / 2.97s · F0

Every element accepts three categories of props:

CategoryControlsExamples
PrimitiveWhat to drawcx, cy, r, fill, stroke
SpatialWhere / howrotation, scale, translate
AnimationWhenfadeIn, fadeOut, draw, easing

These compose freely on a single element:

<Circle
cx={200} cy={150} r={50} // primitive — what
rotation={45} translate={[10, 0]} // spatial — where
fadeIn={20} easing="easeInOut" // animation — when
stroke="#6c5ce7" fill="none"
/>

All primitives (and <Group>) accept these spatial props via the shared SpatialProps interface.

Rotation in degrees. By default the element rotates around its own center.

<Rect x={100} y={50} width={120} height={80} rotation={30} stroke="#6c5ce7" fill="none" />

Override the pivot point with an [x, y] coordinate:

<Rect x={100} y={50} width={120} height={80}
rotation={45} rotationOrigin={[100, 50]}
stroke="#6c5ce7" fill="none" />

A uniform number or an [sx, sy] pair. Values are unitless multipliers (1 = normal size).

<Circle cx={200} cy={150} r={40} scale={1.5} stroke="#e17055" fill="none" />
<Circle cx={200} cy={150} r={40} scale={[2, 0.5]} stroke="#00b894" fill="none" />

An [dx, dy] pixel offset applied before rotation and scale:

<Circle cx={100} cy={100} r={30} translate={[50, 20]} stroke="#fdcb6e" fill="none" />

SVG follows the painter’s model by default — elements declared later in JSX paint on top of earlier ones. The zIndex prop overrides this:

<Player width={300} height={200} fps={30} durationInFrames={60}>
{/* Declared first, but renders on top because of zIndex */}
<Circle cx={130} cy={100} r={50} fill="#6c5ce7" zIndex={2} />
{/* Declared second, but renders behind */}
<Rect x={100} y={60} width={100} height={80} fill="#00b894" zIndex={1} />
</Player>

Key rules:

  • Default zIndex is 0
  • Higher values render later (on top)
  • Ties preserve document order (stable sort)
  • Works on children of <Scene> and <Group>

<Group> is a container that applies transforms and animations to all its children as a single unit.

<Group rotation={15} translate={[50, 0]} fadeIn={20}>
<Rect x={100} y={50} width={200} height={150} stroke="#6c5ce7" fill="none" />
<Circle cx={200} cy={125} r={40} stroke="#e17055" fill="none" />
</Group>

What this does:

  • Rotate a group → rotates everything inside
  • FadeIn on a group → fades in everything together
  • Groups can nest — transforms compose through the hierarchy
  • Groups sort their own children by zIndex — each group creates its own stacking context

The spatial props described above are static — they set a fixed transform for the element’s lifetime. For animated transforms (interpolating between two states over time), use the <Transform> animation wrapper:

// Fixed 45° rotation — no animation
<Circle cx={100} cy={100} r={50} rotation={45}
stroke="#6c5ce7" fill="none" />

Use static transforms for layout positioning, and <Transform> when you need motion. See Transform & Morph for the full animation API.