Designed for gesture-driven animations. Fast, simple, & extensible!

Overview

Yet Another Animation Library

Designed for gesture-driven animations. Fast, simple, & extensible!

It is written in pure swift 3.1 with protocol oriented design and extensive use of generics.

Consider this as a swift optimized version of facebook's pop. It plays nicer with swift and faster too.

Fast:

  • Uses SIMD types and instructions for calculation
  • Better compiler optimization through swift generics

Simple:

  • Supports Curve(Basic), Spring, & Decay animations out of the box
  • Easy API for animating common animatable properties. (checkout the Extensions folder for list of included properties)
  • Type safety guaranteed when assigning animation values
  • Observable, including value, velocity, and target value
  • Builtin chaining operator to easily react to changes in value
  • Provide velocity interpolation with gestures

Extensible:

  • Supports custom property
  • Supports custom animatable type
  • Supports custom animation

Installation

pod "YetAnotherAnimationLibrary"

Usage

Animation

// Spring animation
view.yaal.center.animateTo(CGPoint(x:50, y:100))
view.yaal.alpha.animateTo(0.5, stiffness: 300, damping: 20)

// Curve(Basic) animation
view.yaal.frame.animateTo(CGRect(x:0, y:0, width:50, height:50), duration:0.5, curve: .linear)

// Decay Animation
view.yaal.center.decay(initialVelocity:CGPoint(x:100, y:0))

Observe Changes

// observe value changes
view.yaal.center.value.changes.addListener { oldVelocity, newVelocity in
  print(oldVelocity, newVelocity)
}
// observe velocity changes
view.yaal.center.velocity.changes.addListener { oldVelocity, newVelocity in
  print(oldVelocity, newVelocity)
}

Chaining Reactions

// when scale changes, also change its alpha
// for example if view's scale animates from 1 to 0.5. its alpha will animate to 0.5 as well
view.yaal.scale.value => view.yaal.alpha
// equvalent to the following
// view.yaal.scale.value.changes.addListener { _, newScale in
//   view.yaal.alpha.animateTo(newScale)
// }

// optionally you can provide a mapping function in between.
// For example, the following code makes the view more transparent the faster it is moving
view.yaal.center.velocity => { 1 - $0.magnitude / 1000 } => view.yaal.alpha
// equvalent to the following
// view.yaal.center.velocity.changes.addListener { _, newVelocity in
//   view.yaal.alpha.animateTo(1 - newVelocity.magnitude / 1000)
// }

Set Value (Notify listeners)

// this sets the value directly (not animate to). Change listeners are called.
// Velocity listeners will receive a series of smoothed velocity values.
view.yaal.center.setTo(gestureRecognizer.location(in:nil))

Advance Usages

React to changes

Animate is very efficient at observing animated value and react accordingly. Some awesome effects can be achieved through observed values.

For example, here is a simple 2d rotation animation thats made possible through observing the center value's velocity.

   override func viewDidLoad() {
     // ...
     view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tap(gr:))))
     squareView.yaal.center.velocity => { $0.x / 1000 } => squareView.yaal.rotation
   }
   func tap(gr: UITapGestureRecognizer) {
       squareView.yaal.center.animateTo(gr.location(in: view))
   }


Animate also provide smooth velocity interpolation when calling setTo(_:). This is especially useful when dealing with user gesture.

For example. the following does a 3d rotate animation when dragged

override func viewDidLoad() {
    // ...
    squareView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(pan(gr:))))
    squareView.yaal.perspective.setTo(-1.0 / 500.0)
    squareView.yaal.center.velocity => { $0.x / 1000 } => squareView.yaal.rotationY
    squareView.yaal.center.velocity => { -$0.y / 1000 } => squareView.yaal.rotationX
}

func pan(gr: UIPanGestureRecognizer) {
    squareView.yaal.center.setTo(gr.location(in: view))
}

Custom property

To animate custom property, just create an animation object by calling SpringAnimation(getter:setter:). Use the animation object to animate and set the values. There are 4 types of animations provided by Animate:

  • SpringAnimation
  • CurveAnimation
  • DecayAnimation
  • MixAnimation (does all three types of animation)
class Foo {
    var volumn: Float = 0.0
    lazy var volumnAnimation: SpringAnimation<Float>
        = SpringAnimation(getter: { [weak self] in self?.volumn },
                          setter: { [weak self] in self?.volumn = $0 })
}

volumnAnimation.animateTo(0.5)

If your class inherits from NSObject, then it is even easier by using the built in animation store.

via extension & yaal.animationFor

