Ymotion
Help
Dashboard
All pages

Getting started

Images and designs

Pictures instead of films — a post, a poster, a grid or a carousel — one canvas cut into pieces, exported as PNG, JPEG or WebP.

A document can be a film or an image. An image is made from everything a film is made from (photos, text, shapes, icons, templates, masks, mattes, filters, layer styles, nested compositions) and drawn by the same engine, but it has no timeline: it is one picture, on one canvas, which can be cut into pieces that are exported as pictures. It is what a social post, a poster, a thumbnail, a cover, a grid or a carousel is.

What an image is

An image is one moment on one canvas of 16 to 30000 pixels a side. Nothing in it moves, so a keyframe has nothing to move between: an image refuses a keyframe in words, and the reply gives the call that sets the value instead. It holds no sound, no video layer, no motion blur and no speed, and refuses those in words too, with the call that does the job. When an older image is opened, the reply names its repairs and any content it cannot show. A saved video layer is named for replacement with one of its frames; opening does not silently turn that video into a photo. Templates are held at their poster (below), and what a template plays inside itself stands still with it.

Starting one

First check the current document with an old-list call:

ymotion_doc {"action":"list"}

If your tool list declares kind, then start the image:

ymotion_doc {"action":"new","kind":"image","name":"launch post","width":1080,"height":1350}

The size is pixels, and every length inside is a fraction of it, exactly as in a film, so an image can change size later without anything moving. These are the sizes worth offering, with their pixels:

  • Square post "width":1080,"height":1080
  • Portrait post "width":1080,"height":1350 — 4:5, the tallest a feed shows whole.
  • Tall post "width":1080,"height":1440 — 3:4.
  • Story "width":1080,"height":1920 — 9:16, full screen on a phone.
  • Landscape post "width":1080,"height":566 — 1.91:1.
  • Pin "width":1000,"height":1500 — 2:3.
  • Link post "width":1200,"height":630 — The picture a shared link shows.
  • Video thumbnail "width":1280,"height":720
  • Presentation "width":1920,"height":1080
  • Channel banner "width":2560,"height":1440
  • Wide header "width":1500,"height":500 — 3:1.
  • Cover "width":1584,"height":396 — 4:1.
  • A4 "width":2480,"height":3508 — 210 x 297 mm at 300 dpi.
  • US Letter "width":2550,"height":3300 — 8.5 x 11 in at 300 dpi.
  • A3 "width":3508,"height":4961 — 297 x 420 mm at 300 dpi.
  • A2 "width":4961,"height":7016 — 420 x 594 mm at 300 dpi.
  • Poster 18 x 24 in "width":5400,"height":7200 — At 300 dpi.
  • Square slides "width":1080,"height":1080 — A carousel's slides all share the first slide's shape; Instagram takes up to 20.
  • Portrait slides "width":1080,"height":1350 — A carousel's slides all share the first slide's shape; Instagram takes up to 20.
  • Tall slides "width":1080,"height":1440 — A carousel's slides all share the first slide's shape; Instagram takes up to 20.
  • Landscape slides "width":1080,"height":566 — A carousel's slides all share the first slide's shape; Instagram takes up to 20.
  • Story slides "width":1080,"height":1920 — A carousel's slides all share the first slide's shape; Instagram takes up to 20.

A print size is the paper's size at 300 dots an inch. With no size at all, the image takes the size of the first photo placed in it, its own pixels, the way a film takes its first video's; that photo goes on the whole canvas. It holds 1080x1350 until then:

First ymotion_doc {"action":"list"}; if your tool list declares kind, then:

ymotion_doc {"action":"new","kind":"image","name":"from a photo"}

Cuts and pieces

A cut is a line the whole way across the canvas, at a fraction of its width or its height. The pieces are the cells between the cuts, numbered from 1 in reading order: rows top to bottom, each row left to right. Each piece is one exported picture, so a carousel of six slides is one canvas six slides wide, cut into six pieces, and a 3x3 grid is one picture cut into nine. Piece 0 is the whole canvas, uncut, wherever a piece is named. An image holds at most 48 pieces, each at least 16 pixels a side. In an image a cut is a line across the picture; in a film a cut is in time.

setCuts places the cuts, by count or by fraction, and never moves a pixel of the canvas:

ymotion_edit {"ops":[{"verb":"setCuts","args":{"columns":3,"rows":3}}]}

