Docs

Repeat shapes and text

A fixed-count for draws copies of one native vector or text source. Change the count or a modifier to reshape the whole pattern; saving keeps one compact structure.

imagine dot
  shape: circle
  radius: 4
  fill: "#ff9955"
imagine field
  for 28
    id: orbit
    seed: 42
    create dot
    modifier grid as startingShape
      columns: 7
      gap: (24, 24)
    modifier circle as orbitShape
      radius: 100
      amount: 0
      animate amount from 0 to 1 over 1s ease "ease-in-out"
create field

The source is resolved once. Copies have stable zero-based indices and seeded variation. They are rendered geometry, never hundreds of saved create lines. Loop and modifier IDs are generated from their initial order and saved automatically. An explicit loop id gives inspection a readable name. Modifier IDs are saved automatically, and an optional as alias labels the step.

Order and strength

Modifiers run from top to bottom. Grid, Circle and Scatter blend the incoming position toward a generated position by amount (default 1). Circle with orient: outward also blends rotation toward its outward angle. A full 360° circle omits the duplicated endpoint; a partial span includes both ends. Grid indexes rows from top to bottom. gap measures center-to-center distance.

Transform adds position and clockwise rotation. It multiplies scale and opacity toward their targets and mixes fill toward a static linear color. Noise adds deterministic smooth offsets to incoming positions and rotation. Its input uses the incoming coordinates, frequency, evolution and seed. It is independent of seek history. Source and owner transforms compose in the normal coordinate system.

See the generated modifier reference for parameters and defaults. Unknown modifiers and unconsumed modifier parameters fail validation.

Selection and time

selector accepts all, even, odd, first, last, an index, or an inclusive range such as "2-5". Even includes index zero. A modifier's stagger: 0.04s delays its animated state by selected rank. Nonparticipants keep their incoming state. disabled: true retains a modifier while skipping its evaluation.

Expression value Meaning
each.index, each.count Original domain index and fixed count
each.progress Index divided by count minus one; zero for one copy
each.rank, each.selectedCount Rank and size within the current selection
each.rankProgress Rank divided by selected count minus one; zero for one selected copy
each.seed Deterministic integer derived from loop seed and original index
each.position.x, .y Position entering the current modifier

Numeric expressions use the existing compiled expression engine. Source position, scale, rotation and opacity may use numeric expressions or animation; transforms accept XYZ tuples. Source fill also supports compiled hsl() and mix() expressions; mix() endpoints may be colors, color defines, or nested mix()/hsl(). Tracks are applied in authored order, only to copies in each track's selection. Keyframes replace an expression-valued base on those copies; unselected copies retain their base or earlier track. Live constant edits refresh prepared geometry, keys, modifier parameters and color endpoints. Color defines follow root → owner → source scope, with the source define taking precedence. Static shape properties and animation keys resolve scoped constant defines. Unsupported copy expressions produce a diagnostic. General property references are not supported in copy expressions.

For static tuples use scale: (1, 0.5 + each.progress). Dotted component paths belong to animate scale.y ...; static scale.y: is unsupported syntax and produces an ignored-line diagnostic.

Linear falloff

Transform may have an inline falloff: linear with position, clockwise rotation, positive scalar scale, expand, feather, curve, and invert. It samples the incoming copy position. With defaults, weight is 1 on the negative X side; positive feather fades from the boundary toward positive X. Rotation turns this boundary. expand shifts it along that axis; scale scales the distance. The effective modifier strength is selection × falloff × amount. Falloff parameters are static in this implementation.

Scope and compatibility

Native shapes can have fill and stroke; their primitive order stays copy-major. Effects belong on the owner and affect the composed result once. Nested loops, source groups, SVG sources, per-copy text content, masks, effects and animated geometry are not supported in this slice. The owner may still have ordinary content and children. Editor controls, Path and non-linear falloffs remain deferred.

Existing files keep the same format version. A previously retained fixed-count loop now draws when its source is supported. Older builds retain its source and seed but do not render copies and may discard modifiers when saving. Legacy indexed loops remain ignored. Keep an untouched source when using an older editor.

Loops support up to 10,000 copies each and 20,000 copies across the scene, including hidden groups. Repeated fills and strokes together are limited to 20,000 primitives. Larger patterns produce a validation error.

Performance depends on the artwork and device. Animated modifiers, stagger and noise evolution add work for each copy; static patterns cost less to play.

Text and shared unit modifiers

A source can also be a text blueprint. Copies reuse its shaped glyphs and font resources. Letter, word, and line animations stay inside each copy; loop modifiers act on copies. Loop fill modifiers blend over the final glyph paint in authored order, including glyph color animations and text fill modifiers. An amount of zero leaves that paint unchanged. each follows its authored scope.

imagine title
  text: "LUMIERE"
  fontFamily: "Anton"
  fontSize: 100
  fill: "#d3eaff"
  animate position.y from -30 to 0 over 0.5s
    selector: all
    stagger: 0.04s
imagine chrome
  for 7
    id: layers
    create title
    modifier transform
      position: (each.index * 2, -each.index * 2, each.index)
create chrome as chromeTitle

The same modifiers can go directly inside a text blueprint, with selector: all, all words, or all lines. They run in authored order after glyph animations. Word and line modifiers transform each selected unit about its current glyph-center centroid, preserving its internal arrangement. Selection, rank, stagger, falloff, deterministic noise, and animation timing use the shared unit machinery. A modifier domain is bounded to 1,000 letters, words, or lines, independently of the copy limit. Scene duration includes modifier tracks and the stagger tail of their selected units. Replicated text keeps its text-unit timing; copy stagger is counted once. Independent blueprint duplication preserves modifiers and their animation keys. Text without modifiers keeps its existing limits. Instance effects still apply to the composed result.

Copy source animations now use the text-unit animation evaluator, including ordinary blend and weight; transforms support XYZ. Existing vector scenes keep their selection and replacement order. Source text layout stays shared: per-copy text strings, font changes, nested loops, and solid extrusion are not part of replication.

Text replication is bounded to 16,384 shaped glyph primitives per scene, in addition to the existing copy limits. Larger results produce a validation error.