drawing_animation_plus 1.2.0
drawing_animation_plus: ^1.2.0 copied to clipboard
Gradually paint SVG paths or Flutter Path objects on a canvas (drawing line animation) with orders, curves, ranges and callbacks.
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), animated fills, web support, a repeat flag, stroke and paint overrides, more path orders,
accessibility support, 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.
Animated fills #
Outlines are drawn first; with fillMode the fills of the SVG elements appear as well. FillMode.afterStroke fades
the fill of every element in as soon as its outline is complete (the classic "draw, then fill" look),
FillMode.always shows the fills from the start.
AnimatedDrawing.svg(
"assets/logo.svg",
run: true,
duration: const Duration(seconds: 3),
fillMode: FillMode.afterStroke,
fillFade: 0.15, // each fill fades in over 15% of the animation
)
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). |
||
paintBuilder Callback (int pathIndex, Paint paint) => Paint? to customize the paint of every path, e.g. to color paths by index. |
||
fillMode / fillColor / fillFade Paint the fills of the SVG elements: FillMode.afterStroke fades each fill in once its outline is drawn, FillMode.always shows them from the start. fillColor overrides the parsed fill color (required for AnimatedDrawing.paths). |
||
semanticsLabel Description of the drawing for screen readers. |
||
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,fill,fill-opacity,fill-rule,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. Fills are only painted whenfillModeis set (elements withoutfillare black, as defined by the SVG specification).
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.
Performance #
Parsing and painting are cheap: the largest example asset (149 KB, 968 segments) parses in about 3 ms and a frame
is recorded in less than 0.2 ms (see benchmark/). The widget repaints inside its own RepaintBoundary, so the
rest of your UI is not repainted while the animation runs. AnimatedDrawing.paths only re-parses the paths when a
different list (or different Path objects) is provided.
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.

















