import 'dart:collection'; | |
import 'image.dart'; | |
/// Stores multiple images, most often as the frames of an animation. | |
/// | |
/// Some formats, such as [TiffDecoder], support multiple images that are not | |
/// to be interpreted as animation, but rather multiple pages of a document. | |
/// The [Animation] container is still used to store the images for these files. | |
/// The [frameType] property is used to differentiate multi-page documents from | |
/// multi-frame animations, where it is set to [PAGE] for documents and | |
/// [ANIMATION] for animated frames. | |
/// | |
/// All [Decoder] classes support decoding to an [Animation], where the | |
/// [Animation] will only contain a single frame for single image formats | |
/// such as JPEG, or if the file doesn't contain any animation such as a single | |
/// image GIF. If you want to generically support both animated and non-animated | |
/// files, you can always decode to an animation and if the animation has only | |
/// a single frame, then it's a non-animated image. | |
/// | |
/// In some cases, the frames of the animation may only provide a portion of the | |
/// canvas, such as the case of animations encoding only the changing pixels | |
/// from one frame to the next. The [width] and [height] and [backgroundColor] | |
/// properties of the [Animation] provide information about the canvas that | |
/// contains the animation, and the [Image] frames provide information about | |
/// how to draw the particular frame, such as the area of the canvas to draw | |
/// into, and if the canvas should be cleared prior to drawing the frame. | |
class Animation extends IterableBase<Image> { | |
/// The frames of this document are to be interpreted as animation. | |
static const int ANIMATION = 0; | |
/// The frames of this document are to be interpreted as pages of a document. | |
static const int PAGE = 1; | |
/// The canvas width for containing the animation. | |
int width; | |
/// The canvas height for containing the animation. | |
int height; | |
/// The suggested background color to clear the canvas with. | |
int backgroundColor = 0xffffffff; | |
/// The frames of the animation. | |
List<Image> frames = []; | |
/// How many times should the animation loop (0 means forever)? | |
int loopCount = 0; | |
/// How should the frames be interpreted? If [ANIMATION], the frames | |
/// are part of an animated sequence. If [PAGE], the frames are the pages | |
/// of a document. | |
int frameType = ANIMATION; | |
/// How many frames are in the animation? | |
int get numFrames => frames.length; | |
/// How many frames are in the animation? | |
int get length => frames.length; | |
/// Get the frame at the given [index]. | |
Image operator [](int index) => frames[index]; | |
/// Add a frame to the animation. | |
void addFrame(Image image) { | |
frames.add(image); | |
} | |
/// The first frame of the animation. | |
Image get first => frames.first; | |
/// The last frame of the animation. | |
Image get last => frames.last; | |
/// Is the animation empty (no frames)? | |
bool get isEmpty => frames.isEmpty; | |
/// Returns true if there is at least one frame in the animation. | |
bool get isNotEmpty => frames.isNotEmpty; | |
/// Get the iterator for looping over the animation. This allows the | |
/// Animation to be used in for-each loops: | |
/// for (AnimationFrame frame in animation) { ... } | |
Iterator<Image> get iterator => frames.iterator; | |
} |