"x" and "y" give the cuts as fractions instead, [0.25,0.5]; an axis left out keeps its cuts, and [] or "columns":1 takes them away. Four verbs change the canvas itself, and take no piece:

  • insertPieces adds a piece after one ("after":3), and removePieces takes one out ("from":2): the canvas grows or shrinks by a piece, and everything wholly past it moves with it. The reply names anything left across the edge, and what went with the pieces taken out. These act on a whole column by default; "axis":"y" acts on a whole row, including a stack with no column cuts. A structural edit is refused if a locked layer would have to move; it is never partly applied.
  • setCanvasSize makes the canvas another size and keeps every pixel where it is, anchored at "horizontal" (left, centre, right) and "vertical" (top, middle, bottom). A flat ground stretches to the new canvas; anything it cannot keep exactly, the reply names.
  • resize scales the whole picture to a new size: every photo keeps its size against the canvas's short edge, past its own pixels when the canvas grows, and anything that covered the canvas is fitted again. A shape's width and height are fractions of the frame's two sides, so a shape stretches when the canvas changes shape; the reply says so.
ymotion_edit {"ops":[{"verb":"setCanvasSize","args":{"width":5400,"height":1350,"horizontal":"left"}}]}

Working in a piece

An image's content write can take "piece" (whole-canvas changes take none): inside a piece, positions, sizes, type sizes, fit and align are that piece's, exactly as they are the canvas's in a film, and reading a layer gives the numbers of the piece it lives in. A new thing goes in piece 1 unless another is named (one placed into a composition with hostId goes on the whole canvas), and an op on layers runs in the piece they live in, so a title nudged near a cut stays in its piece. Piece 0 is the whole canvas. An image that is not cut is one piece, so piece 1 is the whole canvas and nothing changes.

ymotion_edit {"ops":[{"verb":"addLayer","args":{"piece":2,"content":{"kind":"text","text":"02"}}}]}

duplicateLayer with "piece" puts the copy in that piece at the same numbers there, which is how one title goes on every slide; a copy of a layer that rides another stays with it, and the reply says so. If an inferred piece cannot be worked in on its own, the op can use the whole canvas and says why. An explicitly named piece is refused; "piece":0 is the deliberate whole-canvas alternative.

Photos

Place an upload as you would in a film. In an image it lands in piece 1, or the piece "piece" names, on a row of its own, and is fitted whole when it is larger than the piece. A photo never arrives larger than it is: a smaller one keeps its own size, because a photo scaled up is pixels the camera did not take.

ymotion_media {"action":"place","id":"<media id>"}

To fill its piece with it instead, fit it with "how":"cover"; a photo that covers a piece is cropped to it, so nothing runs into the next. In piece 0 it covers the whole canvas, across every cut:

ymotion_edit {"ops":[{"verb":"fitToComp","args":{"layerId":"<layer id>","how":"cover"}}]}

A photo's colours are taken as they are stored: one tagged Display P3 or Adobe RGB, as an iPhone's are, is drawn as sRGB on the stage and in the export alike, and an exported picture carries no colour profile. A WebP is upright as stored, whatever its EXIF says, as the browser shows it; a JPEG or a PNG is turned by its EXIF orientation.

Held-photo admission counts the source's decoded size, fitted to the decoder's supported pixel ceiling, rather than its small box on the canvas. A large photo used as a thumbnail still holds those source pixels. The export and the look admit and release them by the pictures they draw, with a bound on the pixels held together; a stack that needs the whole frame can need every photo at once. A file larger than its stored dimensions is counted again when decoded. A resource refusal explains what could not be held rather than silently reducing export quality.

A video placed in an image becomes one of its frames: the picture the export would show at "from" seconds into the file, stored as its own picture and placed like a photo. The reply names the second taken. A frame is an upload, held to the account's storage like any other.

ymotion_media {"action":"place","id":"<video id>","from":3.5}

Text, shapes, icons and templates

addLayer, placeIcon and placeTemplate work as in a film, and in an image each puts its layer in piece 1, or the piece named, on a row of its own. Type sizes are a percentage of the piece's short edge; positions are fractions of the piece from its centre. See Units and Typography.

ymotion_edit {"ops":[{"verb":"addLayer","args":{"content":{"kind":"text","text":"New season"}}}]}

Type and shapes given no colour start as the design page starts them, because a film's white would not show on a white canvas: type in the ground's ink, near-black on a light ground and white on a dark one, a filled shape in blue, and a line or an arrow in the ink. A colour that is given, a text style.paint or a shape's fill, is kept.

A template is a moving thing, so in an image it is held at its poster: the moment where everything is on screen and at rest. Its values still change with setTemplateParams: ordinary value changes rebuild at the instance's stored composition size and keep its placement. An explicit refit follows its current home piece; changing the cuts does not silently resize an ordinary parameter rebuild. A button is placed in a state an image can show, because an image has no moment for a press to come at: most as they are before the press, a like button already liked. The reply names the values it started from, such as pressAt 60, and giving any of them chooses otherwise. Keys, moves, a cursor and a length are kept, and the image shows only what they hold at its poster; the reply says which moment that is.

