Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // CAAnimationHelpers.swift
- // ChainingAnimations
- //
- // Created by Patrik Sjöberg on 2018-11-13.
- // Copyright © 2018 Patrik Sjöberg. All rights reserved.
- //
- import Foundation
- import UIKit
- /**
- Create a keyframe animation for `keyPath` with values supplied in `values`.
- Timings will be calculated from the `track` string that is built of space and numbers,
- where the numbers must correspond to an index in the `values` list.
- Example: `animation(track: "0 1 1", keyPath: "opacity", values: [0.4, 0.8])` will
- result in one keypoint where opaciry is 0.4 at time 0, 0.8 at time 0.5 and 0.8 at time 1,
- creating a blink effect where opacity is higher for a longer time than it's lower.
- */
- func animation<T>(track: String, for keyPath: String, values: [T]) -> CAAnimation {
- let valuesAndTimes = valuesAndTimesFrom(track: track, values: values)
- return animation(keyPath: keyPath, valuesAndTimes: valuesAndTimes)
- }
- /**
- Play animations in a sequence
- Creates a group with supplied animations and durations
- Duration is set for each animation and then the total of all the animations is set to the group
- */
- public func sequential(animationsAndDurations: [(CAAnimation, TimeInterval)]) -> CAAnimation {
- let group = CAAnimationGroup()
- var totalDuration: TimeInterval = 0
- for (anim, duration) in animationsAndDurations {
- anim.beginTime = totalDuration
- anim.duration = duration
- totalDuration += duration
- }
- group.duration = totalDuration
- group.animations = animationsAndDurations.map({$0.0})
- return group
- }
- /**
- Play animations concurrently
- Creates a group of animations
- */
- func concurrent(animations: [CAAnimation]) -> CAAnimation {
- let group = CAAnimationGroup()
- group.animations = animations
- return group
- }
- fileprivate func animation<T>(keyPath: String, valuesAndTimes: [(T, TimeInterval)]) -> CAAnimation {
- let anim = CAKeyframeAnimation(keyPath: keyPath)
- anim.values = valuesAndTimes.map{$0.0}
- anim.keyTimes = valuesAndTimes.map{$0.1}.map({NSNumber(value: $0)})
- anim.calculationMode = .cubic
- return anim
- }
- fileprivate func valuesAndTimesFrom<T>(track: String, values: [T]) -> [(T, TimeInterval)] {
- let length = track.count - 1
- return track.enumerated().compactMap { indexAndChar -> (T, TimeInterval)? in
- let (index, char) = indexAndChar
- if let valueIndex = Int(String(char)) {
- let value = values[valueIndex]
- let time = TimeInterval(index) / TimeInterval(length)
- return (value, time)
- }
- return nil
- }
- }
Add Comment
Please, Sign In to add comment