Repository navigation
Design transform
Krita splits its transform tool into five modes — Free Transform (move/rotate/scale/shear), Perspective (corner + vanishing-point drag), Warp (grid/point displacement with Rigid/Affine/Similitude falloff), Cage (closed-polygon deformation via generalized barycentric coordinates), and Liquify (brush-painted displacement). See the Krita transform tool manual.
Animation is where every raster tool struggles. Krita's own answer is the transform mask: a non-destructive transform attached to one layer (or group), tweenable since 5.0 via the animation-curves docker. It cannot transform the drawings themselves across a range of frames: users report going frame by frame with the transform tool to keep elements aligned (community discussion). Photoshop's video timeline has the same shape: Free Transform touches one layer at one time; batch moves need smart-object surgery. The reason is structural — for a raster tool, every transformed frame is a fresh resampling of pixels, so a 24-frame transform is 24 destructive resamples and 24 undo records.
Lightbox does not have that constraint. Frames are stroke records; a
transform is a deterministic geometry operation on StrokePoints. Applying
the same operation to 200 frames is 200 cheap point-map passes with zero
generational quality loss (strokes re-render through BrushEngine at full
fidelity), one undo step, and a record the AI inbetweener can still read.
That is the unfair advantage this milestone exploits.
A transform session has a target scope chosen in the tool options:
| Scope | What is transformed |
|---|---|
| Active cel | The exposed drawing on the active layer at the playhead (classic Ctrl+T). |
| All layers at this frame | Every visible layer's exposed drawing at the playhead — move a whole composed pose. |
| Selected cel range | The cels marked with the timeline range selection (Set start/end), on that layer. |
| Entire animation | Every drawing on every layer — reframe/rescale the whole shot. |
Rules that make ranges safe:
-
Deduplicate by
Frame.Id. Holds expose the sameFrameinstance on several timeline columns; a scope collects distinct frames so nothing is transformed twice. - Region limiting. If a selection is active when the session starts, only strokes whose points lie (majority) inside the selection mask are transformed — in every frame of the scope. This is "enlarge this part of the document across all frames": select the region once, pick a range scope, scale. Strokes are moved whole (no point-tearing) in v1; soft boundary falloff is a warp-phase follow-up.
-
One undo step. The whole session commits as a single
Performsnapshot, whatever the scope size.
- Affine (move/scale/rotate, uniform or free): closed-form 3×2 matrix built from the gizmo (pivot, scale x/y, angle, translation). Applied to every stroke point. Brush size scales with √(|sx·sy|) so lines thicken proportionally — stored per stroke, so provenance holds.
- Perspective: homography solved from the 4 corner drags (direct 8-unknown linear solve, no external deps), applied per point.
- Warp / cage / liquify (phase 2/3): all are per-point displacement fields, which the stroke record absorbs naturally; cage uses mean-value coordinates. Not in this milestone.
-
Raster baselines (
PaintedFrame.PngBase64): the one pixel path. Affine/perspective baselines are resampled once per commit through a Skia matrix draw. Warp-family transforms will refuse baselines until phase 2. - Fill strokes and clip regions transform with the same point map, so fills and masked strokes stay consistent.
- Ctrl+T enters transform mode (any paint/select tool); Enter/click outside commits, Esc cancels.
- Gizmo: bounding box of the scoped content with 8 scale handles, rotation by dragging outside a corner, move by dragging inside. Perspective sub-mode switches the corners to independent quad drag.
- Live preview: the active frame's affected pixels are drawn through the session matrix (cheap bitmap warp); exact stroke re-render happens on commit. Other frames in the scope commit without preview — the timeline thumbnails refresh immediately after.
- Tool options while in session: scope combo, perspective toggle, numeric angle/scale readout, Commit / Cancel buttons.
Non-destructive animated transforms (Krita-style masks + curves) solve a different problem — motion over time. Lightbox's inbetweener already owns motion synthesis from drawings. What artists cannot do elsewhere is edit the drawings themselves in bulk; that is what this tool does, destructively but losslessly, in the stroke domain.
- Getting started
- Documents and projects
- Tools and strokes
- Brushes
- Colour
- Layers, selections and guides
- The timeline
- Onion skin, references and the camera
- Symbols
- Saving and recovery
- Exporting to a game engine
- AI assistance
- Keyboard, performance and what is planned
- Bones and rigging
- Effects — fire, smoke and water
- A simplified 3D space to draw in: planes, parallax first, orbit second
- Brush performance beyond 4k: what the GPU can and cannot buy us
- The add-on boundary
- Making the AI trustworthy
- What an AI request actually costs
- Bones and spline deformers for 2D — design
- Brush tips — a generated library, not a live calculation
- Cloud and SaaS: what the architecture already fits, and what it does not
- Colour mixing — paint that picks up what it is laid on
- DESIGN: Effects
- DESIGN: Fluid effects — fire, smoke and water as drawn line and fill
- Fluid and viscous media — notes for the next brush-engine pass
- Compositing on the GPU
- Decomposing the two big files: which pieces come out, and with which tool
- One memory limit for pictures
- .NET 10: what is safe, what is unverified, and what it narrows
- One picture cache: the paused canvas on tiles
- The paint path: one mark, made once, under the pen
- Pen dynamics: tilt and speed
- A pencil is graphite on the paper's tooth
- Performance: the ratchet and the map
- Playback's first loop
- Pressure curves — a shape, not an exponent
- Importing Procreate brushes
- A project as a game's asset set
- One hierarchy: folders scope everything
- Puppet pins — design and plan
- The raster checkpoint: making a painting cheap to reopen
- Scoped resources — palettes, references and everything else shared
- Sensitive topics, and the three-track flow
- Design: pose-assisted frame-by-frame animation (rigid bones + AI gap filling)
- Stroke groups: why a merge should never turn strokes into pixels
- The project window: what you do between drawings
- Reading the subject before drawing on it
- The ceiling of a swept soft mark (B349)
- Q171 — a symbol owns a layer stack
- Pillar 3 — reusable assets, as live symbols
- What a template is
- Text, and where fonts sit
- The tiled compositor, and getting it off the CPU
- Design tokens
- Transform tool design (M14)
- Why a brush stamps twice, and when it does not
- Migrating to the designed UI
- Undo stores only what changed
- Vector tooling: making the lines you already drew editable
- The smudge/blur family, and aligning brush settings with Photoshop
Generated from the repository. Edit the files under docs/, not these pages.