Repository: flutter
Issue: [Proposal] Add AnimatedImageController to communicate with animated images (GIF, AVIF, APNG, etc)
Labels: c: new feature,framework,a: images,c: proposal,P3,team-framework,triaged-framework

There is no normal API to communicate with animated images (GIF, AVIF, APNG, etc). 
Actually we can just specify source of image. But there are no way to specify initial frame, reverse, forward or set new current frame.
## Use case

Current implementation is cut. With this feature we could use GIFs fully. For example, bind animation images to user's gestures, system status or success/failure result from services.

## Proposal

```dart
class AnimatedImageValue {
  AnimatedImageValue({
    required this.status,
    required this.loading,
    required this.cachedFrames,
    required this.totalFrames,
    required this.currentFrame,
  });

  final AnimationStatus status;
  final bool loading;
  final int cachedFrames;
  final int totalFrames;
  final int currentFrame;

  bool get allFramesCached => cachedFrames == totalFrames;
}
```

With naive implementation 

```dart
class AnimatedImageController extends ValueNotifier<AnimatedImageValue> {
  AnimatedImageController({
    int initialFrame = 0,
    bool initialPlaying = true,
    required TickerProvider vsync,
  }) : super(
          AnimatedImageValue(
            status: initialPlaying ? AnimationStatus.forward : AnimationStatus.dismissed,
            loading: false,
            cachedFrames: 0,
            currentFrame: initialFrame,
            totalFrames: 1,
          ),
        );

  void forward({bool loop = true}) {} // Play animation forward

  void reverse({bool loop = true}) {} // Play animation reverse

  void reset() {} // Set current frame to currentFrame = 0

  void drive(Animatable<double> animatable, {bool loop = true}) {} // Animate by function

  void stop() {} // Stop animation

  set frame(int f) {
    value = value.copyWith(currentFrame: f);
  }
}
```
Suppose that actions could be sync (when all frames are cached)
And usage:
```dart
class LivePhotoApp extends StatefulWidget {
  const LivePhotoApp({Key? key}) : super(key: key);

  @override
  State<LivePhotoApp> createState() => _LivePhotoAppState();
}

class _LivePhotoAppState extends State<LivePhotoApp> with TickerProviderStateMixin {
  late AnimatedImageController _controller = AnimatedImageController(
    initialFrame: 10,
    initialPlaying: false,
    vsync: this,
  );

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Expanded(
          child: Image.asset(
            'assets/image.HEIC',
            animatedController: _controller,
          ),
        ),
        Row(
          children: [
            Expanded(
              child: ElevatedButton(
                onPressed: () => _controller.stop(),
                child: Text('Stop'),
              ),
            ),
            const SizedBox(width: 12),
            Expanded(
              child: ElevatedButton(
                onPressed: () => _controller.forward(),
                child: Text('Start'),
              ),
            ),
          ],
        ),
      ],
    );
  }
}
```
This controller doesn't need to contain state of animation by itself, because widget Image already handle it. But just provide view of data, and put events in Image