Skip to main content

Layouts

Layouts allow you to arrange your nodes using Flexbox. Any node extending the Layout node can become a part of the layout. This includes, but is not limited to: Rect, Circle, and Img.

Layout root

Layouts are an opt-in feature, meaning that they need to be enabled. It's done by setting the layout property on the Node that we want to become the root of our layout:

// ↓ layout root
<Rect layout>
{/* ↓ layout child */}
<Circle width={320} height={320} />
</Rect>

In the example above, we marked the <Rect> as the layout root. This will cause the position and size of its descendants to be controlled by Flexbox (In this case there's only one valid descendant: <Circle>). The layout root itself is treated differently than its children - its size is controlled by Flexbox, but the position stays unaffected.

Just setting the layout property doesn't always turn the node into a layout root. If the node is already a part of the layout, it will be treated like the rest of the descendants:

// ↓ layout root
<Rect layout>
{/* ↓ layout child, NOT a layout root */}
<Rect layout>
{/* ↓ layout child */}
<Circle width={320} height={320} />
</Rect>
</Rect>

Size and offset

Aside from the position, rotation, and scale, any node extending the Layout class has additional size and offset properties:

Layout.size

API 文档

Layout.offset

API 文档

Cardinal directions

Layout nodes come with a set of helper properties that let you position them in respect to their edges/corners. In the example below we use them to place two squares on the left and right side of a gray rectangle. The yellow square is positioned so that its right edge is in the same place as the left edge of the rectangle. Meanwhile, the red square is placed so that its bottom left corner aligns with the bottom right corner of the rectangle. All possible directions include: middle, top, bottom, left, right, topLeft, topRight, bottomLeft, and bottomRight.

Click to preview animation

import {makeScene2D, Rect} from '@motion-canvas/2d';
import {createRef} from '@motion-canvas/core';

export default makeScene2D(function* (view) {
const rect = createRef<Rect>();

view.add(
<>
<Rect
ref={rect}
width={200}
height={100}
rotation={-10}
fill={'#333333'}
/>
<Rect
size={50}
fill={'#e6a700'}
rotation={rect().rotation}
// Try changing "right" to "top"
right={rect().left}
/>
<Rect
size={100}
fill={'#e13238'}
rotation={10}
bottomLeft={rect().bottomRight}
/>
</>,
);

yield* rect().rotation(10, 1).to(-10, 1);
});

Flexbox configuration

Most flexbox attributes available in CSS are available as Layout properties. You can check out this Flexbox guide to better understand how they work. The most useful properties are listed below:

Layout.padding

API 文档

Layout.margin

API 文档

Layout.gap

API 文档

Layout.direction

API 文档

Layout.alignItems

API 文档

Layout.justifyContent

API 文档

Groups

Nodes that don't extend the Layout class, such as the Node itself, are unaffected by the layout and are treated as if they were never there. This lets you apply filters and transformations to layout nodes without affecting the hierarchy.

From the layout's perspective, all <Rect>s in the example below are siblings:

<Layout direction={'column'} width={960} gap={40} layout>
<Node opacity={0.1}>
<Rect height={240} fill={'#ff6470'} />
<Rect height={240} fill={'#ff6470'} />
</Node>
<Rect height={240} fill={'#ff6470'} />
</Layout>