Layered SVG Art
This tutorial builds an SVG artwork with two layers: blended arc segments in the front and an animated gradient circle behind them.
Imports and Colors
import pydreamplet as dp
from pydreamplet.colors import blend
from pydreamplet.shapes import ring
color1 = "#e2cbc5"
color2 = "#691016"
color3 = "#92a1c2"
color4 = "#082137"
Canvas and Layers
Create the canvas and two groups. The first group is appended first, so it is painted behind the arc layer.
svg = dp.SVG(600, 600, width="300px", height="300px")
circle_layer = dp.G()
arc_layer = dp.G()
svg.append(circle_layer, arc_layer)
Arc Segments
The top half uses ring() paths from 180 to 360 degrees. Each iteration shifts
the center, reduces the radius, and blends the fill color.
x = svg.w / 2
blend_prop = 0
radius = 200
radius_delta = radius / 6
for _ in range(6):
arc = dp.Path(
d=ring(
x,
svg.h / 2,
inner_radius=0,
outer_radius=radius,
start_angle=180,
end_angle=360,
),
fill=blend(color1, color2, blend_prop),
)
arc_layer.append(arc)
x -= radius_delta
radius -= radius_delta
blend_prop += 1 / 6
The bottom half mirrors that idea and blends a second pair of colors.
x = svg.w / 2
blend_prop = 0
radius = 200
for _ in range(6):
arc = dp.Path(
d=ring(
x,
svg.h / 2,
inner_radius=0,
outer_radius=radius,
start_angle=0,
end_angle=180,
),
fill=blend(color3, color4, blend_prop),
)
arc_layer.append(arc)
x += radius_delta
radius -= radius_delta
blend_prop += 1 / 6
Animated Circle
Animate writes SVG <animate> elements. The first animation moves the dashed
stroke; the second changes the circle radius.
circle = dp.Circle(
cx=svg.w / 2,
cy=svg.h / 2,
r=250,
fill="none",
stroke="currentColor",
stroke_width=5,
stroke_dasharray="20,15",
stroke_dashoffset=20,
)
dash_animation = dp.Animate("stroke-dashoffset", dur="2s")
dash_animation.values = [0, 100]
radius_animation = dp.Animate("r", dur="2s")
radius_animation.values = [250, 200, 250]
circle.append(dash_animation, radius_animation)
circle_layer.append(circle)
Gradient Fill
Use ensure_defs() and LinearGradient for reusable SVG definitions. The
gradient's url property returns the url(#...) reference used by fill.
defs = svg.ensure_defs()
gradient = dp.LinearGradient(id="art-gradient", gradientTransform="rotate(90)")
gradient.add_stop("0%", color3)
gradient.add_stop("100%", color1)
defs.append(gradient)
circle.fill = gradient.url
circle.stroke = "#6b7280"
svg.save("layered-art.svg")