Layer styles (a stroke, a drop shadow), blend modes, masks, track mattes, filters and grades all apply as they do in a film. Of the presets, the grades and looks apply; the moving ones write keyframes and are refused.

Across a cut

A photo or a line of type can run across a cut and carry on into the next picture when the person swipes; the reply to an op says when something does. A stroke, a shadow, a blur and a sharpen across a cut are one picture with the piece beside it: each piece is painted past its edges by as far as they reach. Keep type a little in from each cut: a phone's crop can reach about four percent of a piece's width into it.

What is placed against the whole canvas, not a piece: a vignette, a distortion's centre, and a gradient whose box is the frame span the whole canvas, so across a cut they are one picture over every piece, not one to each.

Removing a photo's background, and the cut-out

To remove a photo's background, cut the photo itself out with "place":"only" and "subject":"object": the photo's main subject, whatever it is, stays, and everything round it goes. A photo where nothing stands out is said so and left as it is. Putting things behind a person gives the call under "A photo, and removing its background".

The person in a photo, or any object in it, is cut out with the same call as in footage, made once on a GPU and kept beside the upload, and comes back as one layer. With "place":"above" it sits right over the photo, which stays behind it, so text on a track between the two passes behind the subject; with "only" the photo itself is cut, and the picture shows the subject alone. "select":true shows the selection on the photo first, as a picture, before anything is made. Putting things behind a person gives the call, by the photo's layer, and the rest of it.

Looking at it

An image is one moment, so its look is selected by pieces or a region rather than a timeline. "times", "count", "from", "to" and a nonzero "t" are refused. A top-level "layerId" is refused: look at a layer by a "region" of its id instead. With nothing named, a cut image is an overview: one sheet with a tile for every piece, labelled by its number and size. The gaps show the cuts. An uncut image is its one picture.

ymotion_render {}

If your tool list declares pieces, then:

ymotion_render {"pieces":[1,2]}

A selected look gives separate pictures, up to eight at once; a larger selection is one labelled sheet. "pieces":0 is the whole canvas, uncut. Ordinary looks fit the largest piece to the preview's long edge without enlarging its own pixels; "full":true asks at the design's own pixels. Each piece is painted as a window at the export's Best sampling: it costs that window and the effects that reach it, rather than allocating the whole canvas unless a stack needs it. A reduced preview shows the same framing; a full look is the size for checking fine detail.

A numeric "region" with one named piece is four fractions of that piece, [x,y,width,height] from its top-left. If your tool list declares pieces and region, then:

ymotion_render {"pieces":[2],"region":[0,0,0.5,0.5]}

A layer-id region is of the whole canvas and cannot be combined with a named piece. A seam, where a cut parts two pieces, is a numeric region of the whole canvas: an image's summary gives one ready for each cut, half of each neighbour either side. A region paints those pixels with the same margins as their export; a stack that requires the entire frame still pays that frame's surface and can be refused at its resource limit.

Exporting

An image exports as its pieces, each painted at its own size, never a large render scaled down:

ymotion_render {"what":"export","format":"png"}
  • PNG is exact and keeps transparency where the image leaves any. WebP is exact too, and usually the smallest for type and shapes, up to 16,383 pixels a side. JPEG is quality 95 with full colour detail, put on white, since a JPEG has no transparency: lossy, and the smallest for photos. There is no quality setting.
  • Size. "width" is the long edge in pixels of the largest picture asked, its own or larger: text and shapes are drawn again at that size and photos are sampled from their full resolution. An export is never smaller than the design; resize the design for that.
  • Which pieces. Every piece when none are named; if your tool list declares pieces, "pieces":[1,3] is those, and "pieces":0 the whole canvas, uncut.
ymotion_render {"what":"export","format":"jpeg","width":2160,"pieces":[1]}

One piece is one picture. Several are one archive of pictures named for the image and numbered in reading order (launch post-01.png, launch post-02.png); the whole canvas is launch post.png. The person downloads them by the export's link, or from their Exports page, like any export; <link>/<n> is the n-th picture alone. A grid is posted last piece first, so the reply says the order; Instagram crops every slide of a post to the first one's shape, and takes 20 a post. An image's pictures are no video, so exporting them uses none of the minutes a film's export counts. The exports list says what each export is, such as Image · 6 pictures · PNG. See Exporting a film for how an export is followed, shared and removed: an image's is the same, and takes seconds.

A preview link opens at piece 1 with the export's Best sampling. The person can move through its pieces with the dots, arrows, keys or a swipe, or view the whole canvas. It starts with its first piece as its cover too; an image has no playback clock:

ymotion_render {"what":"preview"}