### Installation Source: https://github.com/cduck/drawsvg/blob/master/README.md Instructions on how to install the DrawSVG library using pip. ```APIDOC ## Install DrawSVG Drawsvg is available on PyPI: ```bash $ python3 -m pip install "drawsvg~=2.0" ``` To enable raster image support (PNG, MP4, and GIF), follow the [full-feature install instructions](#full-feature-install). ``` -------------------------------- ### DrawSVG Installation Source: https://github.com/cduck/drawsvg/blob/master/README.md Provides instructions for installing the DrawSVG library, including options for full-featured installation with extra dependencies. ```APIDOC # Full-feature install Drawsvg may be either be installed with no dependencies (only SVG and SVG-native animation will work): ```bash $ python3 -m pip install "drawsvg~=2.0" ``` Or drawsvg may be installed with extra dependencies to support PNG, MP4, and GIF output: ```bash $ python3 -m pip install "drawsvg[all]~=2.0" ``` An additional required package, [Cairo](https://www.cairographics.org/download/), cannot be installed with pip and must be installed separately. When Cairo is installed, drawsvg can output PNG and other image formats in addition to SVG. Install it with your preferred package manager. Examples: **Ubuntu** ```bash $ sudo apt install libcairo2 ``` **macOS** Using [homebrew](https://brew.sh/) (may require a Python version installed with `brew install python`): ```bash $ brew install cairo ``` **Any platform** Using [Anaconda](https://docs.conda.io/en/latest/miniconda.html) (may require Python and cairo installed in the same conda environment): ```bash $ conda install -c anaconda cairo ``` ``` -------------------------------- ### Install DrawSVG Dependencies Source: https://github.com/cduck/drawsvg/blob/master/README.md Provides installation commands for the DrawSVG library and its required system-level Cairo dependency across different platforms. ```bash python3 -m pip install "drawsvg[all]~=2.0" sudo apt install libcairo2 brew install cairo conda install -c anaconda cairo ``` -------------------------------- ### Install DrawSVG Library Source: https://github.com/cduck/drawsvg/blob/master/README.md Instructions for installing the DrawSVG library using pip. It also mentions enabling full-feature support for raster images and provides guidance for upgrading from version 1.x. ```bash python3 -m pip install "drawsvg~=2.0" ``` -------------------------------- ### SVG-native Animation Source: https://github.com/cduck/drawsvg/blob/master/README.md Example demonstrating how to create SVG animations with playback controls using DrawSVG, suitable for Jupyter notebooks. ```APIDOC ## SVG-native animation with playback controls ```python import drawsvg as draw d = draw.Drawing(400, 200, origin='center', animation_config=draw.types.SyncedAnimationConfig( # Animation configuration duration=8, # Seconds show_playback_progress=True, show_playback_controls=True)) d.append(draw.Rectangle(-200, -100, 400, 200, fill='#eee')) # Background d.append(draw.Circle(0, 0, 40, fill='green')) # Center circle ``` ``` -------------------------------- ### Draw Circles Source: https://context7.com/cduck/drawsvg/llms.txt Demonstrates creating circle elements using center coordinates and radius, with examples of stroke and fill customization. ```python import drawsvg as draw d = draw.Drawing(300, 150) d.append(draw.Circle(50, 75, 40, fill='red')) d.append(draw.Circle(150, 75, 40, fill='none', stroke='blue', stroke_width=3)) d.append(draw.Circle(250, 75, 40, fill='green', stroke='black', stroke_width=10, stroke_opacity=0.5)) d.save_svg('circles.svg') ``` -------------------------------- ### Adjusting Line Thickness with stroke-width Source: https://github.com/cduck/drawsvg/blob/master/docs/index.md Illustrates how to control the thickness of lines using the `stroke-width` attribute. The example shows a series of lines with varying `stroke-width` values, creating a visual gradient of thickness. ```python for i in range(20): d.append(dw.Line((i+1)*15, 10, (i+1)*15, 90, stroke='black', stroke_width=abs(10-i)+1)) ``` -------------------------------- ### Add Path Markers Source: https://context7.com/cduck/drawsvg/llms.txt Demonstrates placing custom markers at the start, middle, or end of paths for annotations like arrows. ```python import drawsvg as draw d = draw.Drawing(300, 150) arrow = draw.Marker(-0.1, -0.5, 0.9, 0.5, scale=4, orient='auto') arrow.append(draw.Lines(-0.1, 0.5, -0.1, -0.5, 0.9, 0, close=True, fill='red')) p = draw.Path(stroke='red', stroke_width=2, fill='none', marker_end=arrow) p.M(20, 75).L(120, 75) d.append(p) d.save_svg('markers.svg') ``` -------------------------------- ### SVG Animation with Playback Controls using DrawSVG Source: https://github.com/cduck/drawsvg/blob/master/README.md This example demonstrates how to create an SVG animation with integrated playback controls using the DrawSVG Python library. It configures the animation duration and enables the display of progress and controls. ```python import drawsvg as draw d = draw.Drawing(400, 200, origin='center', animation_config=draw.types.SyncedAnimationConfig( # Animation configuration duration=8, # Seconds show_playback_progress=True, show_playback_controls=True)) d.append(draw.Rectangle(-200, -100, 400, 200, fill='#eee')) # Background d.append(draw.Circle(0, 0, 40, fill='green')) # Center circle ``` -------------------------------- ### Basic Drawing Elements with DrawSVG Source: https://github.com/cduck/drawsvg/blob/master/README.md Demonstrates how to create various basic SVG drawing elements such as polygons, rectangles, circles, paths, text, and arcs using the DrawSVG Python library. It also shows how to add tooltips, customize stroke and fill properties, and append markers like arrows. The example concludes with saving the drawing as SVG and PNG files, and displaying it in a Jupyter notebook. ```python import drawsvg as draw d = draw.Drawing(200, 100, origin='center') # Draw an irregular polygon d.append(draw.Lines(-80, 45, 70, 49, 95, -49, -90, -40, close=False, fill='#eeee00', stroke='black')) # Draw a rectangle r = draw.Rectangle(-80, -50, 40, 50, fill='#1248ff') r.append_title("Our first rectangle") # Add a tooltip d.append(r) # Draw a circle d.append(draw.Circle(-40, 10, 30, fill='red', stroke_width=2, stroke='black')) # Draw an arbitrary path (a triangle in this case) p = draw.Path(stroke_width=2, stroke='lime', fill='black', fill_opacity=0.2) p.M(-10, -20) # Start path at point (-10, -20) p.C(30, 10, 30, -50, 70, -20) # Draw a curve to (70, -20) d.append(p) # Draw text d.append(draw.Text('Basic text', 8, -10, -35, fill='blue')) # 8pt text at (-10, -35) d.append(draw.Text('Path text', 8, path=p, text_anchor='start', line_height=1)) d.append(draw.Text(['Multi-line', 'text'], 8, path=p, text_anchor='end', center=True)) # Draw multiple circular arcs d.append(draw.ArcLine(60, 20, 20, 60, 270, stroke='red', stroke_width=5, fill='red', fill_opacity=0.2)) d.append(draw.Arc(60, 20, 20, 90, -60, cw=True, stroke='green', stroke_width=3, fill='none')) d.append(draw.Arc(60, 20, 20, -60, 90, cw=False, stroke='blue', stroke_width=1, fill='black', fill_opacity=0.3)) # Draw arrows arrow = draw.Marker(-0.1, -0.51, 0.9, 0.5, scale=4, orient='auto') 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 commands d.append(p) d.append(draw.Line(30, 20, 0, 10, stroke='red', stroke_width=2, fill='none', marker_end=arrow)) # Add an arrow to the end of a line d.set_pixel_scale(2) # Set number of pixels per geometry unit #d.set_render_size(400, 200) # Alternative to set_pixel_scale d.save_svg('example.svg') d.save_png('example.png') # Display in Jupyter notebook #d.rasterize() # Display as PNG d # Display as SVG ``` -------------------------------- ### Basic Drawing Elements Source: https://github.com/cduck/drawsvg/blob/master/README.md Example demonstrating how to create basic SVG drawing elements like polygons, rectangles, circles, paths, text, and arcs using the DrawSVG library. ```APIDOC ## Basic drawing elements ```python import drawsvg as draw d = draw.Drawing(200, 100, origin='center') # Draw an irregular polygon d.append(draw.Lines(-80, 45, 70, 49, 95, -49, -90, -40, close=False, fill='#eeee00', stroke='black')) # Draw a rectangle r = draw.Rectangle(-80, -50, 40, 50, fill='#1248ff') r.append_title("Our first rectangle") # Add a tooltip d.append(r) # Draw a circle d.append(draw.Circle(-40, 10, 30, fill='red', stroke_width=2, stroke='black')) # Draw an arbitrary path (a triangle in this case) p = draw.Path(stroke_width=2, stroke='lime', fill='black', fill_opacity=0.2) p.M(-10, -20) # Start path at point (-10, -20) p.C(30, 10, 30, -50, 70, -20) # Draw a curve to (70, -20) d.append(p) # Draw text d.append(draw.Text('Basic text', 8, -10, -35, fill='blue')) # 8pt text at (-10, -35) d.append(draw.Text('Path text', 8, path=p, text_anchor='start', line_height=1)) d.append(draw.Text(['Multi-line', 'text'], 8, path=p, text_anchor='end', center=True)) # Draw multiple circular arcs d.append(draw.ArcLine(60, 20, 20, 60, 270, stroke='red', stroke_width=5, fill='red', fill_opacity=0.2)) d.append(draw.Arc(60, 20, 20, 90, -60, cw=True, stroke='green', stroke_width=3, fill='none')) d.append(draw.Arc(60, 20, 20, -60, 90, cw=False, stroke='blue', stroke_width=1, fill='black', fill_opacity=0.3)) # Draw arrows arrow = draw.Marker(-0.1, -0.51, 0.9, 0.5, scale=4, orient='auto') 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 commands d.append(p) d.append(draw.Line(30, 20, 0, 10, stroke='red', stroke_width=2, fill='none', marker_end=arrow)) # Add an arrow to the end of a line d.set_pixel_scale(2) # Set number of pixels per geometry unit #d.set_render_size(400, 200) # Alternative to set_pixel_scale d.save_svg('example.svg') d.save_png('example.png') # Display in Jupyter notebook #d.rasterize() # Display as PNG d # Display as SVG ``` ``` -------------------------------- ### Defining Corner Joins with stroke-linejoin Source: https://github.com/cduck/drawsvg/blob/master/docs/index.md Explains how to control the appearance of line segment connections at corners using `stroke-linejoin`. The example showcases 'miter' (pointed), 'round', and 'bevel' (flat) styles. ```python d.append(dw.Line(0, 20, 300, 20, stroke='gray')) g = dw.Group(stroke_width=20, stroke='black', fill='none') g.append(dw.Lines(10, 80, 50, 20, 90, 80, stroke_linejoin='miter')) g.append(dw.Lines(110, 80, 150, 20, 190, 80, stroke_linejoin='round')) g.append(dw.Lines(210, 80, 250, 20, 290, 80, stroke_linejoin='bevel')) d.append(g) ``` -------------------------------- ### JavaScript SVG Animation Setup and Controls Source: https://github.com/cduck/drawsvg/blob/master/examples/playback-controls.html This JavaScript code sets up and manages animation playback controls for an SVG. It handles initialization, event listeners for mouse interactions (mousedown, mousemove, mouseup), and functions to control animation playback (play, pause, scrub). It calculates SVG coordinates and progress fractions based on user interactions with elements like the scrub knob and capture area. Dependencies include the SVG DOM and specific HTML elements with IDs like 'scrub-capture', 'scrub', 'scrub-play', 'scrub-pause', and 'scrub-knob'. ```javascript function svgOnLoad(event) { if (event && event.target && event.target.ownerDocument) { svgSetup(event.target.ownerDocument); } else if (document && document.currentScript && document.currentScript.parentElement) { svgSetup(document.currentScript.parentElement); } } function svgSetup(doc) { var svgRoot = doc.documentElement || svgRoot; var scrubCapture = doc.getElementById("scrub-capture"); if (!scrubCapture || scrubCapture.getAttribute("svgSetupDone")) { return; } scrubCapture.setAttribute("svgSetupDone", true); var scrubContainer = doc.getElementById("scrub"); var scrubPlay = doc.getElementById("scrub-play"); var scrubPause = doc.getElementById("scrub-pause"); var scrubKnob = doc.getElementById("scrub-knob"); var scrubXMin = parseFloat(scrubCapture.dataset.xmin); var scrubXMax = parseFloat(scrubCapture.dataset.xmax); var scrubTotalDur = parseFloat(scrubCapture.dataset.totaldur); var scrubStartDelay = parseFloat(scrubCapture.dataset.startdelay); var scrubEndDelay = parseFloat(scrubCapture.dataset.enddelay); var scrubPauseOnLoad = parseFloat(scrubCapture.dataset.pauseonload); var paused = false; var dragXOffset = 0; var point = svgRoot.createSVGPoint(); function screenToSvgX(p) { var matrix = scrubKnob.getScreenCTM().inverse(); point.x = p.x; point.y = p.y; return point.matrixTransform(matrix).x; } function screenToProgress(p) { var matrix = scrubKnob.getScreenCTM().inverse(); point.x = p.x; point.y = p.y; var x = point.matrixTransform(matrix).x; if (x <= scrubXMin) { return scrubStartDelay / scrubTotalDur; } if (x >= scrubXMax) { return (scrubTotalDur - scrubEndDelay) / scrubTotalDur; } return (scrubStartDelay/scrubTotalDur + (x - dragXOffset - scrubXMin) / (scrubXMax - scrubXMin) * (scrubTotalDur - scrubStartDelay - scrubEndDelay) / scrubTotalDur); } function currentScrubX() { return scrubKnob.cx.animVal.value; } function pause() { svgRoot.pauseAnimations(); scrubPlay.setAttribute("visibility", "visible"); scrubPause.setAttribute("visibility", "hidden"); paused = true; } function play() { svgRoot.unpauseAnimations(); scrubPause.setAttribute("visibility", "visible"); scrubPlay.setAttribute("visibility", "hidden"); paused = false; } function scrub(playbackFraction) { var t = scrubTotalDur * playbackFraction; var limit = scrubTotalDur - 10e-3; if (t < 0) t = 0; else if (t > limit) t = limit; svgRoot.setCurrentTime(t); } function mousedown(e) { svgRoot.pauseAnimations(); if (e.target == scrubKnob) { dragXOffset = screenToSvgX(e) - currentScrubX(); } else { dragXOffset = 0; } scrub(screenToProgress(e)); document.addEventListener('mousemove', mousemove); document.addEventListener('mouseup', mouseup); e.preventDefault(); } function mouseup(e) { dragXOffset = 0; document.removeEventListener('mousemove', mousemove); document.removeEventListener('mouseup', mouseup); if (!paused) { svgRoot.unpauseAnimations(); } e.preventDefault(); } function mousemove(e) { scrub(screenToProgress(e)); } scrubPause.addEventListener("click", pause); scrubPlay.addEventListener("click", play); scrubCapture.addEventListener("mousedown", mousedown); scrubContainer.setAttribute("visibility", "visible"); scrubKnob.setAttribute("visibility", "visible"); if (scrubPauseOnLoad) { pause(); scrub(0); } else { play(); } } svgOnLoad(); ``` -------------------------------- ### Initialize and Configure Drawing Canvas Source: https://context7.com/cduck/drawsvg/llms.txt Demonstrates how to instantiate the Drawing class, set viewport dimensions, define coordinate origins, and export the resulting SVG to various file formats or display it in a Jupyter environment. ```python import drawsvg as draw d = draw.Drawing(400, 200, origin='center') d2 = draw.Drawing(200, 100, origin='top-left', id_prefix='mysvg') d.set_pixel_scale(2) d.set_render_size(800, 400) d.append(draw.Rectangle(-100, -50, 200, 100, fill='blue')) d.save_svg('output.svg') d.save_png('output.png') d.save_html('output.html') svg_string = d.as_svg() d.display_inline() d.rasterize() ``` -------------------------------- ### Create Linear Gradients Source: https://context7.com/cduck/drawsvg/llms.txt Shows how to define linear gradients with multiple color stops and apply them as fills to shapes. ```python import drawsvg as draw d = draw.Drawing(300, 150) grad1 = draw.LinearGradient(0, 0, 100, 0) grad1.add_stop(0, 'red') grad1.add_stop(0.5, 'yellow') grad1.add_stop(1, 'green') d.append(draw.Rectangle(10, 10, 100, 60, fill=grad1)) d.save_svg('linear_gradients.svg') ``` -------------------------------- ### Path Command: Q (quadratic Bézier curve) Source: https://github.com/cduck/drawsvg/blob/master/docs/index.md Explains the `Q(x_ctl, y_ctl, x_end, y_end)` command for drawing quadratic Bézier curves. This command draws a curve from the current point to `x_end, y_end` using `x_ctl, y_ctl` as the single control point. ```python # Curve only (left) p = dw.Path(stroke='black', fill='none', stroke_width=3) d.append(p.M(30, 75).Q(240, 30, 300, 120)) # With control point and construction lines d.append(dw.Use(p, 300, 0)) g = dw.Group(stroke='gray', fill='gray') g.append(dw.Circle(330, 75, 3)) g.append(dw.Circle(600, 120, 3)) g.append(dw.Circle(540, 30, 3)) g.append(dw.Line(330, 75, 540, 30)) g.append(dw.Line(540, 30, 600, 120)) g.append(dw.Line(330, 75, 600, 120, stroke_dasharray='5,5')) g.append(dw.Circle(435, 52.5, 3)) g.append(dw.Circle(570, 75, 3)) g.append(dw.Line(435, 52.5, 570, 75)) g.append(dw.Circle(502.5, 63.75, 4, fill='none')) d.append(g) ``` -------------------------------- ### Apply Styling and Opacity Source: https://github.com/cduck/drawsvg/blob/master/docs/index.md Shows how to apply colors, stroke widths, and opacity settings to elements. Supports standard SVG color keywords and RGB formats. ```python d.append(dw.Rectangle(210, 10, 75, 90, fill='#0000ff', stroke='red', stroke_width=7, stroke_opacity=0.5)) d.append(dw.Rectangle(300, 10, 105, 60, fill='yellow', fill_opacity=0.5, stroke='green', stroke_width=2, stroke_dasharray='5,2')) ``` -------------------------------- ### Masking with Alpha Opacity Source: https://github.com/cduck/drawsvg/blob/master/docs/index.md Shows how to create masks using fill_opacity to achieve varying levels of transparency. ```python fullmask = dw.Mask(maskContentUnits='objectBoundingBox') fullmask.append(dw.Rectangle(0, 0, 1, 1, fill_opacity=1.0, fill='white')) g = dw.Group(mask=fullmask) g.append(dw.Circle(35, 35, 25)) d.append(g) ``` -------------------------------- ### Path Commands: M (moveto) and L (lineto) Source: https://github.com/cduck/drawsvg/blob/master/docs/index.md Introduces basic path drawing commands. `M(x, y)` moves the current point to the specified coordinates without drawing, while `L(x, y)` draws a straight line from the current point to the new coordinates. ```python g = dw.Group(stroke='black', fill='none') p = dw.Path() p.M(10, 10).L(100, 10) g.append(p) p = dw.Path() p.M(10, 20).L(100, 20).L(100, 50) g.append(p) p = dw.Path() p.M(40, 60).L(10, 60).L(40, 42) p.M(60, 60).L(90, 60).L(60, 42) g.append(p) d.append(g) ``` -------------------------------- ### Close Path (Z) Source: https://github.com/cduck/drawsvg/blob/master/docs/index.md Closes the current path by drawing a straight line from the current point back to the starting point of the path. This command is essential for creating closed shapes like polygons and is often used in conjunction with other path drawing commands. ```python path.Z() ``` ```python p = dw.Path(stroke='black', fill='none') d.append(p.M(10, 10).h(30).v(50).h(-30).Z()) d.append(p.M(50, 10).h(30).v(50).Z()) ``` -------------------------------- ### Applying Rotate Transformation in DrawSVG Source: https://github.com/cduck/drawsvg/blob/master/docs/index.md Explains how to rotate SVG elements using `transform='rotate(angle,cx=0,cy=0)'`. The angle is in degrees clockwise, and `cx`/`cy` define the center of rotation. Examples show rotation around the origin and a specified center point. ```python transform = 'rotate(angle,cx=0,cy=0)' ``` ```python # Show frame border d.append(dw.Rectangle(0, 0, 200, 200, stroke='gray', fill='none')) # Rotation is around (0, 0) d.append(dw.Rectangle(70, 30, 40, 40, fill='silver')) d.append(dw.Rectangle(70, 30, 40, 40, fill='gray', transform='rotate(22.5)')) d.append(dw.Rectangle(70, 30, 40, 40, fill='black', transform='rotate(45)')) ``` ```python # Center of rotation d.append(dw.Circle(100, 100, 3, fill='black')) # Non-rotated arrow arrow = dw.Group(id='arrow') arrow.append(dw.Line(110, 100, 160, 100)) arrow.append(dw.Lines(160, 100, 155, 95, 155, 105)) d.append(dw.Use(arrow, 0, 0, stroke='black', fill='black')) # Rotated arrows g = dw.Group(stroke='red', fill='red') g.append(dw.Use(arrow, 0, 0, transform='rotate (60,100,100)')) g.append(dw.Use(arrow, 0, 0, transform='rotate (-90,100,100)')) g.append(dw.Use(arrow, 0, 0, transform='rotate (-150,100,100)')) d.append(g) ``` -------------------------------- ### Create Asynchronous Animation Widget with DrawSVG Source: https://context7.com/cduck/drawsvg/llms.txt Demonstrates the creation of a continuously updating animation widget in Jupyter notebooks using DrawSVG's AsyncAnimation. It shows how to set up the widget, define a frame-drawing function that updates based on time, and modify animation parameters like FPS dynamically. ```python import drawsvg as draw from drawsvg.widgets import AsyncAnimation import math # Cell 1: Create and display widget widget = AsyncAnimation(fps=30) widget # Display the animation # Cell 2: Define the animation function @widget.set_draw_frame def draw_frame(secs=0): d = draw.Drawing(200, 200, origin='center') # Rotating elements based on time angle = secs * 60 # 60 degrees per second d.append(draw.Rectangle(-100, -100, 200, 200, fill='#333')) for i in range(6): a = math.radians(angle + i * 60) x = 50 * math.cos(a) y = 50 * math.sin(a) d.append(draw.Circle(x, y, 15, fill=f'hsl({i*60}, 70%, 60%)')) d.append(draw.Text(f'{secs:.1f}s', 16, 0, 0, center=True, fill='white')) return d # Cell 3: Modify parameters while running widget.fps = 60 # Change framerate ``` -------------------------------- ### Animate SVG Transformations with Python Source: https://context7.com/cduck/drawsvg/llms.txt Demonstrates how to animate transformation attributes such as rotation, scaling, and translation using DrawSVG's 'AnimateTransform'. The examples show animating a rectangle's rotation, a circle's scale, and combined transformations, saving the results to 'animate_transform.svg'. ```python import drawsvg as draw d = draw.Drawing(300, 150) # Rotating rectangle rect = draw.Rectangle(-20, -10, 40, 20, fill='blue') rect.append_anim(draw.AnimateTransform('rotate', '2s', '0 50 50;360 50 50', repeatCount='indefinite')) g = draw.Group(transform='translate(50, 75)') g.append(rect) d.append(g) # Scaling circle circle = draw.Circle(150, 75, 20, fill='green') circle.append_anim(draw.AnimateTransform('scale', '1.5s', '1;1.5;1', repeatCount='indefinite')) d.append(circle) # Combined transform animation rect2 = draw.Rectangle(220, 55, 40, 40, fill='red') rect2.append_anim(draw.AnimateTransform('rotate', '3s', '0 240 75;360 240 75', repeatCount='indefinite')) d.append(rect2) d.save_svg('animate_transform.svg') ``` -------------------------------- ### Create Interactive Drawing Widget with Mouse Events Source: https://github.com/cduck/drawsvg/blob/master/README.md Demonstrates how to initialize a DrawingWidget and bind mousedown and mousemove events to manipulate drawing state. This functionality is currently limited to Jupyter Notebook environments. ```python widget = DrawingWidget(d) @widget.mousedown def mousedown(widget, x, y, info): if (x**2 + y**2) ** 0.5 + 1e-5 < 1: click_list.append((x, y)) redraw(click_list) widget.refresh() @widget.mousemove def mousemove(widget, x, y, info): if (x**2 + y**2) ** 0.5 + 1e-5 < 1: redraw(click_list + [(x, y)]) widget.refresh() widget ``` -------------------------------- ### DrawSVG: Embed Google Fonts Source: https://context7.com/cduck/drawsvg/llms.txt Shows how to embed Google Fonts directly into an SVG using DrawSVG. This ensures consistent font rendering across different platforms by downloading and embedding the necessary CSS. The example demonstrates embedding 'Permanent Marker' and 'Roboto' fonts and using them in text elements. ```python import drawsvg as draw d = draw.Drawing(400, 150) # Embed a Google Font (downloads and embeds CSS) d.embed_google_font('Permanent Marker', text=set('Hello World')) d.embed_google_font('Roboto', text=set('Regular text')) # Use the embedded fonts d.append(draw.Text('Hello World', 48, 200, 50, font_family='Permanent Marker', text_anchor='middle', fill='purple')) d.append(draw.Text('Regular text', 24, 200, 100, font_family='Roboto', text_anchor='middle', fill='black')) d.save_svg('custom_fonts.svg') ``` -------------------------------- ### Extend DrawSVG with Custom SVG Elements Source: https://context7.com/cduck/drawsvg/llms.txt Illustrates how to extend the DrawSVG library by creating custom SVG elements. It shows examples of creating a custom element without children (ForeignObject) and a custom element with children (Hyperlink) by subclassing DrawSVG's base classes and overriding necessary methods. ```python import drawsvg as draw # Custom element without children class ForeignObject(draw.DrawingBasicElement): TAG_NAME = 'foreignObject' has_content = True def __init__(self, content, x, y, width, height, **kwargs): super().__init__(x=x, y=y, width=width, height=height, **kwargs) self.content = content def write_content(self, id_map, is_duplicate, output_file, lcontext, dry_run): if not dry_run: output_file.write(self.content) # Custom element with children (like hyperlink) class Hyperlink(draw.DrawingParentElement): TAG_NAME = 'a' def __init__(self, href, target=None, **kwargs): super().__init__(href=href, target=target, **kwargs) # Usage d = draw.Drawing(300, 150) # Add hyperlink with child elements link = Hyperlink('https://example.com', target='_blank') link.append(draw.Circle(75, 75, 50, fill='blue')) link.append(draw.Text('Click me', 16, 75, 75, center=True, fill='white')) d.append(link) # Add foreign object with HTML content html_content = '