Last active
July 8, 2017 14:22
-
-
Save allanweir/badefea836590cfe61edae915b6e40bf to your computer and use it in GitHub Desktop.
Lottie subclass for partial and reverse playback on iOS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// STAnimationView.swift | |
// Allan Weir | |
// | |
// Created by Allan Weir on 06/02/2017. | |
// Copyright © 2017 Allan Weir. All rights reserved. | |
// http://www.studiousdesigns.com | |
// | |
import UIKit | |
import Lottie | |
class STAnimationView: LOTAnimationView { | |
private var displayLink: CADisplayLink? | |
private var lastUpdateTime: CGFloat = 0 | |
private var endTime: CGFloat = 1 | |
private var lastTimeStamp: Date = Date() | |
private(set) var isPlayingReverse: Bool = false | |
class func animation(named animationName: String) -> STAnimationView { | |
let urlPath = Bundle.main.path(forResource: animationName, ofType: "json")! | |
return STAnimationView(contentsOf: URL(fileURLWithPath: urlPath)) | |
} | |
func play(fromPosition: CGFloat, toPosition: CGFloat) { | |
if let oldLink = self.displayLink { | |
oldLink.invalidate() | |
} | |
self.displayLink = CADisplayLink(target: self, selector: #selector(STAnimationView.updateDisplayLink(link:))) | |
self.displayLink?.add(to: RunLoop.main, forMode: .defaultRunLoopMode) | |
self.isPlayingReverse = (toPosition < fromPosition) | |
self.lastUpdateTime = fromPosition | |
self.endTime = toPosition | |
self.animationProgress = fromPosition | |
self.lastTimeStamp = Date() | |
} | |
internal func updateDisplayLink(link: CADisplayLink) { | |
let newTime = Date() | |
let timePassed = newTime.timeIntervalSince(self.lastTimeStamp) | |
let deltaProgress = CGFloat(timePassed) * (self.animationSpeed / self.animationDuration) | |
var newProgress = !self.isPlayingReverse ? self.animationProgress + deltaProgress : self.animationProgress - deltaProgress | |
if !self.isPlayingReverse { | |
if newProgress >= self.endTime { | |
newProgress = self.endTime | |
self.displayLink?.invalidate() | |
self.displayLink = nil | |
} | |
} else { | |
if newProgress <= self.endTime { | |
newProgress = self.endTime | |
self.displayLink?.invalidate() | |
self.displayLink = nil | |
} | |
} | |
self.animationProgress = newProgress | |
self.lastTimeStamp = newTime | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment