This commit is contained in:
DDIsFriend
2023-08-18 17:28:57 +08:00
commit f0e8a1709d
4282 changed files with 192396 additions and 0 deletions

View File

@@ -0,0 +1,171 @@
//
// EKAttributes+Animation.swift
// SwiftEntryKit
//
// Created by Daniel Huri on 4/21/18.
// Copyright (c) 2018 huri000@gmail.com. All rights reserved.
//
import UIKit
// A protocol that describes an animation
protocol EKAnimation {
var delay: TimeInterval { get set }
var duration: TimeInterval { get set }
var spring: EKAttributes.Animation.Spring? { get set }
}
// A protocol that describes a range animation
protocol EKRangeAnimation: EKAnimation {
var start: CGFloat { get set }
var end: CGFloat { get set }
}
public extension EKAttributes {
/** Describes an animation that can be performed on the entry */
struct Animation: Equatable {
/** Describes properties for a spring animation that can be performed on the entry */
public struct Spring: Equatable {
/** The dampic of the spring animation */
public var damping: CGFloat
/** The initial velocity of the spring animation */
public var initialVelocity: CGFloat
/** Initializer */
public init(damping: CGFloat, initialVelocity: CGFloat) {
self.damping = damping
self.initialVelocity = initialVelocity
}
}
/** Describes an animation with range */
public struct RangeAnimation: EKRangeAnimation, Equatable {
/** The duration of the range animation */
public var duration: TimeInterval
/** The delay of the range animation */
public var delay: TimeInterval
/** The start value of the range animation (e.g. alpha, scale) */
public var start: CGFloat
/** The end value of the range animation (e.g. alpha, scale) */
public var end: CGFloat
/** The spring of the animation */
public var spring: Spring?
/** Initializer */
public init(from start: CGFloat, to end: CGFloat, duration: TimeInterval, delay: TimeInterval = 0, spring: Spring? = nil) {
self.start = start
self.end = end
self.delay = delay
self.duration = duration
self.spring = spring
}
}
/** Describes translation animation */
public struct Translate: EKAnimation, Equatable {
/** Describes the anchor position */
public enum AnchorPosition: Equatable {
/** Top position - the entry shows from top or exits towards the top */
case top
/** Bottom position - the entry shows from bottom or exits towards the bottom */
case bottom
/** Automatic position - the entry shows and exits according to EKAttributes.Position value. If the position of the entry is top, bottom, the entry's translation anchor is top, bottom - respectively.*/
case automatic
}
/** Animation duration */
public var duration: TimeInterval
/** Animation delay */
public var delay: TimeInterval
/** To where OR from the entry is animated */
public var anchorPosition: AnchorPosition
/** Optional translation spring */
public var spring: Spring?
/** Initializer */
public init(duration: TimeInterval, anchorPosition: AnchorPosition = .automatic, delay: TimeInterval = 0, spring: Spring? = nil) {
self.anchorPosition = anchorPosition
self.duration = duration
self.delay = delay
self.spring = spring
}
}
/** Translation animation prop */
public var translate: Translate?
/** Scale animation prop */
public var scale: RangeAnimation?
/** Fade animation prop */
public var fade: RangeAnimation?
/** Does the animation contains translation */
public var containsTranslation: Bool {
return translate != nil
}
/** Does the animation contains scale */
public var containsScale: Bool {
return scale != nil
}
/** Does the animation contains fade */
public var containsFade: Bool {
return fade != nil
}
/** Does the animation contains any animation whatsoever */
public var containsAnimation: Bool {
return containsTranslation || containsScale || containsFade
}
/** Returns the maximum delay amongst all animations */
public var maxDelay: TimeInterval {
return max(translate?.delay ?? 0, max(scale?.delay ?? 0, fade?.delay ?? 0))
}
/** Returns the maximum duration amongst all animations */
public var maxDuration: TimeInterval {
return max(translate?.duration ?? 0, max(scale?.duration ?? 0, fade?.duration ?? 0))
}
/** Returns the maximum (duration+delay) amongst all animations */
public var totalDuration: TimeInterval {
return maxDelay + maxDuration
}
/** Returns the maximum (duration+delay) amongst all animations */
public static var translation: Animation {
return Animation(translate: .init(duration: 0.3))
}
/** No animation at all */
public static var none: Animation {
return Animation()
}
/** Initializer */
public init(translate: Translate? = nil, scale: RangeAnimation? = nil, fade: RangeAnimation? = nil) {
self.translate = translate
self.scale = scale
self.fade = fade
}
}
}