SVGA Player Pro
Introduce
SVGAPlayer is a light-weight animation renderer. You use tools to export svga file from Adobe Animate CC or Adobe After Effects, and then use SVGAPlayer to render animation on mobile application.
SVGAPlayer-Pro render animation natively via Flutter CustomPainter, brings you a high-performance, low-cost animation experience.
If wonder more information, go to this website.
- SVGAPlayer-Flutter supports 2.0 format only.
Usage
Here introduce SVGAPlayer-Pro usage. Wonder exporting usage? Click here.
Add dependency
dependencies:
svgaplayer_pro: ^0.3.2
Locate files
SVGAPlayer could load svga file from Flutter local assets directory or remote server. Add file to pubspec.yaml by yourself.
Super simple to use
The simplest way to render an animation is to use SVGASimpleImage component.
class MyWidget extends StatelessWidget {
const MyWidget({super.key});
@override
Widget build(BuildContext context) {
return Container(
child: SVGASimpleImage(
resUrl: "https://github.com/yyued/SVGA-Samples/blob/master/angel.svga?raw=true"),
);
}
}
Animation will run repeatedly. If you wondering a stronger animation controls, use code.
Code to use
To control an animation rendering, you need to create a SVGAAnimationController instance just like Flutter regular animation. Assign to SVGAImage, load and decode resource using SVGAParser, and then do things as you want with SVGAAnimationController.
import 'package:flutter/widgets.dart';
import 'package:svgaplayer_pro/svgaplayer_flutter.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
late final SVGAAnimationController animationController;
@override
void initState() {
super.initState();
animationController = SVGAAnimationController(vsync: this);
loadAnimation();
}
@override
void dispose() {
this.animationController.dispose();
super.dispose();
}
Future<void> loadAnimation() async {
try {
final videoItem = await SVGAParser.shared.decodeFromURL(
"https://github.com/yyued/SVGA-Samples/blob/master/angel.svga?raw=true");
if (!mounted) {
videoItem.dispose();
return;
}
animationController
..videoItem = videoItem
..repeat(); // Or use forward() / reverse().
} catch (error) {
if (mounted) debugPrint('SVGA load failed: $error');
}
}
@override
Widget build(BuildContext context) {
return Container(
child: SVGAImage(this.animationController),
);
}
}
Reuse MovieEntity
The MovieEntity will dispose after AnimationController dispose or AnimationController::videoItem reset.
After dispose, the MovieEntity can not reused.
If you eager to reuse the MovieEntity, assign MovieEntity::autorelease to false.
final videoItem = await SVGAParser.shared.decodeFromURL(
"https://github.com/yyued/SVGA-Samples/blob/master/angel.svga?raw=true");
videoItem.autorelease = false;
You need to call MovieEntity::dispose() method when no need to use.
Cache
Downloads are not cached. Use dio or another network library for persistent download caching; decoded resources are cached for the lifetime of a movie.
Use SVGAParser.decodeFromBytes (alias of decodeFromBuffer) to decode caching data.
Audio
SVGA files that embed MP3 tracks play automatically with the animation. Control gain on the controller:
animationController.volume = 0.5; // 0.0 ~ 1.0
animationController.muted = true;
Features
Here are many feature samples.
- Replace an element with Bitmap.
- Add text above an element.
- Hides an element dynamicaly.
- Use a custom drawer for element.
Resource lifecycle and limits
SVGAParser bounds downloads (64 MiB), inflated data (128 MiB), individual
images (16 megapixels), and decoded images per movie (256 MiB). Downloads have a
30-second total timeout. These limits are configurable in the parser constructor.
Invalid movies and images fail the returned Future; catch errors when loading.
Native platforms parse in a worker isolate; Web uses the browser event loop.
Use const SVGAParser(retainSourceImages: false) to release encoded media after
loading when the movie will not be serialized again. The default retains it for
compatibility. Call movie.dispose() when manually managing a movie with
autorelease = false.
setImage retains its own image clone; callers still dispose their original.
setImageWithUrl owns its downloaded image. setText borrows the TextPainter by
default; pass owned: true to transfer ownership. Owned resources are released on
replacement, reset(), or movie disposal. Setter methods notify paused views.
Direct writes to the public dynamic maps require calling refresh();
resources inserted directly remain caller-owned.
After mutating generated shapes, transforms or sprite keys, call
movie.invalidateRenderCaches() and notify/rebuild the view. Short sprite
tracks disappear after their final frame. Matte layers use alpha masks and are
not drawn as ordinary content. Audio seeks with the animation, plays once per
forward cycle, and is paused during reverse playback. Web audio is unsupported.
Verification
Run flutter analyze and flutter test in the package, and flutter test in
example/. Optional network integration uses local static resource fixtures:
postman simulation run postman/simulations/resources.sim.yaml --port 4910 --no-history
# In a second terminal:
dart run tool/check_network.dart
flutter test --dart-define=SVGA_RESOURCE_BASE=http://127.0.0.1:4910/resources test/network_resource_integration_test.dart
The simulation models successful binary downloads, HTTP errors, delayed replies
and oversized responses; it does not need a cloud workspace. Stop it with Ctrl-C.
Without SVGA_RESOURCE_BASE, the three network integration tests are skipped.