extension Foo {
    public var volumnAnimation: MixAnimation<CGRect> {
        return yaal.animationFor(key: "volumn",
                                 getter: { [weak self] in self?.volumn },
                                 setter: { [weak self] in self?.volumn = $0 })
    }
}

via yaal.register & yaal.animationFor

// or register ahead of time
yaal.register(key: "volumn", 
              getter: { [weak self] in self?.volumn },
              setter: { [weak self] in self?.volumn = $0 })

// and retrieve the animation object through the same key.
yaal.animationFor(key: "volumn")!.animateTo(0.5)

// NOTE: that this method have limited type safety. You can basically pass any animatable type into `animateTo()`
// There is nothing to stop you from doing the following. but they will crash at run time
yaal.animationFor(key: "volumn")!.animateTo(CGSize.zero)
yaal.animationFor(key: "volumn")!.animateTo(CGRect.zero)

Custom Animatable Type

Custom animatable types are also supported. Just make the type conform to VectorConvertable.

// the following makes IndexPath animatable
extension IndexPath: VectorConvertible {
    public typealias Vector = Vector2
    public init(vector: Vector) {
        self.init(item: Int(vector.x), section: Int(vector.y))
    }
    public var vector: Vector {
        return [Double(item), Double(section)]
    }
}
// Can now be used like this
let indexAnimation = SpringAnimation(getter: { self.indexPath },
                                     setter: { self.indexPath = $0 })
indexAnimation.animateTo(IndexPath(item:0, section:0))

// Note that everything is type safe. incorrect type won't be allowed to compile

Custom Animation

Just subclass Animation and override update(dt:TimeInterval) method. If your animation need getter & setter support, subclass ValueAnimation instead. Checkout the builtin animations for example.

You might also like...
SwiftUI directed Server Driven UI

Server Driven UI (SDUI) Intentions Make a Server Driven UI module for SwiftUI applications that has a direct use. That way the application maintainer

Pure SwiftUI state-driven library to present view sequences and hierarchies.
Pure SwiftUI state-driven library to present view sequences and hierarchies.

PathPresenter swiftUIOnboarding.mp4 Pure SwiftUI routing with transitions, animations, and .sheet() support. In SwiftUI, View is a function of the sta

Advanced Natural Motion Animations, Simple Blocks Based Syntax
Advanced Natural Motion Animations, Simple Blocks Based Syntax

FlightAnimator Moved to Swift 3.1 Support: For Swift 3.1 - Use tag Version 0.9.9 See Installation Instructions for clarification Introduction FlightAn

DaisyChain is a micro framework which makes UIView animations chaining dead simple.

DaisyChain DaisyChain is a micro framework which makes UIView animations chaining dead simple. It uses the exact same interface you are familiars with

Simple UIButton subclass with additional state change animations (e.g. backgroundColor) and missing features
Simple UIButton subclass with additional state change animations (e.g. backgroundColor) and missing features

SimpleButton UIButton subclass with animated, state-aware attributes. Easy to subclass and configure! Full API docs Usage Just create your own SimpleB

A concept to more easily define simple keyframe / multi-step animations in SwiftUI

🎞 Animate A concept to more easily define simple keyframe / multi-step animations in SwiftUI, without: Defining an @State value for each property to

A Fast Animation Engine with an Intuitive API
A Fast Animation Engine with an Intuitive API

Kinieta An Animation Engine for iOS with an Intuitive API and Readable Code! (Written in Swift 4.0.) Why another? I decided to build an Animation Engi

YapAnimator is your fast and friendly physics-based animation system
YapAnimator is your fast and friendly physics-based animation system

YapAnimator is your fast and friendly physics-based animation system. YapAnimator was built with ease-of-use in mind, keeping you sane and your design

Physics-based animations for iOS, tvOS, and macOS.

Advance An animation library for iOS, tvOS, and macOS that uses physics-based animations (including springs) to power interactions that move and respo

