mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 22:55:00 +00:00
Update lottie-ios
This commit is contained in:
@@ -0,0 +1,253 @@
|
||||
// Created by Cal Stephens on 1/24/22.
|
||||
// Copyright © 2022 Airbnb Inc. All rights reserved.
|
||||
|
||||
import CoreGraphics
|
||||
|
||||
// MARK: - Interpolatable
|
||||
|
||||
/// A type that can be interpolated between two values
|
||||
public protocol Interpolatable: AnyInterpolatable {
|
||||
/// Interpolates the `self` to the given number by `amount`.
|
||||
/// - Parameter to: The number to interpolate to.
|
||||
/// - Parameter amount: The amount to interpolate,
|
||||
/// relative to 0.0 (self) and 1.0 (to).
|
||||
/// `amount` can be greater than one and less than zero,
|
||||
/// and interpolation should not be clamped.
|
||||
///
|
||||
/// ```
|
||||
/// let number = 5
|
||||
/// let interpolated = number.interpolateTo(10, amount: 0.5)
|
||||
/// print(interpolated) // 7.5
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// let number = 5
|
||||
/// let interpolated = number.interpolateTo(10, amount: 1.5)
|
||||
/// print(interpolated) // 12.5
|
||||
/// ```
|
||||
func interpolate(to: Self, amount: CGFloat) -> Self
|
||||
}
|
||||
|
||||
// MARK: - SpatialInterpolatable
|
||||
|
||||
/// A type that can be interpolated between two values,
|
||||
/// additionally using optional `spatialOutTangent` and `spatialInTangent` values.
|
||||
/// - If your implementation doesn't use the `spatialOutTangent` and `spatialInTangent`
|
||||
/// parameters, prefer implementing the simpler `Interpolatable` protocol.
|
||||
public protocol SpatialInterpolatable: AnyInterpolatable {
|
||||
/// Interpolates the `self` to the given number by `amount`.
|
||||
/// - Parameter to: The number to interpolate to.
|
||||
/// - Parameter amount: The amount to interpolate,
|
||||
/// relative to 0.0 (self) and 1.0 (to).
|
||||
/// `amount` can be greater than one and less than zero,
|
||||
/// and interpolation should not be clamped.
|
||||
func interpolate(
|
||||
to: Self,
|
||||
amount: CGFloat,
|
||||
spatialOutTangent: CGPoint?,
|
||||
spatialInTangent: CGPoint?)
|
||||
-> Self
|
||||
}
|
||||
|
||||
// MARK: - AnyInterpolatable
|
||||
|
||||
/// The base protocol that is implemented by both `Interpolatable` and `SpatialInterpolatable`
|
||||
/// Types should not directly implement this protocol.
|
||||
public protocol AnyInterpolatable {
|
||||
/// Interpolates by calling either `Interpolatable.interpolate`
|
||||
/// or `SpatialInterpolatable.interpolate`.
|
||||
/// Should not be implemented or called by consumers.
|
||||
func _interpolate(
|
||||
to: Self,
|
||||
amount: CGFloat,
|
||||
spatialOutTangent: CGPoint?,
|
||||
spatialInTangent: CGPoint?)
|
||||
-> Self
|
||||
}
|
||||
|
||||
extension Interpolatable {
|
||||
public func _interpolate(
|
||||
to: Self,
|
||||
amount: CGFloat,
|
||||
spatialOutTangent _: CGPoint?,
|
||||
spatialInTangent _: CGPoint?)
|
||||
-> Self
|
||||
{
|
||||
interpolate(to: to, amount: amount)
|
||||
}
|
||||
}
|
||||
|
||||
extension SpatialInterpolatable {
|
||||
/// Helper that interpolates this `SpatialInterpolatable`
|
||||
/// with `nil` spatial in/out tangents
|
||||
public func interpolate(to: Self, amount: CGFloat) -> Self {
|
||||
interpolate(
|
||||
to: to,
|
||||
amount: amount,
|
||||
spatialOutTangent: nil,
|
||||
spatialInTangent: nil)
|
||||
}
|
||||
|
||||
public func _interpolate(
|
||||
to: Self,
|
||||
amount: CGFloat,
|
||||
spatialOutTangent: CGPoint?,
|
||||
spatialInTangent: CGPoint?)
|
||||
-> Self
|
||||
{
|
||||
interpolate(
|
||||
to: to,
|
||||
amount: amount,
|
||||
spatialOutTangent: spatialOutTangent,
|
||||
spatialInTangent: spatialInTangent)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Double + Interpolatable
|
||||
|
||||
extension Double: Interpolatable { }
|
||||
|
||||
// MARK: - CGFloat + Interpolatable
|
||||
|
||||
extension CGFloat: Interpolatable { }
|
||||
|
||||
// MARK: - Float + Interpolatable
|
||||
|
||||
extension Float: Interpolatable { }
|
||||
|
||||
extension Interpolatable where Self: BinaryFloatingPoint {
|
||||
public func interpolate(to: Self, amount: CGFloat) -> Self {
|
||||
self + ((to - self) * Self(amount))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - CGRect + Interpolatable
|
||||
|
||||
extension CGRect: Interpolatable {
|
||||
public func interpolate(to: CGRect, amount: CGFloat) -> CGRect {
|
||||
CGRect(
|
||||
x: origin.x.interpolate(to: to.origin.x, amount: amount),
|
||||
y: origin.y.interpolate(to: to.origin.y, amount: amount),
|
||||
width: width.interpolate(to: to.width, amount: amount),
|
||||
height: height.interpolate(to: to.height, amount: amount))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - CGSize + Interpolatable
|
||||
|
||||
extension CGSize: Interpolatable {
|
||||
public func interpolate(to: CGSize, amount: CGFloat) -> CGSize {
|
||||
CGSize(
|
||||
width: width.interpolate(to: to.width, amount: amount),
|
||||
height: height.interpolate(to: to.height, amount: amount))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - CGPoint + SpatialInterpolatable
|
||||
|
||||
extension CGPoint: SpatialInterpolatable {
|
||||
public func interpolate(
|
||||
to: CGPoint,
|
||||
amount: CGFloat,
|
||||
spatialOutTangent: CGPoint?,
|
||||
spatialInTangent: CGPoint?)
|
||||
-> CGPoint
|
||||
{
|
||||
guard
|
||||
let outTan = spatialOutTangent,
|
||||
let inTan = spatialInTangent
|
||||
else {
|
||||
return CGPoint(
|
||||
x: x.interpolate(to: to.x, amount: amount),
|
||||
y: y.interpolate(to: to.y, amount: amount))
|
||||
}
|
||||
|
||||
let cp1 = self + outTan
|
||||
let cp2 = to + inTan
|
||||
return interpolate(to, outTangent: cp1, inTangent: cp2, amount: amount)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Color + Interpolatable
|
||||
|
||||
extension Color: Interpolatable {
|
||||
public func interpolate(to: Color, amount: CGFloat) -> Color {
|
||||
Color(
|
||||
r: r.interpolate(to: to.r, amount: amount),
|
||||
g: g.interpolate(to: to.g, amount: amount),
|
||||
b: b.interpolate(to: to.b, amount: amount),
|
||||
a: a.interpolate(to: to.a, amount: amount))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Vector1D + Interpolatable
|
||||
|
||||
extension Vector1D: Interpolatable {
|
||||
public func interpolate(to: Vector1D, amount: CGFloat) -> Vector1D {
|
||||
value.interpolate(to: to.value, amount: amount).vectorValue
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Vector2D + SpatialInterpolatable
|
||||
|
||||
extension Vector2D: SpatialInterpolatable {
|
||||
public func interpolate(
|
||||
to: Vector2D,
|
||||
amount: CGFloat,
|
||||
spatialOutTangent: CGPoint?,
|
||||
spatialInTangent: CGPoint?)
|
||||
-> Vector2D
|
||||
{
|
||||
pointValue.interpolate(
|
||||
to: to.pointValue,
|
||||
amount: amount,
|
||||
spatialOutTangent: spatialOutTangent,
|
||||
spatialInTangent: spatialInTangent)
|
||||
.vector2dValue
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Vector3D + SpatialInterpolatable
|
||||
|
||||
extension Vector3D: SpatialInterpolatable {
|
||||
public func interpolate(
|
||||
to: Vector3D,
|
||||
amount: CGFloat,
|
||||
spatialOutTangent: CGPoint?,
|
||||
spatialInTangent: CGPoint?)
|
||||
-> Vector3D
|
||||
{
|
||||
if spatialInTangent != nil || spatialOutTangent != nil {
|
||||
// TODO Support third dimension spatial interpolation
|
||||
let point = pointValue.interpolate(
|
||||
to: to.pointValue,
|
||||
amount: amount,
|
||||
spatialOutTangent: spatialOutTangent,
|
||||
spatialInTangent: spatialInTangent)
|
||||
|
||||
return Vector3D(
|
||||
x: point.x,
|
||||
y: point.y,
|
||||
z: CGFloat(z.interpolate(to: to.z, amount: amount)))
|
||||
}
|
||||
|
||||
return Vector3D(
|
||||
x: x.interpolate(to: to.x, amount: amount),
|
||||
y: y.interpolate(to: to.y, amount: amount),
|
||||
z: z.interpolate(to: to.z, amount: amount))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Array + Interpolatable, AnyInterpolatable
|
||||
|
||||
extension Array: Interpolatable, AnyInterpolatable where Element: Interpolatable {
|
||||
public func interpolate(to: [Element], amount: CGFloat) -> [Element] {
|
||||
LottieLogger.shared.assert(
|
||||
count == to.count,
|
||||
"When interpolating Arrays, both array sound have the same element count.")
|
||||
|
||||
return zip(self, to).map { lhs, rhs in
|
||||
lhs.interpolate(to: rhs, amount: amount)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user