Draw Module¶
The nib.draw module provides declarative drawing commands for the Canvas view. Commands describe shapes, images, text, and paths that are rendered via Core Graphics on macOS with GPU acceleration.
To render a path as a view instead of on a Canvas, use Path & Shape. Comparison below.
All drawing is performed through command objects that are passed to canvas.draw(), canvas.append(), or provided as the commands parameter on the Canvas constructor. Commands are dataclasses and can be freely created, stored, and reused.
Sections¶
| Section | Description |
|---|---|
| Primitives | Shape commands: Rect, Circle, Ellipse, Line, Arc, Path, Polygon, BezierPath, Points, Shadow, Fill, ColorFill. |
| Paint & Gradients | Paint styling class, PaintStyle, StrokeCap, StrokeJoin enums, and gradient fills: LinearGradient, RadialGradient, SweepGradient. |
| Path Elements | Typed path elements for BezierPath: MoveTo, LineTo, CubicTo, QuadraticTo, Close, ArcTo, Oval, SubPath. |
| Image & Text | Image (raw bytes) and Text drawing commands with font and alignment support. |
Path & Shape: the view-level path API¶
nib.Path has the same operations as BezierPath. nib.Shape renders it as a SwiftUI view instead of a canvas command. Use Shape when the drawing is part of the layout:
- Scales to its frame through
view_box. - Accepts all view modifiers:
padding,shadow_radius,opacity,animation,clip_shape, ... fillaccepts the gradient views:LinearGradient,RadialGradient,AngularGradient,EllipticalGradient.- Subclass and override
build_path()for a reusable shape.
Use Canvas for absolute pixel coordinates, many commands per frame, images and text, pan gestures, or append() / clear() at runtime.
nib.Shape + nib.Path |
nib.Canvas + nib.draw |
|
|---|---|---|
| Result | A view in the layout | A fixed-size drawing surface |
| Coordinates | view_box units, scaled to the frame |
Points on the canvas |
| Styling | View modifiers, gradient views | Paint, nib.draw gradients, Shadow, Blur |
| Updates | Rebuild the view | draw(), append(), clear() |
| Input | None | Pan gestures |
| Images and text | No | nib.draw.Image, nib.draw.Text |
Operation mapping:
nib.Path method |
nib.draw path element |
|---|---|
move_to(x, y) |
MoveTo(x, y) |
line_to(x, y) |
LineTo(x, y) |
curve_to(x, y, control1, control2) |
CubicTo(cp1x, cp1y, cp2x, cp2y, x, y) |
quad_curve_to(x, y, control) |
QuadraticTo(cp1x, cp1y, x, y) |
arc(center, radius, start_angle, end_angle, clockwise) |
PathArc(x, y, width, height, start_angle, sweep_angle) |
close() |
Close() |
add_rect(x, y, width, height) |
PathRect(x, y, width, height) |
add_rounded_rect(x, y, width, height, corner_radius) |
PathRect(x, y, width, height, border_radius) |
add_ellipse(x, y, width, height) |
Oval(x, y, width, height) |
add_circle(center_x, center_y, radius) |
Oval(cx - r, cy - r, 2 * r, 2 * r) |
ArcTo, SubPath have no nib.Path equivalent |
Same triangle, both APIs:
import nib
# As a view: scales to its frame and takes modifiers
nib.Shape(
path=nib.Path().move_to(50, 0).line_to(100, 100).line_to(0, 100).close(),
view_box=(100, 100),
fill="#3B82F6",
width=48,
height=48,
shadow_radius=4,
)
# On a canvas: absolute points, redrawn on demand
canvas = nib.Canvas(width=120, height=120)
canvas.draw([
nib.draw.BezierPath(
elements=[
nib.draw.MoveTo(50, 0),
nib.draw.LineTo(100, 100),
nib.draw.LineTo(0, 100),
nib.draw.Close(),
],
fill="#3B82F6",
),
])
Quick example¶
import nib
def main(app: nib.App):
canvas = nib.Canvas(width=400, height=300, background_color="#1e1e1e")
canvas.draw([
# Rounded rectangle with gradient fill
nib.draw.Rect(
x=20, y=20, width=160, height=100,
fill=nib.draw.LinearGradient(
start=(20, 20), end=(180, 120),
colors=["#6366F1", "#EC4899"],
),
corner_radius=12,
),
# Circle with radial gradient
nib.draw.Circle(
cx=300, cy=80, radius=50,
fill=nib.draw.RadialGradient(
center=(300, 80), radius=50,
colors=["#FBBF24", "#F97316"],
),
),
# Connecting line
nib.draw.Line(x1=180, y1=70, x2=250, y2=80, stroke="#ffffff", stroke_width=2),
# Label
nib.draw.Text("Dashboard", x=20, y=260, fill="#ffffff"),
])
app.build(canvas)
nib.run(main)
Color values¶
All color parameters in draw commands accept either:
- Hex strings:
"#FF0000","#ff0000","FF0000" - nib.Color objects:
nib.Color.RED,nib.Color(hex="#FF0000")
Gradient fills (LinearGradient, RadialGradient, SweepGradient) can be used in place of solid colors on any fill parameter.