├── docs └── img │ ├── 04_fonts1.png │ ├── 04_fonts2.png │ ├── example1.png │ ├── 01_line.svg │ ├── 01_multilines.svg │ ├── 01_polygon.svg │ ├── 04_tspan3.svg │ ├── 03_pHV.svg │ ├── 03_pZ.svg │ ├── 04_tspan2.svg │ ├── 07_trans.svg │ ├── 04_rot2.svg │ ├── 03_pL.svg │ ├── 04_rot.svg │ ├── 01_circ.svg │ ├── 04_tspan.svg │ ├── 01_ellip.svg │ ├── 03_pT.svg │ ├── 01_multilines2.svg │ ├── 07_cart1.svg │ ├── 07_scale.svg │ ├── 07_scale2.svg │ ├── 07_cart3.svg │ ├── 02_dash.svg │ ├── 07_cart2.svg │ ├── 05_lingrad.svg │ ├── 02_join.svg │ ├── 02_mlimit.svg │ ├── 05_radgrad.svg │ ├── 06_use.svg │ ├── 07_rota.svg │ ├── 02_fsc.svg │ ├── 03_pA.svg │ ├── 05_clip.svg │ ├── 02_linecap.svg │ ├── 01_rect.svg │ ├── 01_rectround.svg │ ├── 07_rota2.svg │ ├── 05_mask.svg │ ├── 04_multiline_text.svg │ ├── 04_mutiline_text.svg │ ├── 07_scalcent.svg │ ├── 03_pS.svg │ ├── 05_clip2.svg │ ├── 07_skew.svg │ ├── 04_len.svg │ ├── 03_pQ.svg │ ├── 04_fill.svg │ ├── 04_align.svg │ ├── 06_group.svg │ ├── 04_weight.svg │ ├── 02_foso.svg │ ├── 05_clip3.svg │ ├── 05_mask3.svg │ ├── 02_strokewdth.svg │ ├── 04_path.svg │ ├── 05_mask2.svg │ └── 03_pC.svg ├── examples ├── example1.png ├── example2.png ├── example3.png ├── example4.png ├── example5.gif ├── example6.gif ├── example6.png ├── example7.gif ├── example8.png ├── orbit-spritesheet.png ├── example3.svg ├── example4.svg ├── example8.svg ├── animated.svg ├── example2.svg ├── example1.svg ├── animated-fix-github.svg ├── playback-controls.svg ├── playback-controls.html └── font.svg ├── .gitignore ├── mkdocs.yml ├── drawsvg ├── widgets │ ├── __init__.py │ ├── async_animation.py │ ├── drawing_javascript.py │ └── drawing_widget.py ├── native_animation │ ├── __init__.py │ ├── playback_control_ui.py │ ├── playback_control_js.py │ └── synced_animation.py ├── jupyter.py ├── url_encode.py ├── font_embed.py ├── raster.py ├── __init__.py ├── defs.py ├── frame_animation.py ├── color.py ├── video.py ├── types.py └── drawing.py ├── FUNDING.yml ├── LICENSE.txt ├── setup.py └── README.md /docs/img/04_fonts1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cduck/drawsvg/HEAD/docs/img/04_fonts1.png -------------------------------------------------------------------------------- /docs/img/04_fonts2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cduck/drawsvg/HEAD/docs/img/04_fonts2.png -------------------------------------------------------------------------------- /docs/img/example1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cduck/drawsvg/HEAD/docs/img/example1.png -------------------------------------------------------------------------------- /examples/example1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cduck/drawsvg/HEAD/examples/example1.png -------------------------------------------------------------------------------- /examples/example2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cduck/drawsvg/HEAD/examples/example2.png -------------------------------------------------------------------------------- /examples/example3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cduck/drawsvg/HEAD/examples/example3.png -------------------------------------------------------------------------------- /examples/example4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cduck/drawsvg/HEAD/examples/example4.png -------------------------------------------------------------------------------- /examples/example5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cduck/drawsvg/HEAD/examples/example5.gif -------------------------------------------------------------------------------- /examples/example6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cduck/drawsvg/HEAD/examples/example6.gif -------------------------------------------------------------------------------- /examples/example6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cduck/drawsvg/HEAD/examples/example6.png -------------------------------------------------------------------------------- /examples/example7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cduck/drawsvg/HEAD/examples/example7.gif -------------------------------------------------------------------------------- /examples/example8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cduck/drawsvg/HEAD/examples/example8.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | __pycache__ 3 | /MANIFEST 4 | /dist 5 | /*.egg-info 6 | *.ipynb_checkpoints 7 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Drawsvg Quick Reference 2 | nav: 3 | - Home: index.md 4 | theme: readthedocs 5 | -------------------------------------------------------------------------------- /examples/orbit-spritesheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cduck/drawsvg/HEAD/examples/orbit-spritesheet.png -------------------------------------------------------------------------------- /drawsvg/widgets/__init__.py: -------------------------------------------------------------------------------- 1 | from .drawing_widget import DrawingWidget 2 | from .async_animation import AsyncAnimation 3 | -------------------------------------------------------------------------------- /FUNDING.yml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/displaying-a-sponsor-button-in-your-repository 2 | 3 | github: [cduck] 4 | -------------------------------------------------------------------------------- /docs/img/01_line.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /drawsvg/native_animation/__init__.py: -------------------------------------------------------------------------------- 1 | from .synced_animation import ( 2 | SyncedAnimationConfig, 3 | AnimatedAttributeTimeline, 4 | AnimationHelperData, 5 | animate_element_sequence, 6 | animate_text_sequence, 7 | ) 8 | from .playback_control_ui import draw_scrub 9 | -------------------------------------------------------------------------------- /docs/img/01_multilines.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /docs/img/01_polygon.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /docs/img/04_tspan3.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Fall 7 | -------------------------------------------------------------------------------- /docs/img/03_pHV.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/img/03_pZ.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/img/04_tspan2.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Fall 7 | -------------------------------------------------------------------------------- /docs/img/07_trans.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/img/04_rot2.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | ROTATE 7 | -------------------------------------------------------------------------------- /docs/img/03_pL.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /docs/img/04_rot.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Rotate 7 | Rotate 8 | -------------------------------------------------------------------------------- /docs/img/01_circ.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/img/04_tspan.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Switch among italic, normal, and bold text. 7 | -------------------------------------------------------------------------------- /docs/img/01_ellip.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/img/03_pT.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/img/01_multilines2.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /docs/img/07_cart1.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | downward y 9 | -------------------------------------------------------------------------------- /docs/img/07_scale.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/img/07_scale2.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/img/07_cart3.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | upward y 9 | -------------------------------------------------------------------------------- /docs/img/02_dash.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/img/07_cart2.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | upward y 10 | 11 | -------------------------------------------------------------------------------- /docs/img/05_lingrad.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /docs/img/02_join.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/img/02_mlimit.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/img/05_radgrad.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /docs/img/06_use.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/img/07_rota.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/example3.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/img/02_fsc.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /docs/img/03_pA.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/example4.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | Hyperlink 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/img/05_clip.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/img/02_linecap.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /docs/img/01_rect.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/example8.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /docs/img/01_rectround.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /docs/img/07_rota2.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/img/05_mask.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /docs/img/04_multiline_text.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | this isamultiline textgiven as alist 7 | this isamultiline textgiven as astring 8 | -------------------------------------------------------------------------------- /docs/img/04_mutiline_text.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | this isamultiline textgiven as alist 7 | this isamultiline textgiven as astring 8 | -------------------------------------------------------------------------------- /docs/img/07_scalcent.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/img/03_pS.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/img/05_clip2.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/img/07_skew.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | skewX 15 | 16 | 17 | 18 | 19 | 20 | skewY 21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/img/04_len.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Two words 7 | Two words 8 | Two words (normal length) 9 | Two words 10 | Two words 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/img/03_pQ.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/img/04_fill.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | Simplest Text 8 | Outline / Filled 9 | Too big stroke 10 | Outlined only 11 | Outlined and colored 12 | Colored fill only 13 | -------------------------------------------------------------------------------- /docs/img/04_align.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Start 11 | Middle 12 | End 13 | Auto 14 | Middle 15 | Hanging 16 | -------------------------------------------------------------------------------- /docs/img/06_group.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /examples/animated.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/img/04_weight.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | bold 7 | italic 8 | under 9 | over 10 | through 11 | normal word space 12 | more word space 13 | less word space 14 | wide letter space 15 | narrow letter space 16 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2023 Casey Duckering 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | 9 | -------------------------------------------------------------------------------- /docs/img/02_foso.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/img/05_clip3.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | CLIP 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /drawsvg/jupyter.py: -------------------------------------------------------------------------------- 1 | import dataclasses 2 | 3 | from . import url_encode 4 | from . import raster 5 | 6 | 7 | class _Rasterizable: 8 | def rasterize(self, to_file=None): 9 | if to_file is not None: 10 | return raster.Raster.from_svg_to_file(self.svg, to_file) 11 | else: 12 | return raster.Raster.from_svg(self.svg) 13 | 14 | @dataclasses.dataclass 15 | class JupyterSvgInline(_Rasterizable): 16 | '''Jupyter-displayable SVG displayed inline on the Jupyter web page.''' 17 | svg: str 18 | def _repr_html_(self): 19 | return self.svg 20 | 21 | @dataclasses.dataclass 22 | class JupyterSvgImage(_Rasterizable): 23 | '''Jupyter-displayable SVG displayed within an img tag on the Jupyter web 24 | page. 25 | ''' 26 | svg: str 27 | def _repr_html_(self): 28 | uri = url_encode.svg_as_utf8_data_uri(self.svg) 29 | return ''.format(uri) 30 | 31 | @dataclasses.dataclass 32 | class JupyterSvgFrame: 33 | '''Jupyter-displayable SVG displayed within an HTML iframe.''' 34 | svg: str 35 | width: float 36 | height: float 37 | mime: str = 'image/svg+xml' 38 | def _repr_html_(self): 39 | uri = url_encode.svg_as_data_uri(self.svg, mime=self.mime) 40 | return (f'