Skip to main content

Phase 2 – Core API

Phase 1 taught you how to read a document — how to navigate its structure, identify nodes, and understand what is there. Phase 2 teaches you how to change it. This is where scripts stop being inspectors and start being tools.

The three lessons in this phase cover the operations you will reach for in almost every practical script: executing commands, applying visual properties, moving and transforming objects, and creating new vector content. They are ordered deliberately — commands come first because everything else depends on them. You cannot apply a fill, move a node, or create a shape without going through the command system.

What makes this phase demanding is that the SDK rarely lets you do the obvious thing. You cannot set a fill by assigning a property. You cannot move a node by changing its coordinates. You cannot make a line dashed without also changing its type. Each lesson in this phase documents not just the correct patterns but the specific reasons the intuitive approaches fail — because those are the mistakes every developer makes, and knowing them in advance saves significant debugging time.

By the time you complete this phase you will have a working mental model of how Affinity separates reading state from writing state, and why that separation exists. That model will make everything in Phases 3 and 4 considerably easier to reason about.

The core loop​

Every useful script follows this pattern:

1. Get doc → Document.current
2. Get nodes → doc.selection or doc.layers.all
3. Build commands → DocumentCommand.create*()
4. Batch into compound → CompoundCommandBuilder
5. Execute → doc.executeCommand()

Once you internalise this cycle, each subsequent API becomes a question of selecting the appropriate DocumentCommand.create*() factory.

Lessons​

LessonTopicKey skill you'll gain
04 — Command patternDocumentCommand, CompoundCommandBuilder, undoMaking any change to the document safely
05 — Fills & strokesFillDescriptor, gradients, LineStyle, dash patternsControlling all visual properties of any node
06 — GeometryTransform, CurveBuilder, bounding boxes, PolyCurve, shapes, QR codesMoving nodes and drawing vector paths in code

What to expect​

By the end of Phase 2 you should be able to write a script that:

  • Applies any fill — solid colour, gradient, or none — to any selected node
  • Sets stroke weight, colour, cap style, join style, and dash pattern correctly
  • Moves, scales, and rotates nodes using Transform
  • Draws arbitrary vector paths using CurveBuilder and adds them to the document
  • Reads a node's bounding box and uses it to compute positions
  • Batches multiple changes into a single undoable compound command

You will also understand three of the most counterintuitive SDK behaviours: why LineStyle.createDefault() produces a style with zero weight, why setting style.weight directly has no effect, and why dash patterns require LineType.Dash to be set explicitly before they render. These are not bugs — they reflect the SDK's design — but knowing them before you encounter them will save you considerable frustration.