Rect

The primary building block. A rounded rectangle that also acts as a flex or stack layout container for its children.

0.0s / 4.0s

Usage

import { createScene, Rect } from '@motion-script/core';

export default createScene(function* (stage) {
  // A row container laying out three squares, separated by a gap.
  stage.add(
    <Rect group="row" gap={48} padding={44} cornerRadius={24}>
      <Rect width={130} height={130} fill="#6990DD" cornerRadius={14} />
      <Rect width={130} height={130} fill="#E8617C" cornerRadius={14} />
      <Rect width={130} height={130} fill="#F5C26B" cornerRadius={14} />
    </Rect>
  );
});

Props

PropTypeDefaultDescription
group'row' | 'column' | 'stack''stack'Layout mode for children
gapnumber | 'auto'0Space between children along the main axis. 'auto' distributes evenly
alignAlignName | { x: number, y: number }'center'Child alignment. A named position ('center', 'topLeft', 'bottomRight', …) or a per-axis vector: x: -1 left · 0 center · 1 right, y: -1 bottom · 0 center · 1 top
cornerRadiusnumber | CornerRadiusProps0Corner radius in pixels. Accepts uniform, per-corner, or per-axis shorthand
cornerStyle'rounded' | 'angled' | CornerStyleProps'rounded''rounded' for circular arcs, 'angled' for chamfered cuts

Size defaults

Conditionwidth defaultheight default
No children'fill''fill'
Has children'hug''hug'

If a direct child is 'fill' on the axis Rect would otherwise hug (its group's main axis — width for row, height for column, both independently for stack), that axis defaults to 'fill' instead, so the child has real space to fill into. See Size for the full rule.

Corner shorthands

cornerRadius and cornerStyle share the same shorthand grammar:

// Uniform
<Rect cornerRadius={16} cornerStyle="rounded" />

// Per-axis
<Rect cornerRadius={16} cornerStyle={{ top: 'rounded', bottom: 'angled' }} />

// Per-corner
<Rect
  cornerRadius={{ topLeft: 24, topRight: 24, bottomLeft: 0, bottomRight: 0 }}
/>

Animating

All props animate with .to(). Transition group to cross-fade between layout modes, or animate gap to expand/collapse spacing:

import { createScene, Rect, createRef, easeOut } from '@motion-script/core';

export default createScene(function* (stage) {
  const box = createRef<Rect>();

  stage.add(
    <Rect ref={box} group="row" gap={30} padding={44} cornerRadius={24}>
      <Rect width={130} height={130} fill="#6990DD" cornerRadius={14} />
      <Rect width={130} height={130} fill="#E8617C" cornerRadius={14} />
      <Rect width={130} height={130} fill="#F5C26B" cornerRadius={14} />
    </Rect>
  );

  // Expand gap
  yield* box().to({ gap: 100 }, 0.6, easeOut);

  // Switch to column
  yield* box().to({ group: 'column' }, 0.8, easeOut);
});

Animated child insertion and removal

const card = new Rect({ width: 130, height: 130, fill: '#6990DD', cornerRadius: 14 });

// Insert at index 1 with a 0.4 s transition
yield* box().addChildAt(card, 1, 0.4, easeOut);

// Remove index 0 with a 0.3 s transition
yield* box().removeChildAt(0, 0.3);

Notes

  • Rect is the only shape node that runs layout on its children. Row, Column, and Grid are invisible layout containers; Rect is the layout container that also draws a box.
  • In stack mode children are layered on top of each other and centered by default. Use align to shift them (e.g. align="bottomRight" or align={{ x: 1, y: -1 }}).
  • gap: 'auto' only applies in row and column modes.
  • See Layout for a full reference on sizing, padding, and flex.