drawing_animation_plus 
| From static SVG assets | See more examples in the showcasing app. | |
|---|---|---|
![]() |
![]() |
![]() |
| Dynamically created from Path objects which are animated over time | ||
![]() |
![]() |
drawing_animation_plus is a maintained fork of drawing_animation.
It exposes a central widget called AnimatedDrawing which renders SVG paths (via AnimatedDrawing.svg or
AnimatedDrawing.svgString) or Flutter Path objects (via AnimatedDrawing.paths) in a drawing like fashion.
Compared to the original package it adds a much more complete SVG parser (shapes, groups, transforms, style sheets,
all CSS color formats), web support, a repeat flag, stroke overrides, more path orders, correct onPaint
callbacks and fixes a number of crashes (see the CHANGELOG).
Getting Started - AnimatedDrawing.svg
- Add the dependency to your
pubspec.yaml
dependencies:
drawing_animation_plus: ^1.1.0
- Add the SVG asset
flutter:
assets:
- assets/my_drawing.svg
-
Use the widget
An
AnimatedDrawingwidget can be initiated in two ways:-
Simplified - without animation controller (see Example_01)
By default every animation repeats infinitely. Set
repeattofalseto run it only once, or use theonFinishcallback to setruntofalseafter the first animation cycle completed.AnimatedDrawing.svg( "assets/my_drawing.svg", run: this.run, duration: const Duration(seconds: 3), repeat: false, onFinish: () => print('done'), ) -
Standard - with animation controller (see Example_02)
If you want to control the animation yourself or synchronize it with other animations, provide a custom AnimationController. Reversing the controller un-draws the drawing.
AnimatedDrawing.svg( "assets/my_drawing.svg", controller: this.controller, animationCurve: Curves.easeInOut, )
-
-
Check out the examples in the
examplefolder. Anti-aliasing of the canvas may be switched off in debug mode, for pretty results useflutter run --release.
SVG markup from memory or the network
AnimatedDrawing.svgString(
'<svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" stroke="#0074d9"/></svg>',
run: true,
duration: const Duration(seconds: 2),
)
Getting Started - AnimatedDrawing.paths
By providing Path objects directly to the widget, elements can be changed dynamically, even during the animation
(see Example_01 and Example_04). The internal data structure is
rebuilt whenever a different list of paths (or different Path objects) is provided.
AnimatedDrawing.paths(
[
// Path objects
],
paints: [
// Paint objects (optional), one for each Path element in `paths`.
],
run: this.run,
duration: const Duration(seconds: 3),
)
Option list
| Field | Type | Example |
|---|---|---|
lineAnimation Specifies in which way the path elements are drawn to the canvas. When allAtOnce is selected all path segments are drawn simultaneously. oneByOne paints every path segment one after another. |
LineAnimation.oneByOne |
![]() |
LineAnimation.allAtOnce |
![]() |
|
animationOrder Denotes the order in which the path elements are drawn to the canvas when lineAnimation is set to LineAnimation.oneByOne. Defaults to the order of the SVG asset or path list (PathOrders.original). Every PathOrder can be .reversed or .combined with another one; groupByPath: true keeps all contours of a path together. |
PathOrders.original |
![]() |
PathOrders.bottomToTop |
![]() |
|
PathOrders.decreasingLength |
![]() |
|
PathOrders.increasingLength |
![]() |
|
PathOrders.leftToRight |
![]() |
|
PathOrders.rightToLeft |
![]() |
|
PathOrders.topToBottom |
![]() |
|
animationCurve Easing curves adjust the rate of change of an animation over time. See the Flutter docs. Also applied to external controllers. |
Curves.linear |
![]() |
Curves.elasticOut |
![]() |
|
Curves.bounceInOut |
![]() |
|
Curves.decelerate |
![]() |
|
| Other | ||
run / duration / repeat Control the built-in animation controller. Setting run to false pauses, setting it to true again restarts. repeat (default true) restarts the animation after each cycle. |
||
onFinish Callback when one animation cycle is finished. |
||
onPaint Callback when a path is completely painted to the canvas. Returns the index and the Path itself. |
||
range Animate only the paths within a PathIndexRange; paths below the range are painted immediately, paths above are excluded. |
||
width / height Fixed dimensions of the widget. If only one is given the aspect ratio of the drawing is preserved. Without them the widget fills its parent (or uses the aspect ratio in unbounded parents). |
||
scaleToViewport Paths are scaled to the available viewport while maintaining the aspect ratio. Defaults to true. |
||
strokeColor / strokeWidth Override the stroke color/width of all paths (paths with an entry in paints are not affected). |
||
paints AnimatedDrawing.paths only: one Paint per path. |
||
debug DebugOptions to show the bounding box/viewport or to record every frame as PNG (onFrame or files), e.g. for creating GIFs (see Example_04). |
Supported SVG specifications
- Elements:
path,rect(incl.rx/ry),circle,ellipse,line,polyline,polygon, containerssvg,g,a,switch. Everything insidedefs,symbol,clipPath,mask,marker,patternand unsupported elements such astext,imageoruseis ignored. - Attributes (as presentation attributes, inline
styleor simple<style>sheets with tag, class and id selectors):stroke,stroke-width(withpx,pt,pc,mm,cm,inunits),stroke-linecap,stroke-linejoin,stroke-opacity,opacity,color,display,visibility,transform. - Colors:
#rgb,#rgba,#rrggbb,#rrggbbaa,rgb(),rgba(),hsl(),hsla(), CSS named colors,none,transparent,currentColor. Paint servers (url(#gradient)) fall back to their fallback color. - Transforms:
matrix,translate,scale,rotate,skewX,skewY, also nested in groups. - Elements without
strokeare drawn in black with a hairline stroke width; usestrokeColor/strokeWidthto override.fillis ignored: the animation always strokes the outlines.
Elements that can not be parsed are skipped and reported through debugPrint (use SvgParser(strict: true) to
throw instead).
Known limitations
- Lengths of curved segments are measured by the Flutter engine with a coarse tolerance; conic curves (as created by
Path.addOval/Path.addArc) are measured as straight chords. This only affects the relative speed of the animation, not the rendering. The SVG shapes of this package are built from cubic curves to keep timing accurate. text,use, gradients, patterns, clipping, masks, percentage andemlengths and complex CSS selectors are not supported.
How can I use my own SVG files?
Most SVG files exported from Inkscape, Illustrator or Figma work out of the box. For files using unsupported
features you can convert the artwork in Inkscape: select all objects, ungroup (Ctrl+U), convert to paths
(Path >> Object to Path) and save, optionally running the result through svgo or
svgomg.
Examples
Example_01: Set up the simplifiedAnimatedDrawingwithAnimatedDrawing.svgandAnimatedDrawing.pathsExample_02: Set upAnimatedDrawingwith a custom animation controllerExample_03: Small artistic showcasing app with vectorized drawings of old book scans provided by the British LibraryExample_04: Shows how to create high resolution GIFs using thedebugfield
Migrating from drawing_animation
Replace the dependency and the import (package:drawing_animation_plus/drawing_animation_plus.dart). The API is
source compatible; note that onPaint now fires when a path is completely painted (as documented) and that an
empty paths list no longer throws.
Credits
Thank you to biocarl for the original drawing_animation package, to maxwellito for the vivus project which served as initial inspiration and to dnfield for the path_parsing library.
Credits to the British Library for their awesome collection of old book scans which are used in the showcasing app.
Libraries
- drawing_animation_plus
- drawing_animation_plus

















