Transform Basics
Use transforms when geometry should stay local, but its rendered position,
rotation, or scale should change. In pyDreamplet, the most common pattern is to
append elements to a G group and transform the group.
Local Coordinates
A group creates a local coordinate system for its children. The elements inside
the group can be drawn around (0, 0), then the group can be moved as a single
unit.
import pydreamplet as dp
svg = dp.SVG(540, 360)
origin = dp.G(pos=(svg.w / 2, svg.h / 2))
svg.append(origin)
origin.append(dp.Circle(cx=0, cy=0, r=6, fill="#14b8a6"))
origin.append(
dp.Line(
x1=-120,
y1=0,
x2=120,
y2=0,
stroke="currentColor",
stroke_width=3,
opacity=0.45,
)
)
origin.append(
dp.Line(
x1=0,
y1=-120,
x2=0,
y2=120,
stroke="currentColor",
stroke_width=3,
opacity=0.28,
)
)
The group is centered on the canvas, but its children still use coordinates relative to the group origin.
Vector Placement
Many shape constructors accept pos, and G.pos is a Vector. Vector math is
useful when you want to build geometry around a local origin.
circle_pos = dp.Vector(110, 0)
origin.append(dp.Circle(pos=circle_pos, r=12, fill="#14b8a6"))
Vector.direction is expressed in degrees. Updating it rotates the vector while
keeping its magnitude, which makes radial placement concise.
for _ in range(4):
circle_pos.direction += 72
origin.append(dp.Circle(pos=circle_pos, r=12, fill="#14b8a6"))
This is the same pattern used for radial marks, circular layouts, and animated designs where each element starts from a rotated copy of the same vector.
Rotation
Set angle on a group to rotate everything inside it.
needle = dp.G(angle=-45)
origin.append(needle)
needle.append(
dp.Rect(
x=-12,
y=-118,
width=24,
height=110,
rx=12,
fill="#38bdf8",
stroke="currentColor",
stroke_width=4,
)
)
This keeps the shape simple. The rectangle is still defined vertically around the local origin, and the group handles the rotation.
Scale And Pivot
Scaling and rotation happen around the group pivot. The default pivot is
(0, 0), which is usually what you want when the group is drawn around its own
origin.
markers = dp.G(scale=dp.Vector(1.15, 1.15))
origin.append(markers)
for angle in range(0, 360, 45):
mark = dp.G(angle=angle)
mark.append(
dp.Circle(cx=0, cy=-140, r=8, fill="#f83898", stroke="currentColor", stroke_width=3)
)
markers.append(mark)
When the pivot needs to be somewhere else, set pivot=(x, y) explicitly.
Transform Order
G exposes an order property for transform composition. The default is
"trs", which applies translation, then rotation, then scale.
badge = dp.G(pos=(svg.w / 2, svg.h / 2), angle=-45, scale=dp.Vector(1.2, 1.2), order="trs")
badge.append(dp.Rect(x=-42, y=-24, width=84, height=48, rx=10, fill="#95cf20"))
badge.append(
dp.Text(
"trs",
x=0,
y=0,
fill="currentColor",
font_size=18,
text_anchor="middle",
alignment_baseline="middle",
)
)
svg.append(badge)
Changing the order can produce a visibly different result, especially when translation, rotation, and non-uniform scale are combined.
Next
Continue with Text basics to place, align, and measure SVG text.