Drawing
APIs for vector paths, styling, and rendering commands.
Path
Vector path for custom geometry.
Constructors
Path.new()
Creates an empty path.
Path.new(): Path
Methods
path:moveTo(point)
Moves the pen to a new position, starting a new subpath.
path:moveTo(point: Vector)
path:lineTo(point)
Draws a straight line from the current position.
path:lineTo(point: Vector)
path:quadTo(control, end)
Draws a quadratic Bezier curve.
path:quadTo(control: Vector, endPoint: Vector)
path:cubicTo(c1, c2, end)
Draws a cubic Bezier curve.
path:cubicTo(controlOut: Vector, controlIn: Vector, endPoint: Vector)
path:close()
Closes the current subpath with a line to the start.
path:close()
path:reset()
Clears all path data. Warning: Don't call while rendering.
path:reset()
path:add(other, transform?)
Merges another path into this one.
path:add(other: Path, transform?: Mat2D)
path:measure()
Returns a PathMeasure for the entire path.
path:measure(): PathMeasure
path:contours()
Returns a ContourMeasure for the first contour.
path:contours(): ContourMeasure?
Operators
Length (#)
Returns the number of path commands.
local commandCount = #path
Example: Drawing a Triangle
local path = Path.new()
path:moveTo(Vector.xy(50, 0))
path:lineTo(Vector.xy(100, 100))
path:lineTo(Vector.xy(0, 100))
path:close()
See Also: PathMeasure, Renderer.drawPath
PathMeasure
Measures and manipulates paths.
Attributes
measure.length
Total length of the path across all contours. Type: number (read-only)
measure.isClosed
True only if the path has exactly one closed contour. Type: boolean (read-only)
Methods
measure:positionAndTangent(distance)
Returns the position and tangent at a distance along the path.
measure:positionAndTangent(distance: number): Vector, Vector
Returns: position, tangent (both Vector)
Example:
local measure = path:measure()
local pos, tan = measure:positionAndTangent(measure.length / 2)
measure:warp(point)
Transforms a point from "path space" coordinates to world coordinates along the path.
measure:warp(point: Vector): Vector
How it works:
- X coordinate = Distance along the path (0 = start,
measure.length= end) - Y coordinate = Perpendicular offset from the path centerline
- Positive Y = Offset to the left of the path direction
- Negative Y = Offset to the right of the path direction
Example: Text Along a Curve
-- Place points along a wavy path
local measure = curvePath:measure()
-- Point at 50% along path, centered on path
local center = measure:warp(Vector.xy(measure.length * 0.5, 0))
-- Point at 50% along path, 10 units to the left
local leftOffset = measure:warp(Vector.xy(measure.length * 0.5, 10))
-- Point at 50% along path, 10 units to the right
local rightOffset = measure:warp(Vector.xy(measure.length * 0.5, -10))
Use Cases:
- Placing text or objects along a curved path
- Creating parallel offset paths
- Animating elements that follow a trajectory
measure:extract(start, end, dest, startWithMove?)
Extracts a segment into a destination path.
measure:extract(startDist: number, endDist: number, dest: Path, startWithMove?: boolean)
Example: Animated Line Drawing
local displayPath = Path.new()
measure:extract(0, measure.length * progress, displayPath, true)
See Also: ContourMeasure, Path.measure
ContourMeasure
Iterator for individual contours within a path. Use with path:contours() to iterate through multi-contour paths.
Attributes
contour.next
Next contour, or nil if this is the last. Type: ContourMeasure? (read-only)
Note: ContourMeasure provides iteration only. For length measurement and path manipulation, use PathMeasure instead.
Example: Iterating Contours
local contour = path:contours()
local count = 0
while contour do
count += 1
contour = contour.next
end
print("Path has", count, "contours")
See Also: PathMeasure
Paint
Defines how paths are rendered (fill/stroke, color, etc.).
Constructors
Paint.new()
Creates a paint with default settings.
Paint.new(): Paint
Paint.with(definition)
Creates a paint with multiple properties at once.
Paint.with(definition: PaintDefinition): Paint
PaintDefinition Type:
type PaintDefinition = {
style: ("fill" | "stroke")?, -- Rendering style (default: "fill")
color: Color?, -- Fill or stroke color
thickness: number?, -- Stroke width (stroke only)
cap: ("round" | "butt" | "square")?, -- Line endings (stroke only)
join: ("round" | "bevel" | "miter")?, -- Corner style (stroke only)
blendMode: BlendMode?, -- Compositing mode
feather: number?, -- Feathering amount
gradient: Gradient?, -- Applied gradient
}
All fields are optional. Unspecified fields use Paint defaults.
Example:
local stroke = Paint.with({
style = "stroke",
thickness = 3,
color = Color.rgb(255, 0, 102),
cap = "round",
join = "round"
})
Attributes
| Attribute | Type | Description |
|---|---|---|
style | "fill" or "stroke" | Rendering style |
color | Color | Fill or stroke color |
thickness | number | Stroke width (stroke only) |
cap | "round", "butt", "square" | Line endings (stroke only) |
join | "round", "bevel", "miter" | Corner style (stroke only) |
blendMode | BlendMode | Compositing mode |
feather | number | Feathering amount |
gradient | Gradient? | Applied gradient |
Methods
paint:copy(overrides?)
Creates a copy with optional property overrides.
paint:copy(overrides?: PaintDefinition): Paint
Example:
local highlight = basePaint:copy({ color = Color.rgb(255, 255, 0) })
See Also: Gradient, Renderer.drawPath
Gradient
Color gradients for fills.
Constructors
Gradient.linear(from, to, stops)
Creates a linear gradient.
Gradient.linear(from: Vector, to: Vector, stops: {GradientStop}): Gradient
Example:
local gradient = Gradient.linear(
Vector.xy(0, 0),
Vector.xy(100, 0),
{
{ position = 0, color = Color.rgb(255, 0, 0) },
{ position = 1, color = Color.rgb(0, 0, 255) }
}
)
Gradient.radial(center, radius, stops)
Creates a radial gradient.
Gradient.radial(center: Vector, radius: number, stops: {GradientStop}): Gradient
GradientStop Type
type GradientStop = {
position: number, -- 0.0 to 1.0
color: Color
}
See Also: GradientStop
Renderer
Drawing commands and state management. Passed to draw() functions.
Methods
renderer:drawPath(path, paint)
Draws a path with the specified paint.
renderer:drawPath(path: Path, paint: Paint)
renderer:drawImage(image, sampler, blendMode, opacity)
Draws an image.
renderer:drawImage(image: Image, sampler: ImageSampler, blend: BlendMode, opacity: number)
renderer:drawImageMesh(image, vertices, uvs, indices)
Draws an image using mesh data (vertices, UVs, and triangle indices).
renderer:save()
Pushes the current state (transform, clip) onto the stack.
renderer:save()
renderer:restore()
Pops the last saved state. Always pair with save()!
renderer:restore()
renderer:transform(mat)
Applies a transformation to subsequent drawing.
renderer:transform(mat: Mat2D)
renderer:clipPath(path)
Restricts drawing to the path region until restore().
renderer:clipPath(path: Path)
Example: Drawing a Rotated Object
function draw(self, renderer)
renderer:save()
renderer:transform(Mat2D.withTranslation(self.x, self.y))
renderer:transform(Mat2D.withRotation(self.angle))
renderer:drawPath(self.path, self.paint)
renderer:restore()
end
Warning: Unbalanced save()/restore() calls cause rendering bugs in later frames.
Next Steps
- Continue to Scene
- Need a refresher? Review Quick Reference