Programmatically generate SVG (vector) images, animations, and interactive Jupyter widgets

Support chaining Path commands (#20)

Noah 217e798d d7362314

Changed files
+24 -25
drawSvg
+1 -3
README.md
···
arrow.append(draw.Lines(-0.1, -0.5, -0.1, 0.5, 0.9, 0, fill='red', close=True))
p = draw.Path(stroke='red', stroke_width=2, fill='none',
marker_end=arrow) # Add an arrow to the end of a path
-
p.M(20, -40)
-
p.L(20, -27)
-
p.L(0, -20)
d.append(p)
d.append(draw.Line(30, -20, 0, -10,
stroke='red', stroke_width=2, fill='none',
···
arrow.append(draw.Lines(-0.1, -0.5, -0.1, 0.5, 0.9, 0, fill='red', close=True))
p = draw.Path(stroke='red', stroke_width=2, fill='none',
marker_end=arrow) # Add an arrow to the end of a path
+
p.M(20, -40).L(20, -27).L(0, -20) # Chain multiple path operations
d.append(p)
d.append(draw.Line(30, -20, 0, -10,
stroke='red', stroke_width=2, fill='none',
+23 -22
drawSvg/elements.py
···
if len(args) > 0:
commandStr = commandStr + ','.join(map(str, args))
self.args['d'] += commandStr
-
def M(self, x, y): self.append('M', x, -y)
-
def m(self, dx, dy): self.append('m', dx, -dy)
-
def L(self, x, y): self.append('L', x, -y)
-
def l(self, dx, dy): self.append('l', dx, -dy)
-
def H(self, x): self.append('H', x)
-
def h(self, dx): self.append('h', dx)
-
def V(self, y): self.append('V', -y)
-
def v(self, dy): self.append('v', -dy)
-
def Z(self): self.append('Z')
def C(self, cx1, cy1, cx2, cy2, ex, ey):
-
self.append('C', cx1, -cy1, cx2, -cy2, ex, -ey)
def c(self, cx1, cy1, cx2, cy2, ex, ey):
-
self.append('c', cx1, -cy1, cx2, -cy2, ex, -ey)
-
def S(self, cx2, cy2, ex, ey): self.append('S', cx2, -cy2, ex, -ey)
-
def s(self, cx2, cy2, ex, ey): self.append('s', cx2, -cy2, ex, -ey)
-
def Q(self, cx, cy, ex, ey): self.append('Q', cx, -cy, ex, -ey)
-
def q(self, cx, cy, ex, ey): self.append('q', cx, -cy, ex, -ey)
-
def T(self, ex, ey): self.append('T', ex, -ey)
-
def t(self, ex, ey): self.append('t', ex, -ey)
def A(self, rx, ry, rot, largeArc, sweep, ex, ey):
-
self.append('A', rx, ry, rot, int(bool(largeArc)), int(bool(sweep)), ex,
-
-ey)
def a(self, rx, ry, rot, largeArc, sweep, ex, ey):
-
self.append('a', rx, ry, rot, int(bool(largeArc)), int(bool(sweep)), ex,
-
-ey)
def arc(self, cx, cy, r, startDeg, endDeg, cw=False, includeM=True,
includeL=False):
''' Uses A() to draw a circular arc '''
···
self.L(cx+sx, cy+sy)
elif includeM:
self.M(cx+sx, cy+sy)
-
self.A(r, r, 0, largeArc ^ cw, cw, cx+ex, cy+ey)
class Lines(Path):
''' A sequence of connected lines (or a polygon)
···
if len(args) > 0:
commandStr = commandStr + ','.join(map(str, args))
self.args['d'] += commandStr
+
return self
+
def M(self, x, y): return self.append('M', x, -y)
+
def m(self, dx, dy): return self.append('m', dx, -dy)
+
def L(self, x, y): return self.append('L', x, -y)
+
def l(self, dx, dy): return self.append('l', dx, -dy)
+
def H(self, x): return self.append('H', x)
+
def h(self, dx): return self.append('h', dx)
+
def V(self, y): return self.append('V', -y)
+
def v(self, dy): return self.append('v', -dy)
+
def Z(self): return self.append('Z')
def C(self, cx1, cy1, cx2, cy2, ex, ey):
+
return self.append('C', cx1, -cy1, cx2, -cy2, ex, -ey)
def c(self, cx1, cy1, cx2, cy2, ex, ey):
+
return self.append('c', cx1, -cy1, cx2, -cy2, ex, -ey)
+
def S(self, cx2, cy2, ex, ey): return self.append('S', cx2, -cy2, ex, -ey)
+
def s(self, cx2, cy2, ex, ey): return self.append('s', cx2, -cy2, ex, -ey)
+
def Q(self, cx, cy, ex, ey): return self.append('Q', cx, -cy, ex, -ey)
+
def q(self, cx, cy, ex, ey): return self.append('q', cx, -cy, ex, -ey)
+
def T(self, ex, ey): return self.append('T', ex, -ey)
+
def t(self, ex, ey): return self.append('t', ex, -ey)
def A(self, rx, ry, rot, largeArc, sweep, ex, ey):
+
return self.append('A', rx, ry, rot, int(bool(largeArc)),
+
int(bool(sweep)), ex, -ey)
def a(self, rx, ry, rot, largeArc, sweep, ex, ey):
+
return self.append('a', rx, ry, rot, int(bool(largeArc)),
+
int(bool(sweep)), ex, -ey)
def arc(self, cx, cy, r, startDeg, endDeg, cw=False, includeM=True,
includeL=False):
''' Uses A() to draw a circular arc '''
···
self.L(cx+sx, cy+sy)
elif includeM:
self.M(cx+sx, cy+sy)
+
return self.A(r, r, 0, largeArc ^ cw, cw, cx+ex, cy+ey)
class Lines(Path):
''' A sequence of connected lines (or a polygon)