drawing_animation_plus Pub

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

  1. Add the dependency to your pubspec.yaml
dependencies:
  drawing_animation_plus: ^1.1.0
  1. Add the SVG asset
flutter:
  assets:
    - assets/my_drawing.svg
  1. Use the widget

    An AnimatedDrawing widget can be initiated in two ways:

    1. Simplified - without animation controller (see Example_01)

      By default every animation repeats infinitely. Set repeat to false to run it only once, or use the onFinish callback to set run to false after the first animation cycle completed.

      AnimatedDrawing.svg(
        "assets/my_drawing.svg",
        run: this.run,
        duration: const Duration(seconds: 3),
        repeat: false,
        onFinish: () => print('done'),
      )
      
    2. 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,
      )
      
  2. Check out the examples in the example folder. Anti-aliasing of the canvas may be switched off in debug mode, for pretty results use flutter 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, containers svg, g, a, switch. Everything inside defs, symbol, clipPath, mask, marker, pattern and unsupported elements such as text, image or use is ignored.
  • Attributes (as presentation attributes, inline style or simple <style> sheets with tag, class and id selectors): stroke, stroke-width (with px, pt, pc, mm, cm, in units), 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 stroke are drawn in black with a hairline stroke width; use strokeColor/strokeWidth to override. fill is 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 and em lengths 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 simplified AnimatedDrawing with AnimatedDrawing.svg and AnimatedDrawing.paths
  • Example_02: Set up AnimatedDrawing with a custom animation controller
  • Example_03: Small artistic showcasing app with vectorized drawings of old book scans provided by the British Library
  • Example_04: Shows how to create high resolution GIFs using the debug field

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