Skip to content
quickthumb
All documentation

Path

Canvas.path() draws filled or stroked vector paths using standard SVG path data (d), without requiring an external SVG file or extra dependencies:

from quickthumb import Canvas

canvas = Canvas(160, 120).path(
    "M 0 0 H 100 V 100 H 0 Z M 25 25 H 75 V 75 H 25 Z",
    position=(20, 10),
    width=120,
    height=100,
    view_box=(0, 0, 100, 100),
    color="#42CEB7",
)
canvas.export("path.png")

Parameters

Parameter Type Default Description
d str required SVG path commands (M, L, H, V, C, S, Q, T, A, Z).
position tuple required (x, y) position in pixels or percentage strings ("50%").
width int required Frame width in pixels.
height int required Frame height in pixels.
view_box tuple \| None None Local coordinate window (x, y, width, height). Defaults to (0, 0, width, height).
color str \| None "#000000" Flat fill color. Set to None for stroke-only paths.
fill LinearGradient \| RadialGradient \| None None Gradient fill. Replaces color when provided.
stroke str \| None None Stroke color (hex string).
stroke_width int \| float 1 Stroke thickness in local units.
line_cap str "butt" Endpoint style: "butt", "round", or "square".
line_join str "miter" Corner join style: "miter", "bevel", or "round".
miter_limit float 4 Maximum miter ratio before switching to bevel.
dash_array tuple \| None None Dash pattern tuple of lengths (dash, gap, ...).
dash_offset float 0 Starting phase offset into the dash pattern.
rotation float 0.0 Rotation in degrees.
opacity float 1.0 Layer opacity from 0.0 to 1.0.
anchor tuple (0.5, 0.5) Normalized pivot point for rotation and scaling.
animation AnimationSpec \| None None Timeline animation for motion, trim, dash phase, or morphing.

Examples

Stroked curves with dashed outline

canvas.path(
    "M10 50 C30 0 70 100 90 50",
    position=(20, 10),
    width=120,
    height=100,
    color=None,
    stroke="#42CEB7",
    stroke_width=6,
    line_cap="round",
    view_box=(0, 0, 100, 100),
    dash_array=(12, 6),
    dash_offset=3,
)

Gradient fill with cutouts

Paths use the even-odd fill rule: overlapping internal contours naturally create cutouts or holes.

from quickthumb import LinearGradient

canvas.path(
    "M10 10 H90 V90 H10 Z M30 30 H70 V70 H30 Z",
    position=(20, 10),
    width=120,
    height=100,
    color=None,
    fill=LinearGradient(angle=45, stops=[("#42CEB7", 0), ("#315D8E", 1)]),
    view_box=(0, 0, 100, 100),
)

Path Animations

Animated dash phase (Marching ants)

Animate DashOffsetTrack to create a crawling dashed-line effect:

from quickthumb import AnimationSpec, DashOffsetTrack, KeyframeSpec, TimingSpec

phase_animation = AnimationSpec.timeline(
    DashOffsetTrack(keyframes=[
        KeyframeSpec(time=0, value=0),
        KeyframeSpec(time=1, value=20),
    ]),
    timing=TimingSpec(duration=1),
    easing="linear",
)

canvas.path(
    "M0 10 H100",
    position=(10, 10),
    width=200,
    height=20,
    color=None,
    stroke="#42CEB7",
    dash_array=(6, 4),
    animation=phase_animation,
)

Stroke trim (Self-drawing line)

Use TrimEndTrack to progressively draw a line or outline from start to finish:

from quickthumb import AnimationSpec, KeyframeSpec, TimingSpec, TrimEndTrack

draw_outline = AnimationSpec.timeline(
    TrimEndTrack(keyframes=[
        KeyframeSpec(time=0, value=0.0),
        KeyframeSpec(time=1.5, value=1.0),
    ]),
    timing=TimingSpec(duration=1.5),
    easing="ease_in_out",
)

canvas.path(
    "M0 20 Q50 -10 100 20",
    position=(20, 20),
    width=200,
    height=60,
    view_box=(0, -10, 100, 30),
    color=None,
    stroke="#42CEB7",
    stroke_width=4,
    animation=draw_outline,
)
  • TrimStartTrack and TrimEndTrack: Normalized endpoints (0.0 to 1.0) along the path's total length.
  • TrimOffsetTrack: Shifts the trimmed interval along the path.

Path morphing

Smoothly transform one vector shape into another using PathMorphTrack:

from quickthumb import AnimationSpec, KeyframeSpec, PathMorphTrack, TimingSpec

morph = AnimationSpec.timeline(
    PathMorphTrack(keyframes=[
        KeyframeSpec(time=0, value="M10 10 H50 V50 H10 Z"),
        KeyframeSpec(time=1, value="M20 20 H60 V60 H20 Z"),
    ]),
    timing=TimingSpec(duration=1),
    easing="ease_in_out",
)

canvas.path(
    "M10 10 H50 V50 H10 Z",
    position=(10, 10),
    width=100,
    height=100,
    color="#42CEB7",
    animation=morph,
)

Each key must have 1–16 nondegenerate contours, matching in count, order, open/closed status, winding, and nesting. Contours must not intersect or touch, including during the transition. Incompatible keys raise path_morph_topology; an invalid intermediate shape fails during rendering rather than changing topology.

Complex outlines may exceed the limits of 256 subdivided vertices per contour, 4096 correspondence points, or one million edge-pair checks. Resampling must retain vertices within ¼ local SVG unit; enlargement can make that approximation visible. Simplify the paths if morph preparation rejects them.

Export Support

  • Raster & Video (PNG, GIF, MP4, WebM): Render paths, dashes, trims, and morph animations.
  • Lottie: Export supported path morph animations as vectors.
  • HTML: Native SVG rendering with CSS stroke animations for supported open paths. Morph animations use the authored still image.
  • PDF & PPTX: Export supported paths as vectors; morph animations use the authored still image.