Add a second index to track preload position

Using one index was causing the end of gifs to be cut off if the number
of frames wasn't a multiple of the preload size. This creates a second
index to track the preload position and the display frame position.
This commit is contained in:
Tony DiPasquale 2015-06-05 11:01:56 -04:00
parent 6a22c41aa1
commit b3da34a186
1 changed files with 8 additions and 5 deletions

View File

@ -20,6 +20,8 @@ class Animator {
private var imageSource: CGImageSourceRef
/// The index of the current GIF frame.
private var currentFrameIndex = 0
/// The index of the current GIF frame from the source.
private var currentPreloadIndex = 0
/// Time elapsed since the last frame change. Used to determine when the frame should be updated.
private var timeSinceLastFrameChange: NSTimeInterval = 0.0
@ -52,6 +54,7 @@ class Animator {
let framesToProcess = min(numberOfFrames, maxNumberOfFrames)
animatedFrames.reserveCapacity(framesToProcess)
animatedFrames = reduce(0..<framesToProcess, []) { $0 + pure(prepareFrame($1)) }
currentPreloadIndex = framesToProcess
}
/// Loads a single frame from an image source, resizes it, then returns an `AnimatedFrame`.
@ -79,7 +82,7 @@ class Animator {
/// :param: index The index of the frame.
/// :returns: An optional image at a given frame.
private func frameAtIndex(index: Int) -> UIImage? {
return animatedFrames[index % animatedFrames.count].image
return animatedFrames[index].image
}
/// Updates the current frame if necessary using the frame timer and the duration of each frame in `animatedFrames`.
@ -87,17 +90,17 @@ class Animator {
/// :returns: An optional image at a given frame.
func updateCurrentFrame(duration: CFTimeInterval) -> Bool {
timeSinceLastFrameChange += min(maxTimeStep, duration)
var frameDuration = animatedFrames[currentFrameIndex % animatedFrames.count].duration
var frameDuration = animatedFrames[currentFrameIndex].duration
if timeSinceLastFrameChange >= frameDuration {
timeSinceLastFrameChange -= frameDuration
let lastFrameIndex = currentFrameIndex
currentFrameIndex = ++currentFrameIndex % numberOfFrames
currentFrameIndex = ++currentFrameIndex % animatedFrames.count
// Loads the next needed frame for progressive loading
if animatedFrames.count < numberOfFrames {
let nextFrameToLoad = (lastFrameIndex + animatedFrames.count) % numberOfFrames
animatedFrames[lastFrameIndex % animatedFrames.count] = prepareFrame(nextFrameToLoad)
animatedFrames[lastFrameIndex] = prepareFrame(currentPreloadIndex)
currentPreloadIndex = ++currentPreloadIndex % numberOfFrames
}
return true
}