Home telegram - listViewAnimation
Post
Cancel

telegram - listViewAnimation

ListViewAnimation

protocol Interpolatable

1
static func interpolator() -> (Interpolatable, Interpolatable, CGFloat) -> (Interpolatable)

class ListViewAnimation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let from: Interpolatable
let to: Interpolatable
let duration: Double
let startTime: Double
private let curve: (CGFloat) -> CGFloat
private let interpolator: (Interpolatable, Interpolatable, CGFloat) -> Interpolatable
private let update: (CGFloat, Interpolatable) -> Void
private let completed: (Bool) -> Void

public init<T: Interpolatable>(from: T, to: T, duration: Double, curve: @escaping (CGFloat) -> CGFloat, beginAt: Double, update: @escaping (CGFloat, T) -> Void, completed: @escaping (Bool) -> Void = { _ in }) {
    self.from = from
    self.to = to
    self.duration = duration
    self.curve = curve
    self.startTime = beginAt
    self.interpolator = T.interpolator()
    self.update = { progress, value in
        update(progress, value as! T)
    }
    self.completed = completed
}

completeAt

1
2
3
4
5
6
7
8
public func completeAt(_ timestamp: Double) -> Bool {
    if timestamp >= self.startTime + self.duration {
        self.completed(true)
        return true
    } else {
        return false
    }
}

valueAt

1
2
3
4
5
6
7
8
9
private func valueAt(_ t: CGFloat) -> Interpolatable {
    if t <= 0.0 {
        return self.from
    } else if t >= 1.0 {
        return self.to
    } else {
        return self.interpolator(self.from, self.to, t)
    }
}

applyAt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public func applyAt(_ timestamp: Double) {
    var t = CGFloat((timestamp - self.startTime) / self.duration)
    let ct: CGFloat
    if t <= 0.0 + CGFloat.ulpOfOne {
        t = 0.0
        ct = 0.0
    } else if t >= 1.0 - CGFloat.ulpOfOne {
        t = 1.0
        ct = 1.0
    } else {
        ct = self.curve(t)
    }
    self.update(ct, self.valueAt(ct))
}
This post is licensed under CC BY 4.0 by the author.