Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/cats-oss/sica
:deer: Simple Interface Core Animation. Run type-safe animation sequencially or parallelly
https://github.com/cats-oss/sica
animation carthage cocoapods ios macos swift swift-package-manager tvos
Last synced: about 10 hours ago
JSON representation
:deer: Simple Interface Core Animation. Run type-safe animation sequencially or parallelly
- Host: GitHub
- URL: https://github.com/cats-oss/sica
- Owner: cats-oss
- License: mit
- Created: 2018-06-25T07:55:06.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2021-11-30T21:46:54.000Z (about 3 years ago)
- Last Synced: 2024-12-22T17:10:56.819Z (about 10 hours ago)
- Topics: animation, carthage, cocoapods, ios, macos, swift, swift-package-manager, tvos
- Language: Swift
- Homepage:
- Size: 12.5 MB
- Stars: 1,056
- Watchers: 36
- Forks: 57
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Simple Interface Core Animation
Sica can execute various animations sequentially or parallelly.
## Features
- Animation with duration and delay
- parallel / sequence animation
- Easings
- Springs
- Transition## Requirements
- Xcode 9.3 or greater
- iOS 9 or greater
- tvOS 10.0 or greater
- macOS 10.11 or greater
- Swift 4.2 (since 0.3.4)## Installation
### Carthage
If youβre using [Carthage](https://github.com/Carthage/Carthage), simply add
Sica to your `Cartfile`:```ruby
github "cats-oss/Sica"
```### CocoaPods
Sica is available through [CocoaPods](https://cocoapods.org). To instal
it, simply add the following line to your Podfile:```ruby
pod 'Sica'
```### Swift Package Manager
Sica is available through `SwiftPM`, create ` Package.swift` and add `dependencies` value
```Package.swift
dependencies: [
.package(url: "https://github.com/cats-oss/Sica.git", from: "0.4.1")
]
```
See also: [GitHub - j-channings/swift-package-manager-ios: Example of how to use SPM v4 to manage iOS dependencies](https://github.com/j-channings/swift-package-manager-ios)## Usage
### Sample Animation
#### Sequence Animation
If you set `.sequence`, sequence animation is shown.
```swift
let animator = Animator(view: sampleView)
animator
.addBasicAnimation(keyPath: .positionX, from: 50, to: 150, duration: 2, timingFunction: .easeOutExpo)
.addSpringAnimation(keyPath: .boundsSize, from: sampleView.frame.size, to: CGSize(width: 240, height: 240), damping: 12, mass: 1, stiffness: 240, initialVelocity: 0, duration: 1)
.run(type: .sequence)
```
![SequenceAnimation](resources/sequenceAnimation.gif)#### Parallel Animation
If you set `.parallel`, parallel animation is shown.
```swift
let animator = Animator(view: sampleView)
animator
.addBasicAnimation(keyPath: .positionX, from: 50, to: 150, duration: 5, timingFunction: .easeOutExpo)
.addBasicAnimation(keyPath: .transformRotationZ, from: 0, to: CGFloat.pi, duration: 3, timingFunction: .easeOutExpo)
.run(type: .parallel)
```
![ParallelAnimation](resources/parallelAnimation.gif)#### Forever Animation
If you set `forever` before calling `run`, forever animation is shown.
```swift
let animator = Animator(view: sampleView)
animator
.addBasicAnimation(keyPath: .positionX, from: 50, to: 150, duration: 2, timingFunction: .easeOutExpo)
.addBasicAnimation(keyPath: .positionX, from: 150, to: 50, duration: 2, timingFunction: .easeOutExpo)
.forever(autoreverses: false)
.run(type: .sequence)
```
![Forever](resources/forever.gif)#### Cancel
If you want to cancel animation, you should call `cancel`.
```swift
let animator = Animator(view: sampleView)
/*
Add animation and run
*/
animator.cancel() // Animation cancel
```#### Remove Added Animations
If you call `run` and then you call add animation method, no animation will be added.
If you use animator again, you call `removeAll` before `addBasicAnimation` or `addSpringAnimation` or `addTransitionAnimation`.
```swift
let animator = Animator(view: sampleView)
/*
Add animation and run
*/// Bad
animator.addBasicAnimation() // π you can't add animation// Good
animator.removeAll()
.addBasicAnimation() // π You can add animation.
```## Functions
### Add Animation
```swift
public func addBasicAnimation(keyPath: Sica.AnimationKeyPath, from: T, to: T, duration: Double, delay: Double = default, timingFunction: Sica.TimingFunction = default) -> Self where T : AnimationValueType
public func addSpringAnimation(keyPath: Sica.AnimationKeyPath, from: T, to: T, damping: CGFloat, mass: CGFloat, stiffness: CGFloat, initialVelocity: CGFloat, duration: Double, delay: Double = default, timingFunction: Sica.TimingFunction = default) -> Self where T : AnimationValueType
public func addTransitionAnimation(startProgress: Float, endProgress: Float, type: Sica.Transition, subtype: Sica.TransitionSub, duration: Double, delay: Double = default, timingFunction: Sica.TimingFunction = default) -> Self
```### Add Animation Option
```swift
public func delay(_ delay: Double) -> Self
public func forever(autoreverses: Bool = default) -> Self
```### Animation Operation
```swift
public func run(type: Sica.Animator.AnimationPlayType, isRemovedOnCompletion: Bool = default, completion: (() -> Swift.Void)? = default)
public func cancel()
public func removeAll() -> Self
```## Extensions
You can access sica property in `UIView` and `CALayer`.
```swift
let view = UIView(frame: ...)
view.sica
.addBasicAnimation(keyPath: .positionX, from: 50, to: 150, duration: 2, timingFunction: .easeOutExpo)
.run(type: .sequence)
``````swift
let layer = CALayer()
layer.sica
.addBasicAnimation(keyPath: .positionX, from: 50, to: 150, duration: 2, timingFunction: .easeOutExpo)
.run(type: .sequence)
```## Support
### Animation
- CABasicAnimation
- CATransition
- CASpringAnimation### AnimationPlayType
you can choose animation play type
- run animation sequentially
- run animation parallelly### EasingFunctions
you can choose various timing functions![EasingFunctions](resources/EasingFunctions.gif)
### KeyPaths Table
|Sica|KeyPath|
|:-:|:-:|
|`.anchorPoint`|`anchorPoint`|
|`.backgroundColor`|`backgroundColor`|
|`.borderColor`|`borderColor`|
|`.borderWidth`|`borderWidth`|
|`.bounds`|`bounds`|
|`.contents`|`contents`|
|`.contentsRect`|`contentsRect`|
|`.cornerRadius`|`cornerRadius`|
|`.filters`|`filters`|
|`.frame`|`frame`|
|`.hidden`|`hidden`|
|`.mask`|`mask`|
|`.masksToBounds`|`masksToBounds`|
|`.opacity`|`opacity`|
|`.path`|`path`|
|`.position`|`position`|
|`.shadowColor`|`shadowColor`|
|`.shadowOffset`|`shadowOffset`|
|`.shadowOpacity`|`shadowOpacity`|
|`.shadowPath`|`shadowPath`|
|`.shadowRadius`|`shadowRadius`|
|`.sublayers`|`sublayers`|
|`.sublayerTransform`|`sublayerTransform`|
|`.transform`|`transform`|
|`.zPosition`|`zPosition`|#### Anchor Point
|Sica|KeyPath|
|:-:|:-:|
|`.anchorPointX`|`anchorPoint.x`|
|`.anchorPointy`|`anchorPoint.y`|#### Bounds
|Sica|KeyPath|
|:-:|:-:|
|`.boundsOrigin`|`bounds.origin`|
|`.boundsOriginX`|`bounds.origin.x`|
|`.boundsOriginY`|`bounds.origin.y`|
|`.boundsSize`|`bounds.size`|
|`.boundsSizeWidth`|`bounds.size.width`|
|`.boundsSizeHeight`|`bounds.size.height`|#### Contents
|Sica|KeyPath|
|:-:|:-:|
|`.contentsRectOrigin`|`contentsRect.origin`|
|`.contentsRectOriginX`|`contentsRect.origin.x`|
|`.contentsRectOriginY`|`contentsRect.origin.y`|
|`.contentsRectSize`|`contentsRect.size`|
|`.contentsRectSizeWidth`|`contentsRect.size.width`|
|`.contentsRectSizeHeight`|`contentsRect.size.height`|#### Frame
|Sica|KeyPath|
|:-:|:-:|
|`.frameOrigin`|`frame.origin`|
|`.frameOriginX`|`frame.origin.x`|
|`.frameOriginY`|`frame.origin.y`|
|`.frameSize`|`frame.size`|
|`.frameSizeWidth`|`frame.size.width`|
|`.frameSizeHeight`|`frame.size.height`|#### Position
|Sica|KeyPath|
|:-:|:-:|
|`.positionX`|`position.x`|
|`.positionY`|`position.y`|#### Shadow Offset
|Sica|KeyPath|
|:-:|:-:|
|`.shadowOffsetWidth`|`shadowOffset.width`|
|`.shadowOffsetHeight`|`shadowOffset.height`|#### Sublayer Transform
|Sica|KeyPath|
|:-:|:-:|
|`.sublayerTransformRotationX`|`sublayerTransform.rotation.x`|
|`.sublayerTransformRotationY`|`sublayerTransform.rotation.y`|
|`.sublayerTransformRotationZ`|`sublayerTransform.rotation.z`|
|`.sublayerTransformScaleX`|`sublayerTransform.scale.x`|
|`.sublayerTransformScaleY`|`sublayerTransform.scale.y`|
|`.sublayerTransformScaleZ`|`sublayerTransform.scale.z`|
|`.sublayerTransformTranslationX`|`sublayerTransform.translation.x`|
|`.sublayerTransformTranslationY`|`sublayerTransform.translation.y`|
|`.sublayerTransformTranslationZ`|`sublayerTransform.translation.z`|#### Transform
|Sica|KeyPath|
|:-:|:-:|
|`.transformRotationX`|`transform.rotation.x`|
|`.transformRotationY`|`transform.rotation.y`|
|`.transformRotationZ`|`transform.rotation.z`|
|`.transformScaleX`|`transform.scale.x`|
|`.transformScaleY`|`transform.scale.y`|
|`.transformScaleZ`|`transform.scale.z`|
|`.transformTranslationX`|`transform.translation.x`|
|`.transformTranslationY`|`transform.translation.y`|
|`.transformTranslationZ`|`transform.translation.z`|## License
Sica is available under the MIT license. See the [LICENSE file](https://github.com/cats-oss/Sica/blob/master/LICENSE) for more info.