flutter_spritesheet_animation
Flutter के लिए हल्का स्प्राइटशीट एनीमेशन विजेट। ग्रिड-आधारित और JSON एटलस (TexturePacker, Aseprite) के समर्थन के साथ नामित एनीमेशन, प्लेबैक मोड और बाहरी कंट्रोलर के साथ।
Flutter के लिए हल्का स्प्राइटशीट एनीमेशन विजेट। ग्रिड-आधारित और JSON एटलस (TexturePacker, Aseprite) के समर्थन के साथ नामित एनीमेशन, प्लेबैक मोड और बाहरी कंट्रोलर के साथ।
यह अंग्रेज़ी मूल स्नैपशॉट है। नवीनतम सामग्री GitHub पर देखें।
Lightweight spritesheet animation widget for Flutter. Supports grid-based and JSON atlas (TexturePacker, Aseprite) spritesheets with named animations, playback modes, and an external controller.
Zero external dependencies - uses only the Flutter SDK.
frameTagsdependencies:
flutter_spritesheet_animation: ^1.0.2
For spritesheets with frames arranged in a uniform grid:
SpriteAnimation.grid(
image: AssetImage('assets/explosion.png'),
columns: 8,
rows: 4,
frameCount: 30, // optional, defaults to columns * rows
fps: 24,
width: 128,
height: 128,
)
For spritesheets defined by a JSON atlas (TexturePacker or Aseprite export):
// Load atlas from asset
final atlas = await SpriteAtlas.fromAsset('assets/character.json');
SpriteAnimation.atlas(
image: AssetImage('assets/character.png'),
atlas: atlas,
animation: 'idle', // named animation from frameTags
width: 128,
height: 128,
)
Use SpriteAnimationController for programmatic playback control:
final controller = SpriteAnimationController(
fps: 24,
mode: PlayMode.pingPong,
loop: true,
autoPlay: false,
);
// In your widget tree
SpriteAnimation.grid(
image: AssetImage('assets/explosion.png'),
columns: 8,
rows: 4,
controller: controller,
)
// Control playback
controller.play();
controller.pause();
controller.stop();
controller.goToFrame(5);
// Change settings at runtime
controller.fps = 30;
controller.mode = PlayMode.reverse;
controller.loop = false;
// Switch named animations (atlas mode)
controller.setAnimation('walk', atlas: atlas);
// Read state
controller.isPlaying; // bool
controller.currentFrame; // int
controller.totalFrames; // int
controller.animationName; // String?
// Don't forget to dispose when using externally
controller.dispose();
Pre-cache spritesheet images to eliminate loading flash:
// Single image
await SpriteAnimation.precache(
const AssetImage('assets/explosion.png'),
context,
);
// Multiple images in parallel
await SpriteAnimation.precacheAll([
const AssetImage('assets/idle.png'),
const AssetImage('assets/walk.png'),
const AssetImage('assets/attack.png'),
], context);
SpriteAnimation.grid(
image: AssetImage('assets/explosion.png'),
columns: 8,
rows: 4,
loop: false,
onFrame: (frame) => print('Frame: $frame'),
onComplete: () => print('Animation finished'),
)
TexturePacker (hash):
{
"frames": {
"idle_0.png": {
"frame": { "x": 0, "y": 0, "w": 64, "h": 64 },
"rotated": false,
"trimmed": false,
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
"sourceSize": { "w": 64, "h": 64 }
}
},
"meta": {
"size": { "w": 256, "h": 256 },
"frameTags": [
{ "name": "idle", "from": 0, "to": 3 },
{ "name": "walk", "from": 4, "to": 9 }
]
}
}
Aseprite (array):
{
"frames": [
{
"filename": "idle_0.png",
"frame": { "x": 0, "y": 0, "w": 64, "h": 64 },
"duration": 100
}
],
"meta": {
"frameTags": [
{ "name": "idle", "from": 0, "to": 3 }
]
}
}
Both formats are auto-detected.
Optimized for smooth 60fps animation rendering:
CustomPainter(repaint: controller) — frame changes repaint only the paint layer, skipping build() entirelyDuration objects in the hot pathprecache() / precacheAll() to eliminate loading flash| Property | Type | Default | Description |
|---|---|---|---|
image |
ImageProvider |
required | Spritesheet image |
columns |
int |
- | Grid columns (grid mode) |
rows |
int |
- | Grid rows (grid mode) |
frameCount |
int? |
columns*rows | Total frames (grid mode) |
atlas |
SpriteAtlas |
- | Atlas data (atlas mode) |
animation |
String? |
first | Animation name (atlas mode) |
fps |
double |
12 | Frames per second |
autoPlay |
bool |
true | Start automatically |
loop |
bool |
true | Loop animation |
mode |
PlayMode |
forward | Playback direction |
blendMode |
BlendMode |
srcOver | Canvas blend mode |
fit |
BoxFit |
contain | How sprite fits in bounds |
width |
double? |
- | Fixed width |
height |
double? |
- | Fixed height |
controller |
SpriteAnimationController? |
- | External controller |
onFrame |
ValueChanged<int>? |
- | Frame change callback |
onComplete |
VoidCallback? |
- | Completion callback |
| Method | Description |
|---|---|
play() |
Start or resume playback |
pause() |
Pause at current frame |
stop() |
Stop and reset to frame 0 |
goToFrame(int) |
Jump to specific frame |
setAnimation(String, {SpriteAtlas}) |
Switch named animation |
dispose() |
Clean up resources |
| Property | Type | Default | Description |
|---|---|---|---|
speed |
double |
1 | Playback multiplier applied to the whole clock |
repeatCount |
int? |
null | Cycles to play before completing; null is unlimited |
completedCycles |
int |
0 | Cycles finished since playback started |
onCycle |
ValueChanged<int>? |
- | Fires on every wrap of a looping animation |
fps sets the base frame rate, but atlas animations carry per-frame
durations and ignore it. speed scales the clock either way:
final controller = SpriteAnimationController(speed: 2); // twice as fast
controller.speed = 0.5; // half speed
// Play the effect three times, then stop and call onComplete
final controller = SpriteAnimationController(repeatCount: 3)
..onCycle = (done) => debugPrint('cycle $done')
..onComplete = () => debugPrint('done');
repeatCount only applies while loop is true: a non-looping animation
always stops after one pass.
| Method | Description |
|---|---|
SpriteAtlas.fromJson(String) |
Parse from JSON string |
SpriteAtlas.fromAsset(String) |
Load from Flutter asset |
getAnimation(String) |
Get animation data by name |
animationNames |
List of available animation names |
MIT
निर्भरता सूची 3 आइटम
{"sdk":"flutter"}{"sdk":"flutter"}^6.0.0उपयोग के अनुसार छाँटें, गतिविधि की तुलना करें और अपनाने से पहले मूल प्रोजेक्ट की आवश्यकताएँ जाँचें।
“A repository is the most basic element of GitHub.”
GitHub Docs — About repositories ↗