Comments
  • Xcode10.2 build error

    Xcode10.2 build error

    extension double2: VectorType, VectorConvertible, SIMDVectorType {
        public static var zero = double2()
        public static var rawValueCount: Int { return 2 }
        public func distance(between: double2) -> Double {
            return simd.distance(self, between)
        }
    }
    
    extension double3: VectorType, VectorConvertible, SIMDVectorType {
        public static var zero = double3()
        public static var rawValueCount: Int { return 3 }
        public func distance(between: double3) -> Double {
            return simd.distance(self, between)
        }
    }
    
    extension double4: VectorType, VectorConvertible, SIMDVectorType {
        public static var zero = double4()
        public static var rawValueCount: Int { return 4 }
        public func distance(between: double4) -> Double {
            return simd.distance(self, between)
        }
    }
    

    Type 'SIMD2' does not conform to protocol 'SIMDVectorType' Type 'SIMD2' does not conform to protocol 'VectorType'

    opened by lixiang1994 5
  • Namespace properties inside .yaal

    Namespace properties inside .yaal

    Use same technic as RxSwift

    Introduce new protocol and generic struct to namespace all Yaal properties inside .yaal, instead of yaal_ prefix

    What do you think about this?

    opened by asiliuk 1
  • Type 'SIMD2<Scalar>' does not conform to protocol 'SIMDVectorType' and 'VectorType'

    Type 'SIMD2' does not conform to protocol 'SIMDVectorType' and 'VectorType'

    I'm getting an issue in Vector.swift where double2, double3, and double4 are raising problems with SIMDVectorType and VectorType. The entire program does not compile, and the errors are raised within the pod itself.

    These errors are being raised in every one of the extensions: double2, double3, and double4. Two errors per. Here's one of the error messages:

    [...]/Pods/YetAnotherAnimationLibrary/Sources/Types & Operators/Vector.swift:87:1: Type 'SIMD2<Scalar>' does not conform to protocol 'VectorType'

    It's also displaying this information underneath the error message:

    [...]/Pods/YetAnotherAnimationLibrary/Sources/Types & Operators/Vector.swift:46:17: Multiple matching functions named '/' with type '(SIMD2<Scalar>, Double) -> SIMD2<Scalar>'

    Any idea how I can fix this?

    opened by adrwz 0
  • Recreating Footprint App Placeholder animation

    Recreating Footprint App Placeholder animation

    Hi I just want to know how to create this animation? by tapping on placeholder, it bounce delightedly. it consist of scale and a little perspective animation.

    untitled

    FootPrint app on the App Store

    opened by haashem 0
Releases(1.6.0)
Owner
Luke Zhao
Luke Zhao
A Swift library to take the power of UIView.animateWithDuration(_:, animations:...) to a whole new level - layers, springs, chain-able animations and mixing view and layer animations together!

ver 2.0 NB! Breaking changes in 2.0 - due to a lot of requests EasyAnimation does NOT automatically install itself when imported. You need to enable i

Marin Todorov 3k Dec 27, 2022
Ease is an event driven animation system that combines the observer pattern with custom spring animations as observers

Ease is an event driven animation system that combines the observer pattern with custom spring animations as observers. It's magic. Features Animate a

Robert-Hein Hooijmans 1.3k Nov 17, 2022
A collection of animations for iOS. Simple, just add water animations.

DCAnimationKit A collection of animations for iOS Simply, just add water! DCAnimationKit is a category on UIView to make animations easy to perform. E

Dalton 797 Sep 23, 2022
Simple, extensible interpolation framework

THIS PROJECT IS NO LONGER MAINTAINED. Popsicle is a Swift framework for creating and managing interpolations of different value types with built-in UI

David Roman 1.1k Nov 17, 2022
(Animate CSS) animations for iOS. An easy to use library of iOS animations. As easy to use as an easy thing.

wobbly See Wobbly in action (examples) Add a drop of honey ?? to your project wobbly has a bunch of cool, fun, and easy to use iOS animations for you

Sagaya Abdulhafeez 150 Dec 23, 2021
(Animate CSS) animations for iOS. An easy to use library of iOS animations. As easy to use as an easy thing.

wobbly See Wobbly in action (examples) Add a drop of honey ?? to your project wobbly has a bunch of cool, fun, and easy to use iOS animations for you

Sagaya Abdulhafeez 150 Dec 23, 2021
An extensible iOS and OS X animation library, useful for physics-based interactions.

Pop is an extensible animation engine for iOS, tvOS, and OS X. In addition to basic static animations, it supports spring and decay dynamic animations

Meta Archive 19.8k Dec 28, 2022
Awesome IOS Styling with SwiftUI, Animation, Effects, Gesture ⭐️

Awesome SwiftUI Styling with SwiftUI ⭐️ This repository is dedicated to IOS styling using SwiftUI. (often using Other Libraries.) I started collecting

SeungYeub Baek 1 Apr 5, 2022
You can dismiss modal by using gesture

RPModalGestureTransition You can dismiss modal by using gesture. Usage 1.Define animation You define animator class inherits UIViewControllerAnimatedT

Naoya Sugimoto 90 Apr 21, 2020