Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/timdonnelly/advance
Physics-based animations for iOS, tvOS, and macOS.
https://github.com/timdonnelly/advance
animation gestures interaction ios motion physics springs swift ui
Last synced: 3 days ago
JSON representation
Physics-based animations for iOS, tvOS, and macOS.
- Host: GitHub
- URL: https://github.com/timdonnelly/advance
- Owner: timdonnelly
- License: bsd-2-clause
- Created: 2016-02-12T22:20:07.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2022-05-16T17:49:30.000Z (over 2 years ago)
- Last Synced: 2024-12-19T14:05:02.440Z (3 days ago)
- Topics: animation, gestures, interaction, ios, motion, physics, springs, swift, ui
- Language: Swift
- Homepage: http://timdonnelly.github.io/Advance/
- Size: 7.43 MB
- Stars: 4,503
- Watchers: 96
- Forks: 207
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[![Build Status](https://travis-ci.org/timdonnelly/Advance.svg?branch=master)](https://travis-ci.org/timdonnelly/Advance)
![Swift 5.0](https://img.shields.io/badge/Swift-5.0-orange.svg)
![GitHub release](https://img.shields.io/github/release/timdonnelly/Advance.svg)
[![SwiftPM compatible](https://img.shields.io/badge/SwiftPM-compatible-orange.svg)](#swift-package-manager)
[![CocoaPods compatible](https://img.shields.io/cocoapods/v/Advance.svg)](#cocoapods)# Advance
An animation library for iOS, tvOS, and macOS that uses physics-based animations (including springs) to power interactions that move and respond realistically.
```swift
let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))// Springs animate changes to a value
let spring = Spring(initialValue: view.center)// The `onChange` closure will be called every time the spring updates
spring.onChange = { [view] newCenter in
view.center = newCenter
}/// The view's center will realistically animate to the new target value.
spring.target = CGPoint(x: 300, y: 200)
```## Installation
There are several ways to integrate Advance into your project.
* **Manually:** add `Advance.xcodeproj` to your project, then add `Advance-{iOS|macOS|tvOS}.framework` as an "Embedded Binary" to your application target (under General in target settings). From there, add `import Advance` to your code and you're good to go.
* **Carthage:** add `github "timdonnelly/Advance"` to your `Cartfile`.
* **CocoaPods:** add `pod 'Advance'` to your `Podfile`.
* **Swift Package Manager:** add a dependency to your `Project.swift`: `.package(url: "http://github.com/timdonnelly/Advance", from: "3.0.0")`
##### Requirements
* iOS 10+, tvOS 10+, or macOS 10.12+
* Swift 5.0 (Xcode 10.2 or higher)## Usage
**API documentation is [available here](http://timdonnelly.github.io/Advance/).**
Advance animations are applied on every frame (using `CADisplayLink` on iOS/tvOS, and `CVDisplayLink` on macOS), allowing for fine-grained control at any time.
### `Spring`
`Spring` instances animate changes to a value over time, using spring physics.
```swift
let spring = Spring(initialValue: 0.0)
spring.onChange = { [view] newAlpha in
view.alpha = newAlpha
}// Off it goes!
spring.target = 0.5
```#### Configuring a spring
```swift
/// Spring values can be adjusted at any time.
spring.tension = 30.0 /// The strength of the spring
spring.damping = 2.0 /// The resistance (drag) that the spring encounters
spring.threshold = 0.1 /// The maximum delta between the current value and the spring's target (for each component) for which the simulation can enter a converged state./// Update the simulation state at any time.
spring.velocity = 6.5
spring.value = 0.2/// Sets the spring's target and the current simulation value, and removes all velocity. This causes the spring to converge at the given value.
spring.reset(to: 0.5)```
### `Animator`
`Animator` allows for more flexibility in the types of animation that can be performed, but gives up some convenience
in order to do so. Specifically, animators allow for *any* type of animation or simulation to be performed for a single
value.```swift
let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))/// Animators coordinate animations to drive changes to a value.
let sizeAnimator = Animator(initialValue: view.bounds.size)sizeAnimator.onChange = { [view] newSize in
view.bounds.size = newSize
}/// A simple timed animation
sizeAnimator.animate(to: CGSize(width: 123, height: 456), duration: 0.25, timingFunction: .easeInOut)/// Some time in the future (before the previous timed animation was complete)...
/// Spring physics will move the view's size to the new value, maintaining the velocity from the timed animation.
sizeAnimator.simulate(using: SpringFunction(target: CGSize(width: 300, height: 300)))/// Some time in the future (before the previous spring animation was complete)...
/// The value will keep the same velocity that it had from the preceeding spring
/// animation, and a decay function will slowly bring movement to a stop.
sizeAnimator.simulate(using: DecayFunction(drag: 2.0))```
Animators support two fundamentally different types of animations: timed and simulated.
#### Timed animations
Timed animations are, well, timed: they have a fixed duration, and they animate to a final value in a predictable manner.
```swift
animator.animate(to: CGSize(width: 123, height: 456), duration: 0.25, timingFunction: .easeInOut)
````TimingFunction` described the pacing of a timed animation.
`TimingFunction` comes with a standard set of functions:
```swift
TimingFunction.linear // No easing
TimingFunction.easeIn
TimingFunction.easeOut
TimingFunction.easeInOut
TimingFunction.swiftOut // Similar to Material Design's default curve
```Custom timing functions can be expressed as unit beziers ([described here](https://www.w3.org/TR/css-easing-1/#cubic-bzier-timing-function)).
```swift
let customTimingFunction = TimingFunction(x1: 0.1, y1: 0.2, x2: 0.6, y2: 0.0)
```#### Simulated animations
Simulated animations use a *simulation function* to power a physics-based transition. Simulation functions are types conforming to the `SimulationFunction` protocol.
Simulated animations may be started using two different methods:
```swift
// Begins animating with the custom simulation function, maintaining the previous velocity of the animator.
animator.simulate(using: MyCustomFunction())// or...
// Begins animating with the custom simulation function, imparting the specified velocity into the simulation.
animator.simulate(using: DecayFunction(), initialVelocity: dragGestureRecognizer.velocity(in: view))
```### Animating Custom Types
Values conforming to the `VectorConvertible` protocol can be animated by Advance. Conforming types can be converted to and from a `Vector` implementation.
```swift
public protocol VectorConvertible: Equatable, Interpolatable {
associatedtype VectorType: SIMD where VectorType.Scalar == Double
init(vector: VectorType)
var vector: VectorType { get }
}
```The library adds conformance for many common types through extensions.
## Contributing
If you encounter any issues or surprises, please open an issue.
For suggestions or new features, please consider opening a PR with a functional implementation. Issues may be used if you aren't sure how to implement the change, but working code is typically easier to evaluate.
## License
This project is released under the [BSD 2-clause license](https://github.com/timdonnelly/Advance/blob/master/LICENSE).