← Files PicsartARCHIVED FILE
skills/motion/references/ASSET-COMPOSITION.md
6.03 KB · Oct 10, 2026 · 18:02 UTC
# Asset composition — build a scene from uploaded assets (the non-Figma compose step) This is Stage 2 for the **asset route**: the user uploaded photos / logos / screenshots / clips and you've agreed a concept + layout (grid, stack, collage, montage, single focus). Now turn that into a valid MP Scene. Unlike the Figma path there is **no layer tree and no coordinates handed to you** — you place every asset deliberately, so the composition is yours to author from the concept. **Obey [`COMPOSE-FUNDAMENTALS.md`](./COMPOSE-FUNDAMENTALS.md) throughout** — hosting/CSP, one Drive folder, live text + fonts, placement, treatment-from-the-catalogue, highest-level-tool-first, and the eye. The **tools are the same as the Figma path** — only the *ingest* differs (here: `upload` + `probe_media`, not the Figma connector). This file adds only the asset-specific ingest and layout. ## 1. Get the assets in, and MEASURED - **Upload → Picsart URL.** `picsart_media_upload` every file; author the returned `pastatic`/`gcdn` URL, **never** a `blob:`/`data:`/local path (CSP-blocked in preview). One Drive folder per project — the shared hosting/Drive rule, [`COMPOSE-FUNDAMENTALS.md`](./COMPOSE-FUNDAMENTALS.md) §2–4. - **An uploaded SVG logo/icon → a live shape, not a `media` layer.** Read its `<path>` `d`s and convert them with `picsart_media_import_svg_path` onto one shape layer (see [`TOOL-ROUTING.md`](./TOOL-ROUTING.md)), so it can recolor, draw on and scale cleanly. A PNG/JPG logo stays a `media` asset; don't trace a raster. - **Probe before placing.** `picsart_media_probe_media` each asset for real **dims / aspect / fps / duration**. You cannot size a photo into a cell or fit a clip without its true dimensions — never guess them from the thumbnail. - **View each asset** (your own eye) to know *what* it is and which way is up — see `SCENE-VALIDATION.md` (the eye works at the input end too). ## 2. Pick the composition approach — template first - **Scene template** — `picsart_media_apply_scene_template` (montage / collage / title families; browse with `list_scene_templates` / `describe_scene_template`). This is the fastest path to a grid, collage, or montage layout — it lands a valid, arranged scene you then drop assets into. - **Recipe** — `photo-promo` is the canonical "photos → a composed reel with transitions, blurred fill, and a readable title"; `ui-motion` for screenshots. Fetch it (`get_recipe`) before hand-building. - **Hand-place with `patch_scene`** only when no template/recipe fits the chosen layout — one `media` layer per asset, positioned by its `transform` (see §3). Constructing a whole scene op-by-op is the last resort, not the default. ## 3. Layout patterns — how to place assets Every asset is a `media` layer (`bounds` = its placed box, `fit` per below), z-order = paint order. - **Grid** — N assets in rows×cols. Compute cell size from the canvas minus gutters: `cellW = (W − (cols+1)·gutter) / cols` (same for height); each asset's `position` = its cell centre; `fit:"cover"` to fill the cell (crops overflow — **check the crop with the eye**) or `fit:"contain"` + a blurred fill behind (§4) to avoid gaps. - **Stack** — assets overlapping, each offset + a small rotation, z-order = stacking order; the top of the stack is the focal one. A "fan" is a stack with increasing rotation. - **Collage** — varied sizes and positions, larger for the hero; mind overlaps (they're intentional here, but verify nothing important is covered). - **Montage / sequence** — one asset full-frame at a time, as a **track of clips** with transitions between (this is the *only* one-asset-per-screen layout — `photo-promo` builds exactly this). - **Single focus** — one hero asset placed large/centred, the rest supporting (small, edged, or absent). ## 4. Size to the canvas — assets rarely match the target ratio - **`fit:"cover"`** fills the box and **crops** the overflow — the usual choice for a full-bleed photo, but the crop can cut off a head/product, so **verify on a rendered still**. - **`fit:"contain"`** shows the whole asset and leaves a gap — **never leave black bars**: fill the gap with a **blurred, scaled copy of the same asset** behind it (the `photo-promo` / `blur_fill` trick), or a solid/gradient backing that matches the concept. - Default `position` is the box centre; a portrait photo in a landscape canvas is `cover`-cropped or `contain` + blurred fill, never squished (never `fit:"fill"` on a photo — it distorts). ## 5. Text over assets — readable Titles/captions are **live text, font by resolved URL** (the shared rule — [`COMPOSE-FUNDAMENTALS.md`](./COMPOSE-FUNDAMENTALS.md) §5). The asset-specific part: keep it **readable over a busy photo** — a scrim/gradient backing or a drop shadow (`get_capabilities`), never raw text on a full-bleed image. ## 6. Validate — schema, then the eye `picsart_media_validate_scene` first (schema), then the **eye check** (`SCENE-VALIDATION.md`): render a `contact_sheet` still and look — is any asset **blank** (upload/CSP failed), **cropped** badly by its fit, **off-frame**, is the **grid aligned** (even gutters, no drift), does anything **overlap/leak** that shouldn't. There is no design to diff against here — the ground truth is the **agreed concept**; confirm the composition matches it before adding motion, then hand off to Stage 3 (working mode: part by part, or the whole motion at once). ## Mistakes - Authoring a `blob:`/`data:`/`figma.com` asset URL — CSP-blocked → blank in preview; upload first. - Guessing an asset's dimensions instead of `probe_media` — cells and fits land wrong. - `fit:"fill"` on a photo (distorts) or leaving **black bars** on `contain` (use a blurred fill). - Hand-placing a grid op-by-op when a **scene template** would land it in one call. - One-asset-per-screen by reflex — that's only the *montage* layout; grid/stack/collage put several assets on screen together (see the Stage-0 triage note). - Skipping the eye-check and shipping a scene that validates but has a cropped hero or a blank tile.
SHA-256: 056127fa140470429c591d67953dc4a95a2e356599f05e20a2230063a06c58d9