Documentation
MoveMatic is a vector animation tool for product UI motion on macOS. Compose vector shapes, text, images, and video into multi-scene .mvm documents; animate every property with keyframes; add span effects, pulses, and camera zooms; and render the whole thing to MP4. This page is the complete reference.
Installation
Download the DMG from the MoveMatic page, open it, and drag MoveMatic.app into your Applications folder. macOS 14 Sonoma or later, Apple Silicon only.
Concepts
Three nested ideas drive everything else.
- Document — a
.mvmfile holds one or more scenes, a chosen active scene, and an optional document-wide audio bed. - Scene — a fixed-size canvas with its own duration, frame rate, background, layer tree, and timeline. Scenes are played back in order; each can declare a transition into the next.
- Layer — every visible thing on the canvas. Layers carry static properties (position, size, fill, stroke, corner radius, shadow, opacity, etc.) and time-based ones (visibility spans, keyframes, pulses).
The toolset is organized around those three: most edits happen in the Layer panel (organize), the Inspector (set properties), or the Timeline (animate).
Opening a document
- File → New (⌘N) creates an empty document with a single 1920×1080 scene.
- File → Open… (⌘O) opens an existing
.mvmfile. - File → Open Recent lists recently opened documents.
- ⌘S saves; ⌘⇧S saves a copy.
Each document opens in its own window. The title bar shows the filename and an Edited badge while there are unsaved changes.
Sample project
The DMG ships with two sample documents under Help → Sample Documents:
- Showcase.mvm — a four-scene, ~18-second promo built around a deliberate visual story (Hello, Motion, Stories, Ship It). It exercises every shipping layer kind, span effect, pulse target, and keyframable property. Good first thing to open.
- AllFeatures.mvm — a denser feature-parade test fixture. Useful as a reference but reads as a tour, not a story.
Canvas
The center of the window is the canvas — a fixed-size scene rendered with whatever's authored at the current playhead. Floating panels (layers, inspector, timeline, scene strip) overlay it as material-backed cards rather than pane splits.
Navigation
- Pan — drag empty canvas with Space held, or two-finger scroll, or drag with the middle mouse button.
- Zoom — pinch on the trackpad, or ⌘+ / ⌘-. ⌘0 fits the whole scene; ⌘1 zooms to 100%; ⌘2 zooms to the selected layer.
- ⌥-drag — duplicate-on-drag. If the drag begins over a layer the selected set is cloned and the copies move with the drag; if it begins on empty canvas it pans.
Selection chrome
Selected layers get an accent-colored dashed bounding box, eight resize handles, and a rotate handle above the top edge. Cropped images and videos wrap the chrome around the visible cropped sub-rect, not the original layer frame.
For freeform / arc / wave lines the rectangular bbox is suppressed in favor of per-anchor endpoint dots (with Start and End labels), which double as drag handles.
Click and drag
- Click on a layer selects it. ⇧-click or ⌘-click extends the selection.
- Click on empty canvas drops the selection. Click-drag from empty space draws a marquee that picks up every layer it touches.
- Click on a selected group, then drag — moves the group. A pure click (no drag) drills into the child under the cursor.
- The body drag is gated by a 4-point arming threshold so a click never accidentally nudges a layer with sub-pixel rounding.
Snap guides
Drag a layer near another layer's edges or center, the scene center, or the scene's edges and a yellow guide line appears with the alignment value. Hold ⌘ during the drag to bypass snapping.
Right-click context menu
Right-click anywhere on the canvas to insert layers, paste, group / ungroup, manage z-order, hide / lock, and reach a Select Layer submenu that lists every layer within 20 pt of the cursor (sorted nearest-first). Handy when layers overlap and a regular click would always pick the top-most one — the menu lets you target an obscured layer directly.
Layer panel
The Layer panel is the floating card on the upper left. It shows every layer in the active scene as a tree — groups expand into their children — with the Scene pseudo-row at the top.
Rows
Each row has, left to right: indent, disclosure chevron (for groups), kind icon, fill swatch, name, hidden / locked badges, and a timeline-pin "meatball" target.
- Double-click a row name to rename inline.
- Right-click a row for context actions: Rename, Reset Name, Duplicate, Group, Ungroup, Hide / Lock, Reset Timeline, Replace Media…, Delete.
- Hidden layers show an eye-with-slash badge and dim out. Locked layers show a lock badge and reject canvas edits. Click the badge to toggle it back off — un-hide / unlock without going through the context menu.
Scene pseudo-row
The top row labeled Scene stands in for "nothing selected" — clicking it clears the selection so the Inspector pivots to scene-level properties. Its trailing anti-meatball (a slashed dot) unpins every layer's timeline pin in one click. ⌥-clicking the anti-meatball does the opposite — pins every layer in the scene (groups + descendants).
Selection
- Click a row to select it. ⇧-click for range, ⌘-click to toggle.
- ↑ / ↓ arrows navigate vertically; ⇧↑ / ⇧↓ extend the selection.
- → / ← expand / collapse the focused group (or step into / out of it when already open).
- Tab cycles selection through siblings at the current depth (root → next root, or within a group's children). ⇧Tab steps backward. Both wrap.
- Return drills into every selected group at once — expands each, then replaces the selection with the union of all their direct children. Empty groups just expand.
Drag-reorder
Drag any row to a new position. An accent-colored line marks the drop slot. When the dragged row is part of a multi-selection, every selected layer rides along (the payload is newline-separated UUIDs; drops preserve relative stacking).
Pin to timeline
The small dot at the right of each row is the timeline pin. Click it to keep that layer's timeline rows visible even when the layer isn't selected on canvas — handy for editing layer A's timing while picking colors on layer B.
⌥-clicking a group's pin expands the group AND pins every descendant in one click — a fast way to bring a whole folder's timing into view.
Scene strip
The scene strip is a thin band of chips above the timeline showing every scene in the document. Click a chip to jump to that scene; drag to reorder; right-click for Rename, Duplicate, Delete.
The active scene is highlighted. Transitions are rendered as short connector pills between chips; click one to set its kind (Fade, Slide, Push, Zoom) and duration.
Rename opens a modal sheet — double-click the chip OR pick Rename from the context menu. The sheet's text field is auto-focused with the existing name selected, so you can type to replace. Return commits, Esc cancels. The Inspector's scene-name field is still inline (auto-focused on new-scene creation), so creating a new scene drops you straight into the typing surface.
Timeline
The Timeline panel docks across the bottom of the window. Its content depends on what's selected: nothing selected shows the aggregate tracks across the whole scene; selecting layers reveals their per-layer rows.
Common chrome
- Transport — Jump to start, frame back, play, frame forward, settings, scrubber. Scrubber tracks the playhead live.
- Timecode readout — shows
seconds · frame/total. - Ripple toggles — two arrow pills floating beside any selected timeline bar / marker, indicating push items before / push items after directions. See Ripple editing.
- Music chip — the document audio bed's filename, with a chevron menu to relink / volume / remove.
Per-layer rows
Each selected (or pinned) layer renders a stack of rows:
- Visibility — colored span bars for every
TimeSpanon the layer. - Video (video layers only) — the clip's scene range, with source-trim handles.
- Pulses (opt-in; appears when a pulse exists) — circular markers with optional duration tails.
- Keyframes — one diamond strip per animated property.
When a group is the sole layer shown, children-aggregate rows appear under it: visibility / video / pulses / keyframes / behaviors / motions scoped to that group's subtree. Empty buckets are hidden.
Inspector
The Inspector is the floating card on the upper right. It always reflects the primary selected layer; multi-selection edits fan out across every other selected layer in the same gesture.
Common rows: Transform (X, Y, Rotation), Size (W, H, Corner radius), Appearance (Fill, Stroke with a solid / dashed / dotted style, Opacity slider, Shadow), Animation (Origin, Cursor override, Motion Trails), plus kind-specific sections (Text font / size / color, Video clip range, Line shape, etc.). Opacity, Blur, and many other scalar rows use a unified slider control (rail + editable value + arrow-step + label scrub).
Multi-select offsets are preserved. Scrubbing or stepping a property with multiple selected layers offsets each one by the same delta from its own baseline. Before scrub: multiple. After scrub: still multiple. Typing a specific value into the field is still a "set them all" action.
Text: harmonize. A checkbox next to the text-color swatch derives the glyph color as a hue-preserving darker shade of the layer's fill — one-click readable foreground for chip-style buttons. The swatch is disabled (and the cursor flips to 🚫) while harmonize is on; flip it off to set the color directly. Only shows for fills that aren't fully transparent.
Claude Assistant
A second tab on the Inspector hosts an embedded Claude conversation that can read and edit the active scene. Enable it in MoveMatic → Settings → Assistant, paste your own Anthropic API key, pick a model (Opus 4.7, Sonnet 4.6, or Haiku 4.5), and a "Assistant" segment appears next to "Properties" in the Inspector header.
- Ask in natural language. The assistant has tools to read the scene and apply structured patches.
- Each turn lands as a single undoable edit — named after the turn so the undo menu reads "Undo Make every text fill cyan" rather than "Undo Edit."
- Friendly per-tool-call summaries appear in the transcript; "Copy transcript" sends the whole exchange to the clipboard for sharing.
- Your API key stays in
NSUserDefaultson your Mac and is only sent toapi.anthropic.comwhen you submit a turn.
Mix & Match
Select a row of layers and choose Arrange → Mix & Match… (or right-click the selection on canvas). A sheet lets you toggle which property categories to redistribute across the selection — Fill, Stroke Color, Stroke Width, Shadow, Corner Radius, Width, Height, X, Y, Rotation, Font, Font Size, Text Color, Text Content — then commits the whole shuffle as a single undo step.
- Bias slider. All the way left: pure shuffle — values get permuted within the selection, so no new value is introduced. Slide right and each destination layer pulls a fresh value sampled from the pool's min–max range. Useful for "vary these cards a little" vs "completely re-mix them."
- Distribute as set. When on, every enabled property uses the same source layer per destination, so layer A's whole look transfers to layer B in one move. Off: each property is permuted independently — a faster way to feel out unusual combinations.
- Text content pool. Text-content shuffles work off a comma-separated pool. Pre-fills with the current selection's text so you can extend it (add more candidate strings) before committing.
- Discrete properties (Shadow presets, Font names) always shuffle — the bias slider doesn't apply because there's no continuous range to sample from.
Layer kinds
Layers are added from the palette at the bottom-left of the canvas (the "+" button menu) or via the layer panel's "+".
- Rectangle — fill, stroke (uniform or per-side), corner radius, shadow.
- Ellipse — same set as rectangle, no corner radius.
- Text — string, font (PostScript name), size, color, optional bounding box (fill + stroke + corner radius).
- Line — multi-shape: freeform polyline with optional Catmull-Rom smoothing and arrowheads; preset closed shapes (square, circle, triangle); preset open shapes (arc, wave). Arc has a bend slider (-10…10) and a length multiplier that scales the curl on long arcs; wave has a frequency / amplitude pair, with frequency snapped to half-cycle increments so both endpoints sit on the layer's midline. Arc bend and wave amplitude scale with the line's width; arc and wave hide their Width / Height fields (the geometry is the length), and converting a line to a circle squares its height to its width.
- Image — PNG, JPEG, HEIC, etc. Imported via drag-and-drop onto the canvas, or via the palette. Supports crop and stroke around the cropped region.
- Video — H.264 / HEVC / etc. Stored by file URL plus a security-scoped bookmark so a moved file silently relinks. Carries multiple clips per layer, each with its own source range, speed, end behavior, and an optional Freeze Frame mode. See Videos.
- Cursor — animated SwiftUI cursor in one of a dozen variants (Arrow, Pointer, Grab, I-beam, etc.) plus a Wait throbber. Treated as an animatable cursor sprite, not an interaction layer.
- Hotspot — invisible rectangle that overrides any cursor layer's variant when the cursor's bbox intersects it. The only "interaction region" kind.
- Zoom — camera viewport. See Camera zoom.
- Group — container with optional auto-layout. Groups have their own transform, opacity, span effects, and pulses, which compose with their children's.
- Gradient Field — procedural two-color drifting gradient with warp speed and pulse amount; good for backgrounds.
- Particle — region that emits primitives or layer clones. Configurable rate / lifetime / direction / gravity / scale / opacity curves; emits from its own frame OR from any chosen scene layer (line layers contribute curvature). See Particles.
Groups
Select two or more sibling layers and press ⌘G (or Arrange → Group) to wrap them in a group. ⌘⇧G ungroups, baking the group's transform / scale / rotation / layout / pulses into each child so the visual position is preserved.
Grouping is supported at any depth. A group inside a group rotates and scales with its parent; nested children's keyframes, span effects, and pulses all play correctly through the parent chain. The only restriction is that grouping requires every selected layer to share a parent — cross-parent selections disable the Group command rather than silently re-homing layers.
Return on a group selects its direct children. With multiple groups selected, every group expands and the selection becomes the union of all their children.
Size mode
Groups carry a Size Mode toggle in the Layout section:
- Dynamic (default): the group's bounds are the union AABB of its laid-out children. Resizing isn't meaningful — you change child positions or layout to change the group.
- Fixed: the group has its own explicit W and H independent of contents. A purple translucent rect (same vocabulary as a Zoom layer's chrome) appears on canvas with standard 8-corner resize handles. The first flip from Dynamic to Fixed seeds W/H from the current children-derived bounds, so the on-screen rect doesn't jump.
Fixed groups carry a floating lock pill in the rect's top-right corner. Locked (default): moving the rect moves the children with it — historical group-drag behavior. Unlocked: moving the rect leaves the children where they are, useful for sliding a "viewport" frame around the contents.
Auto-layout groups
Groups have a layout mode in the Inspector — Freeform (default), Horizontal, or Vertical. In Horizontal or Vertical, children are stacked along the chosen axis with a configurable gap and alignment (start, center, end), like a CSS flex container. Per-child X (or Y) keyframes are ignored along the laid-out axis; everything else still animates.
The groupGap is keyframable, so you can animate cards spreading apart and back together as a single coordinated breathing motion.
Selection & reorder
- Marquee — drag from empty canvas to draw a selection rect. Every layer whose AABB intersects gets picked.
- Multi-select duplicate — with multiple layers selected, ⌘D duplicates them all; ⌥-drag clones the whole set.
- Bring forward / send backward — ⌘] / ⌘[. To-front and to-back are ⌘⇧] / ⌘⇧[.
- Align & Distribute — under the Arrange menu. Each acts on the selection set in scene space.
Auto-naming
Rectangles, ellipses, lines, text layers, cursors, and videos auto-name themselves based on a salient attribute and stay synced as you edit:
- Rectangles: "<color> Rectangle" from fill.
- Ellipses: "<color> Ellipse" from fill.
- Lines: "<color> <shape>" from stroke + lineShape (e.g. Coral Wave).
- Text: the first line of the text content.
- Cursors: the variant label.
- Videos: the source filename minus extension.
The moment you type your own name in the inspector or the layer-panel rename field, auto-naming turns off for that layer. Right-click → Reset Name turns it back on and re-derives. The menu item hides itself for shape / line / video layers that are already at their auto-derived default, so the menu doesn't show dead options.
Visibility spans
A visibility span is a time range during which a layer renders. Layers without any spans are visible everywhere by default; the visibility track itself is opt-in and only appears once a layer has at least one span.
- Drag a span's body in the timeline to move it; drag either edge to resize.
- Click a span to surface it in the Inspector as Span on <Layer>, with start / end times and the effect list.
- Add a span from the layer header's + menu → Visibility (disabled when the playhead is already inside an existing span). Adding the first one makes the visibility track appear.
- The aggregate Visibility row collapses spans that share start/end across layers into one bar; dragging it moves every contributing span.
- Layers with no authored timeline content (no spans, pulses, motions, behaviors, keyframes, or video clips) get a thin placeholder row so the playhead's vertical line still reaches the layer's space.
Span effects
Each span carries up to one intro effect (plays at the span's start) and one outro effect (plays at the span's end), plus optional secondary effects. They stack — a span with Fade In + Slide In Left as intro will do both simultaneously over the effect's duration.
Available effects
- Fade In / Fade Out — opacity ramp.
- Pop In / Pop Out — overshoot scale spring (0 → 1.08 → 1.0).
- Bounce In / Bounce Out — multi-bounce eased scale.
- Slide In / Slide Out — Left / Right / Top / Bottom, four directions each.
- Type On / Delete Off (text only) — reveal / hide characters from the start.
- Draw On / Erase Off (line only) — animate the line's drawn length. Each has its own direction toggle (arrow.left.circle / arrow.right.circle in the inspector) — flip drawOn's direction to grow from the end inward, or flip eraseOff's to erase from the start. They're independent.
- Blinking Cursor Start / End (text only) — pulsing caret glyph at the start or end of the typed text.
Group span effects pivot scale / rotation around the laid-out children's content centroid rather than the group's stored origin, so a Pop In on a group expands outward from the visible content's center, not from an off-content reference point.
Pulses
A pulse is a one-shot beat at a specific time. The layer plays a short envelope (~1 second) firing one or more of three independent effects:
- Scale — brief size bump (1 → 1.15 → 1) with sine easing.
- Glow — triple-stacked accent-color drop shadow that fades in and back out.
- Radiate — three concentric rings emanating outward from the layer's center, staggered, each with a dark base outline so the rings read on any background. The layer's own silhouette covers its rings; layers below it in z-order get painted over.
Drop pulse markers on the per-layer pulse row, or aggregate across the scene. The inspector lets you toggle each effect, set its trigger time, and (for groups) inherit downward to children.
Keyframes
Every animatable property has its own track and its own diamond strip. To create a keyframe:
- Edit the property in the Inspector; the small diamond next to the field flips to a filled accent color and a keyframe is recorded at the current playhead.
- Or click the diamond directly — it snapshots the current value.
- Or press ⌘K to snapshot every transform / size / opacity property at once.
Drag a diamond in the timeline to retime; click to select and surface its row in the Inspector with time, value, easing, and wait. Multi-select diamonds with ⇧-click or marquee to retime in bulk.
Animatable properties
X, Y, Rotation, Scale X, Scale Y, Opacity, Fill, Stroke, Stroke Width, Width, Height, Corner Radius, Shadow, Cursor variant, Group Gap, Font Size, Font Name, Text Color, Line Arc Bend, Line Wave Frequency.
Easing
Each keyframe carries an easing curve that governs interpolation into the next keyframe: Linear, Ease In, Ease Out, Ease In/Out, Spring (with stiffness + damping), and Cubic (CSS-style four-point bezier).
The inspector's easing picker fans across the timeline's multi-selection: when every selected keyframe shares a preset the picker shows it; when they disagree the picker shows a blank label, and any selection from the menu writes the new preset to every selected keyframe in one undo entry.
Wait keyframes
Each keyframe also carries a wait value: hold the keyframe's value for N seconds after its time before interpolating to the next. Equivalent to authoring a paired keyframe at time + wait, but expressed as a single field so retiming the source diamond pulls the wait along with it.
Visually, waits render as a translucent tail off the right side of the diamond on the timeline.
Behaviors
Procedural property animators that drive a layer's value over a time range without authored keyframes. Add one from the layer header's + menu — each behavior targets a single keyframable property (X, Y, rotation, scale, opacity, font size, line bend, …). Behaviors render as yellow bars on the property's timeline row; drag the body to move, drag an edge to resize.
Three kinds:
- Oscillate — sine wave between a min and a max at a chosen frequency. Min, Max, Frequency. Phase optional.
- Shake — random jitter inside a min–max range. Magnitude is controlled by the range.
- Wiggle — smooth random walk (seeded). Lower frequencies feel like drift; higher feel like tremor. Randomize the seed via the inspector's dice icon.
While a behavior's window covers the playhead, the behavior's evaluator wins — keyframes on the same property still resolve at the window's start for the baseline, but the behavior's output is what renders inside the window. Outside the window, keyframes resume.
Motions
Layer-level animators that move the whole layer over a time range. Added from the layer header's + menu. Motions render as orange bars on a dedicated per-layer Motion row.
- Follow Layer — attracts the layer's position toward another scene layer's center over the motion's window. Pick the target via the layer picker. Optional orbit-on-arrival keeps it circling once it's close. The aggregate Follow row shows fused bars.
- Follow Path — moves the layer along a chosen line layer (freeform, arc, wave, circle, square, triangle). Knobs:
- Ping-pong with a cycles count (0.5 increments, so a single return is 0.5).
- Loop (closed shapes only) — mutually exclusive with ping-pong.
- Tilt — rotate the layer to match the path's tangent.
- Tilt per-letter (text layers) — each glyph rotates to the tangent at its own arc position.
- Upright letters — flip glyphs that would otherwise read upside-down on a steep tangent.
Motions claim their target properties (X, Y, plus rotation when Tilt is on) for their window, the same way Behaviors do — keyframes on those properties are bypassed inside.
Target picker & end state. A follow's target rows are labeled Target Layer (Follow Layer) and Target Path (Follow Path), and a layer is excluded from its own picker. Each follow ends with a chosen end state — by default Stick, which holds the followed position once the window ends. Follow Path leads with a Transition to Start duration that eases the layer onto the path before the path motion begins (hidden when the entry mode is Snap).
Motion trails
Turn on Trails in the Inspector's Animation section and a moving layer leaves a short series of fading ghost copies at its recent positions — a motion-blur-style echo that traces the path of the motion. Enable it on a group and the whole composite trails together. Trails render identically on the canvas and in exported MP4 / PNG output, and are purely visual: they add no layers and don't affect hit-testing or selection.
Particles
A particle layer is a region that spawns rendered particles over time. Inspector sections:
Shape
The rendered primitive per particle — Circle, Square, Triangle, Diamond, Pentagon, Hexagon, Star, Ring, plus the option to Choose Layer… and clone one of the scene's own layers (text glyph, an image, a shape, a group) as the particle shape. Cloned particles inherit the source's full rendering.
Emitter
A single menu defining where particles spawn:
- Rectangle / Ellipse / Border / Point — emission shape inside the particle layer's own frame.
- Choose Layer… — pick any other scene layer as the emission source. The particle layer's bbox binds 1:1 to the chosen non-line source. For line sources the polyline is sampled at 200 evenly-spaced u-values so the cloud hugs the actual stroke (freeform curves, arcs, waves, circles all supported). An inline x next to the menu clears back to in-layer mode.
Emission, Motion, Life curve, Render
- Rate + Lifetime.
- Speed, Speed ±, Direction, Direction ±, Gravity.
- Rotation start, Rotation ±, Angular velocity.
- Scale start / end, Opacity start / end.
- Blur per-particle gaussian, Seed (re-rollable).
- Tint gradient — sample each particle's color from a gradient across the emitter, projected onto a chosen angle.
- Clip to Frame — when on (default), particles can't render past the particle layer's bbox. Off lets them drift indefinitely on velocity / gravity.
Aggregate tracks
With nothing selected, the timeline renders collapsed rows across every layer in the scene — one per track type that has any content:
- Visibility — bars sharing the same (start, end) across multiple layers fuse into one. Dragging a fused bar moves every contributing layer's matching span by the same delta.
- Video — one bar per clip across every video layer (multi-clip layers contribute multiple bars). Grouped video layers fold in too.
- Keyframes — diamonds at every unique time; a marker showing how many layers' keyframes share that time.
- Pulses — markers at every unique time.
- Behaviors — fused yellow bars when multiple layers' behaviors share a (start, end). Same drag / trim / ripple semantics as the visibility aggregate.
- Follow (motions) — fused orange bars across layer-level motion ranges.
Clicking a fused marker opens a small popover listing each contributing layer so you can drill in. When a single group is the timeline's sole layer, the per-layer rows are followed by these same aggregate rows scoped to its children's subtree — visibility, video, keyframes, pulses, behaviors, and motions all participate.
Timeline selection
Spans, pulses, keyframes, and video clips are independently selectable on the timeline. Click for single, ⇧-click for additive, marquee for batch. The selection drives:
- Inspector contents (single span → span editor; single keyframe → keyframe row; multi → bulk-edit mode).
- Delete behavior (⌫ removes every selected item).
- Ripple anchor (the dragged item's original position seeds the snapshot — see Ripple).
Snapping
Drag-snap is split into two layers, both configurable from the timeline's settings sheet:
- Grid increment — quantize every drag to a chosen step: Frame, 0.1s, 0.25s, 0.5s, or 1s.
- Proximity targets — toggles for "also snap to" the playhead, visibility / video span edges, keyframes, and pulses. Anything within ~6 px of the cursor's quantized position pulls it onto the target time.
Hold ⌘ during a drag to bypass snapping entirely for fine adjustments.
Set In / Set Out
With one or more spans (or video clips) selected on the timeline:
- I — set each selected item's in (start) to the current playhead. If the playhead is past the item's end, the whole item slides instead of inverting.
- O — same, but for the out (end).
Both honor the current ripple toggles: with ripple on, the trim's delta cascades through every captured before / after item the same way a body drag would, and the "Ripple moved N items" toast fires so the silent shift is visible.
Ripple editing
Ripple mode shifts the rest of the scene's timeline content by the same delta as the primary drag, like a tracking shot. The two toggles — push items before and push items after — pick which side of the dragged item's anchor goes along for the ride.
- R cycles the toggles: off → before → after → both → off.
- Direction pills appear on any selected timeline bar / marker once a ripple direction is on, so you can see at a glance what's coming with you.
- Ripple applies to every drag and every trim (span body, span edge, pulse marker, keyframe, video clip; I / O; the Move / Distribute / Expand / Contract / Retime modals).
- Items pushed past the timeline's duration extend the scene to fit; pulled back inside the original duration shrink it back to where it was at drag-begin (never below).
- The captured anchor is the dragged edge's original time, so trimming a span's left edge ripples the items before that edge (with push-before on); trimming the right edge ripples items after the new right edge.
Move, Expand / Contract & Retime
A group of batch modal sheets under the Timeline menu: Move… (⌘⇧M), Distribute… (⌘⇧D), Expand / Contract… (⌘⇧E), and Retime…. Each previews its result non-destructively on the real timeline as you adjust, and commits as a single undo step — Cancel restores exactly what was there before.
- Move… — shift every selected item by a delta (typed in seconds) or to a snap target (the playhead, a specific time, the earliest item's start).
- Expand / Contract… — scale every selected item's time around an anchor (the selection's start, center, or end), optionally stretching item lengths along with the gaps. Useful for "make this whole intro 30% faster" without retouching each keyframe. (Formerly "Dilate.")
- Retime… — a table of every selected item with editable Start and Duration fields; rows reorder live as their timing changes, and the whole set applies at once when you click Retime.
All honor ripple toggles — non-selected items shift to keep the rest of the scene aligned with the user's edit. The toggles ARE the global Push Before / Push After; flipping them inside a modal flips them everywhere else, and vice versa.
Distribute
Kind-agnostic — pick 2+ timeline elements of any mix (visibilities, video clips, keyframes, pulses, behaviors, motions) and choose Timeline → Distribute… (⌘⇧D). One sheet, two modes:
- Sequential lays the items end-to-end from the earliest start, separated by a chosen gap — a staircase of bars or beats.
- Cascade fans the items out from a common start by a chosen amount, in one of four orders (earliest-first, layer top-down, layer bottom-up, or random), with a spacing curve to spread or compress the gaps.
Like the other batch sheets, Distribute previews on the real timeline, runs as a single undo step, and respects the global ripple toggles for items outside the selection.
Timeline zoom
The timeline cycles between three zooms — fit all (1×), 4×, and 8× — via the Z keyboard shortcut. The 4× and 8× modes show a context minimap above the tracks for navigation across the larger-than-window timeline.
- Toggle via the magnifier in the timeline toolbar, or with Z.
- While zoomed in, two-finger horizontal scroll pans the visible window; the minimap shows where it sits in the full scene.
- The minimap's window can be dragged or its edges resized to move / zoom the viewport.
Multiple scenes
A document can hold any number of scenes. Each scene has its own size, frame rate, duration, background color, start- and end-pause (holds of the first frame before the timeline animates and the last frame after it runs out), and layer tree.
- Add scene — ⌘⇧N, the "+" on the scene strip, or Scene → New Scene.
- Duplicate active scene — Scene → Duplicate. Adds " Copy" to the name and inherits size / fps / duration / background from the source.
- Delete — right-click a scene chip → Delete. A document always keeps at least one scene.
- Reorder — drag scene chips. Playback follows array order.
- Rename — double-click a chip's title. Empty names fall back to Scene N.
Scene transitions
Between any two adjacent scenes you can drop a transition. Click the connector pill between scene chips to open the transition picker.
- Fade — cross-fade between the outgoing last frame and the incoming first frame.
- Slide Left / Slide Right — outgoing scene slides off in the chosen direction.
- Push — outgoing pushes out as incoming pushes in (matched motion).
- Zoom — outgoing scales out while incoming scales in.
- None — hard cut.
Duration is configurable per transition. A scene's endPause field lets you hold the last frame for an extra N seconds before the transition starts — useful for letting a finished animation breathe.
Audio bed
A document can carry one continuous audio track that plays across every scene during preview and is muxed into the exported MP4. Set it via Scene → Document Audio… or the music chip on the scene strip.
- Pick any audio file (MP3, AAC, M4A, WAV). A security-scoped bookmark is stored alongside the path so moved files silently relink.
- Volume is per-document, 0…1.
- The track auto-fades over the last second of the final scene so exports don't end with an abrupt audio cut.
Images
Drag any image file onto the canvas to add it. Multi-drag drops every file at once, fanned out by 20pt down-right so they don't all land on the same pixel.
- Image bytes are inlined into the
.mvmdocument on save — there's no relink dance for images. - Layer size on add defaults to the source's natural pixel dimensions, capped at 600pt on the long edge.
- Stroke around the image follows the cropped (visible) region, not the original layer frame.
- Right-click → Replace Image… swaps the source without disturbing the layer's transform, animations, or selection. If the new image has a different aspect a dialog asks whether to keep the layer's current frame or resize to the new natural aspect.
Videos
Pick a video file via the palette or drag-drop it. MoveMatic supports anything AVKit can decode (H.264 / HEVC / ProRes / etc.).
Multiple clips per layer
A video layer holds a list of video clips — each clip places a portion of the layer's source on the scene timeline at its own start / end, with its own trim, speed, and end behavior. The Video row renders one bar per clip; all bars share the layer's single source file.
- Add Clip — the + in the row gutter adds a clip from the playhead to scene end (or from
0when the playhead is already inside another clip). Right-clicking the row also exposes Add Clip. - Duplicate Clip — right-click a clip → Duplicate. Clones with a fresh id, shifted right by the original's length so the two don't overlap.
- Split at Playhead — right-click a clip → Split at Playhead. The second half's
sourceStartadvances by the elapsed source-time so the cut is seamless. - Delete — right-click → Delete, or select the clip and press ⌫.
- Newly added or duplicated clips are auto-selected so the inspector dives straight into the new clip's properties.
Source vs scene time
Each clip carries a source range plus a scene range. Dragging the bar's body moves the clip in scene time; dragging the left edge trims into the source; dragging the right edge truncates the rendered length. Clips snap to the standard timeline targets (other clips' edges, span edges, keyframes, pulses, playhead).
Trim sheet
Click Trim… in the video clip inspector to open a dedicated trim sheet:
- A 24-thumbnail filmstrip and a large preview pane.
- Frame-precise In and Out integer-frame fields with ↑ / ↓ stepping (⇧ × 10) and a total-frame readout.
- Drag either yellow handle to move that endpoint; drag the body in between to translate the whole range — a dashed white ghost of the original range stays visible and the leading / trailing edge snaps back to either ghost endpoint (4 candidates, nearest wins within ~14 px). The snap fires a cyan highlight on the ghost.
- Hover playhead — moving the cursor over the strip without clicking shows a thin cyan playhead and live-scrubs the preview to that source frame.
- I / O set In / Out at the cursor's current source-time (hover position when hovering, otherwise the last-touched handle). They override even a focused frame field — the field commits its pending edit, then the action lands.
End behavior
When scene time runs past the source's natural end, the clip can:
- End — go blank (the clip's outpoint stops playback).
- Loop — wrap modulo the source duration.
- Freeze Frame (end) — hold the last frame.
- Loop Back and Forth — ping-pong the source.
Freeze Frame mode
The clip inspector's Mode toggle flips between Video (normal playback) and Freeze Frame. When Freeze Frame is on, the trim / playback / end-behavior knobs disappear and the inspector shows a mini-filmstrip, a large preview, and an integer-frame input. The chosen frame renders for the entire span — extend the clip's right edge indefinitely past the source duration and it stays held. Useful for "card holds" between cuts.
Speed
Each clip has a Playback Speed field (0.01% – 10000%). Scrub the label or arrow-step the field by 1% (⇧ × 10, ⌥ ÷ 10). The bar in the timeline rescales so the rendered duration always matches the trimmed source ÷ speed.
Relink & missing sources
Video files are referenced by file URL + security-scoped bookmark. If a file moves, MoveMatic silently relinks via the bookmark on next open. If a file is genuinely gone, the layer shows a striped placeholder ("Video missing") and the layer panel's right-click menu surfaces Replace Video… to point at the new location.
Audio
Each video clip carries its own audio that's muxed into the exported MP4 alongside the document audio bed, at the clip's scene timing.
Stroke
Videos accept the same stroke options as images — color, width, position (inside / outside), per-side widths. The stroke wraps the visible cropped region, with rounded corners matching the layer's cornerRadius.
Cropping
Images and videos both support cropping via the Crop toggle in the Inspector.
- Off — the source fills the layer frame.
- Auto (legacy / video-only) — detect a black-keyed source window and mask everything else to transparent. Insets X and Y let you tune the detected bbox.
- Manual — open the Crop editor by clicking Edit Crop…. A modal sheet shows the source at native resolution with eight handle controls; drag handles to set the crop rectangle, arrow keys to nudge by one pixel (⇧ = ten), Auto snaps to a detected source window, Reset drops the crop back to identity. Esc cancels; ⌘Return commits.
The crop editor's loupe is pixel-accurate — zoom in close and the source's actual pixels are visible without resampling.
After a manual crop the inspector's X / Y read the visible top-left position rather than the underlying layer-frame top-left, and the 3×3 origin grid maps cells to the visible cropped sub-rect's corners / edges / center. Selection chrome, the stroke, and the rounded mask all line up with the visible content.
Camera zoom
A Zoom layer is a camera viewport — for the duration of its visibility span, the rendered scene "lenses into" the layer's rectangle.
- Full screen mode: the whole canvas zooms into the rectangle. Use for hero-shot moments — drop a zoom layer over a single button at the end of an animation and the playback gracefully closes in on it.
- Picture-in-picture mode: the captured rectangle is rendered into a child rect somewhere else on the canvas, like a sticky note showing a detail from another part of the scene. The child rect is its own layer with its own transform, animations, span effects, and pulses.
- Zoom span edges carry their own start / end transition picker: a smooth animated zoom-in, a fade, or a hard cut on each side independently.
- Zoom layers are invisible at edit time except for their outline so you can drag the bounds; during playback / export they're consumed entirely.
Export to MP4
File → Export… (⌘E) opens the export sheet.
- Target — Current Scene, All Scenes (joined by transitions), or a specific scene by name. The last choice is remembered.
- Output filename — defaulted from the document name + target.
- Motion blur samples — Off, Fast (2× ½-res), Light (4×), Medium (8×), Strong (16×). Each sample is rendered at a different sub-frame time and averaged. Fast renders at half resolution into an off-screen bitmap; close to indistinguishable quality on real motion at roughly an eighth of Light's cost. The renderer also skips the blur pass on frames where nothing actually moves during the shutter window, so long static stretches export at single-frame speed regardless of the setting.
- Output scale — 1×, 2×, 3×. Multiplies the scene's pixel dimensions in the output.
- Include audio — toggle the document audio bed + every video clip's audio into the muxed output.
Export is non-blocking — a progress sheet shows percentage, current frame, and a live preview snapshot updated every ~10Hz. Cancel via the sheet's Cancel button or Esc.
The rendered MP4 matches the live canvas pixel-for-pixel: same layer kinds, same span effects, same pulses, same scene transitions, same zoom-camera mapping. If there's a visible difference you found a bug — file it.
Keyboard shortcuts
File & document
| Shortcut | Action |
|---|---|
| ⌘N | New document |
| ⌘O | Open document |
| ⌘S | Save |
| ⌘⇧S | Save a copy |
| ⌘W | Close window |
| ⌘E | Export MP4 |
| ⌘Z / ⌘⇧Z | Undo / Redo |
Canvas
| Shortcut | Action |
|---|---|
| ⌘+ / ⌘- | Zoom in / out |
| ⌘0 | Fit scene to canvas |
| ⌘1 | Zoom to 100% |
| ⌘2 | Zoom to selected layer |
| Space drag | Pan |
| ⌥ drag | Duplicate-on-drag (over a layer) / Pan (empty space) |
| ⌘ drag | Bypass snapping |
| ⇧ drag | Constrain motion to a single axis |
| ↑ / ↓ / ← / → | Nudge selection by 1pt (⇧ = 10pt) |
| L | Toggle aspect lock on width / height |
| ⌫ / Delete | Delete selection |
Selection & layers
| Shortcut | Action |
|---|---|
| ⌘A | Select all layers in active scene |
| ⌘D | Duplicate selection |
| ⌘G / ⌘⇧G | Group / Ungroup |
| ⌘] / ⌘[ | Bring forward / Send backward |
| ⌘⇧] / ⌘⇧[ | Bring to front / Send to back |
| ↑ / ↓ (layer panel) | Navigate rows (⇧ = extend) |
| → / ← (layer panel) | Expand / collapse group (or step into / out of) |
| Tab / ⇧Tab | Cycle through siblings at the current depth |
| Return | Drill into every selected group (selection becomes their children) |
Timeline
| Shortcut | Action |
|---|---|
| Space | Play / Pause |
| ← / → (timeline focus) | Step one frame back / forward |
| ⇧← / ⇧→ | Step 10 frames back / forward |
| Home / End | Jump to scene start / end |
| ⌘K | Snapshot keyframes for every transform / size / opacity property at playhead |
| I / O | Set In / Set Out on every selected span / video clip (honors ripple) |
| R | Cycle ripple direction: off → before → after → both → off |
| Z | Cycle timeline zoom: 1× → 4× → 8× → 1× |
| I / O (Trim sheet) | Set In / Out at the trim sheet's cursor source-time — overrides focused fields |
| ⌘ drag | Bypass timeline snapping |
| ⌘⇧M | Open the Move… modal |
| ⌘⇧D | Open the Distribute… modal |
| ⌘⇧E | Open the Expand / Contract… modal |
Scenes
| Shortcut | Action |
|---|---|
| ⌘⇧N | New scene |
| ⌘⇧→ / ⌘⇧← | Next / previous scene |
Languages
MoveMatic is localized into English, Deutsch, Español, Français, Italiano, Nederlands, Polski, Português (Brasil), Українська, 日本語, 한국어, 简体中文, and 繁體中文. It picks the right language automatically based on your System Settings → General → Language & Region preferences.
To pin MoveMatic to a specific language without changing system preferences, open System Settings → General → Language & Region → Applications, click the + button, and pick MoveMatic.
Documents created in a non-English locale also auto-name their scenes and layers in that language — Szene 1, 사각형 1, Ellisse 2 — so the layer panel reads naturally instead of dropping back to English defaults. Renamed layers persist as you typed them across locale changes.