All Projects → alexrvarela → SwiftTweener

alexrvarela / SwiftTweener

Licence: MIT license
A pure Swift animation engine.

Programming Languages

swift
15916 projects
objective c
16641 projects - #2 most used programming language

Projects that are alternatives of or similar to SwiftTweener

Tween.js
JavaScript/TypeScript animation engine
Stars: ✭ 8,409 (+11263.51%)
Mutual labels:  easing-functions, tween, easing, easing-equations
Kute.js
KUTE.js is a JavaScript animation engine for modern browsers.
Stars: ✭ 2,270 (+2967.57%)
Mutual labels:  easing-functions, tween, animation-engine
kinieta
A Fast Animation Engine with an Intuitive API
Stars: ✭ 44 (-40.54%)
Mutual labels:  tween, tweening, animation-engine
interpolations
Lightweight Unity library for smoothing movements and value progressions in code (dragging, easing, tweening).
Stars: ✭ 29 (-60.81%)
Mutual labels:  easing-functions, tweening
FluentTransitions
▶ Smooth UI animations & transitions for .NET
Stars: ✭ 27 (-63.51%)
Mutual labels:  tweening, transitions
bevy easings
Helpers and Plugins for Bevy
Stars: ✭ 83 (+12.16%)
Mutual labels:  tweening, easing
Just Animate
Making Animation Simple
Stars: ✭ 242 (+227.03%)
Mutual labels:  timeline, transitions
Stepperview
SwiftUI iOS component for Step Indications.
Stars: ✭ 281 (+279.73%)
Mutual labels:  timeline, swift-package-manager
PhaserCHOP-TD-Summit-Talk
Project files associated with http://github.com/dbraun/PhaserCHOP and David Braun's "Quantitative Easing" talk at the 2019 TouchDesigner Summit https://www.youtube.com/watch?v=S4PQW4f34c8
Stars: ✭ 36 (-51.35%)
Mutual labels:  easing-functions, easing
ux-animate
A simple but powerful tweening, spring physics, animation library for Rust
Stars: ✭ 19 (-74.32%)
Mutual labels:  tween, tweening
MintAnimation
一款高效易用的Unity插值动画系统,可以快速制作UI动画
Stars: ✭ 84 (+13.51%)
Mutual labels:  tween, tweener
duck-tween
A tween library for unity
Stars: ✭ 23 (-68.92%)
Mutual labels:  tween, tweening
PhaserCHOP
A TouchDesigner channel operator for phase-staggered animations
Stars: ✭ 15 (-79.73%)
Mutual labels:  easing-functions, easing
Kvkcalendar
A most fully customization calendar and timeline library for iOS 📅
Stars: ✭ 160 (+116.22%)
Mutual labels:  timeline, swift-package-manager
Kinetic
A flexible tweening library for iOS in Swift similar to GSAP's TweenMax.
Stars: ✭ 54 (-27.03%)
Mutual labels:  tween, timeline
Wilderness
An SVG animation API
Stars: ✭ 127 (+71.62%)
Mutual labels:  tween, timeline
Androidviewanimations
Cute view animation collection.
Stars: ✭ 12,008 (+16127.03%)
Mutual labels:  easing-functions
ezing
Easing functions for Rust
Stars: ✭ 47 (-36.49%)
Mutual labels:  easing-functions
ue4-uitween
Unreal 4 UMG UI tweening plugin in C++
Stars: ✭ 178 (+140.54%)
Mutual labels:  tween
Pillar Valley
👾A cross-platform video game built with Expo, three.js, and Firebase! 🎮🕹
Stars: ✭ 242 (+227.03%)
Mutual labels:  tween

Swift Tweener

Swift animation engine, make more powerful and creative Apps.

Logo

This project has rewritten in pure Swift from CocoaTweener

Prerequisites

  • Swift 5.0

Features

Declarative & chainable syntax

Now, with Declarative Syntax and Tween chaining, to create a Tween:

Tween(myView)
.duration(1.0)
.ease(.inOutCubic)
.to(
    .key(\.alpha, 1.0),
    .key(\.frame, CGRect(x:20.0,
                         y:20.0,
                         width:UIScreen.main.bounds.width - 40,
                         height:UIScreen.main.bounds.width - 40)),
    .key(\.backgroundColor!, .red)//NOTE:This property is an optional, add ! to keypath.
)
.onComplete { print("Tween complete") }
.after()//Creates a new tween after with same target and properties.
.duration(1.0)
.ease(Ease.outBounce)
.to(
    .key(\.alpha, 0.25),
    .key(\.frame, CGRect(x:20.0, y:20.0, width:100.0, height:100.0)),
    .key(\.backgroundColor!, .blue)
)
.play()

To create a Timeline:

Timeline(
    
    //Place tweens here, separated by commas.
    
    //Tween 1
    Tween(myView)
    .ease(.inOutQuad)
    .to(.key(\.center, .zero) )
    .onStart {
        self.flipX(inverted: true)
    }
    .onComplete { print("Tween 1 complete") },
    
    //Tween 2
    Tween(myView)
    .to(.key(\.center, self.center) )
    .onStart {
        self.flipY()
    }
    .onComplete { print("Tween 2 complete") }
    
    //Etc....
)
.play()

View's extensions

To make it more friendly, now includes UIView's and NSView's extensions with predefined animations ready-to-use calling a single function from your view instance:

.spring()                     
.zoomIn()
.zoomOut()
.pop()
.fadeIn()
.fadeOut()
.flyLeft()
.flyRight()
.flyTop()
.flyBottom()
.slideLeft()
.slideRight()
.slideTop()
.slideBottom()
.flipX()
.flipY()
.shake()
.jiggle()
.bounce()
.swing()
.spin()
.loop()

View's extensions

Any object Type Support

To add support to other Types and custom Types, assuming there is a struct like this:

public struct Vector3{
    var x, y, z: Double
    func buffer() -> [Double] { return [x, y, z] }
    static func zero() -> Vector3 { return Vector3(x:0.0, y:0.0, z:0.0) }
    static var random: Vector3 {
         return Vector3( x:.random(in: 0...1.0),
                         y:.random(in: 0...1.0),
                         z:.random(in: 0...1.0)
         )
    }
}

Tweener is based on Double arrays so you have to tell it how to convert your object to Array and back to Object.

Tweener.addType(
                toType:{ values in return Vector3(x:values[0], y:values[1], z:values[2]) },
                toArray:{ point in return point.buffer() }
                )

Now, you can animate a 'Vector3' Type object.

Tween(myInstance)
.to(.key(\.myVec3Property, .random))
.play()

MacOS support

This version includes macOS support and samples.

Mac samples

Installation

Install using Cocoapods

To integrate install Cocoa Pods using this gem:

$ gem install cocoapods

Now, add Tweener to your Podfile

pod 'Tweener', '~> 2.1.1'

To install dependencies run this command:

pod install

Install using Carthage

To integrate install Carthage with brew:

$ brew update
$ brew install carthage

Now, add Tweener to your Cartfile

github "alexrvarela/SwiftTweener" ~> 2.1.1

To install dependencies run this command:

$ carthage update

Finally, drag & drop Tweener.framework to your Xcode Project

Install using Swift Package Manager

To install, add dependencies to your Package.swift

dependencies: [
    .package(url: "https://github.com/alexrvarela/SwiftTweener.git", .upToNextMajor(from: "2.1.1"))
]

Install manually

Download, build and copy Tweener.framework to your Xcode project.

Usage

Import Tweener engine to your project:

import Tweener

Animate by default any of these kinds of properties: Int, Float, Double, CGFloat, CGPoint, CGRect, UIColor, CGAffineTransform, CATransform3D

First set initial state:

myView.alpha = 0.25
myView.frame = CGRect(x:20, y:20, width:50, height:50)
myView.backgroundColor = .blue

Create and add a simple Tween:

Tween(myView)
.duration(1.0)//One second
.ease(.inOutCubic)
.to(
    .key(\.alpha, 1.0),
    .key(\.frame,CGRect(x:20, y:20, width:250, height:250)),
    .key(\.backgroundColor!, .red)
)
.play()

Or use 'from' and 'to' keys:

Tween(myView)
.duration(1.0)//One second
.ease(.inOutCubic)
.from(
    .key(\.alpha, 0.25),
    .key(\.frame, CGRect(x:20, y:20, width:50, height:50)),
    .key(\.backgroundColor!, .blue)
)
.to(
    .key(\.alpha, 1.0),
    .key(\.frame,CGRect(x:20, y:20, width:250, height:250)),
    .key(\.backgroundColor!, .red)
)
.play()

To remove a Tween from Engine simply call stop().

myTween.stop()

Simple tween

Tween chaining

To create and chain a Tween with same target and properties just call .after()

    let firstTween = Tween(myViewInstance)
    // This creates and chains a new tween whith time delay after 'firstTween'.
    let secondTween = firstTween.after()
    //This plays firstTween and secondTween.
    secondTween.play()

To create and chain a Tween with different target and Type pass the second Tween as parameter.

    let firstTween = Tween(myViewInstance)
    let secondTween = Tween(otherViewInstance)
    // This chains booth and sets the second one after first one.
    firstTween.after(secondTween)
    //This plays firstTween and secondTween.
    secondTween.play()

You can chain as many Tweens as you want.

Tween handlers

Interact with your code using block handlers:

myTween.onStart {
    self.backgroundColor = .green
}

myTween.onUpdate {
    doAnything()
}

myTween.onComplete {
    self.backgroundColor = .red
}

myTween.onOverwrite {
    self.backgroundColor = .blue
}

Handlers

Remove and pause existing Tweens in the Engine

You can pause, resume and remove existing tweens:

For all existing tweens:

Tweener.pauseAllTweens()
Tweener.resumeAllTweens()
Tweener.removeAllTweens()

By target:

Tweener.pauseTweens(target:myView)
Tweener.resumeTweens(target:myView)
Tweener.removeTweens(target:myView)

By specific properties of a target:

Tweener.pauseTweens(target:myView, keys:[\UIView.backgroundColor, \UIView.alpha])
Tweener.resumeTweens(target:myView, keys:[\UIView.backgroundColor, \UIView.alpha])
Tweener.removeTweens(target:myView, keys:[\UIView.backgroundColor, \UIView.alpha])

Unleash your creativity!

Touch point sample:

Touch

Drag views sample:

Drag

Pause tweens sample:

Background animations

Easing

This engine is based on Robert Penner's Easing equations

Easing curves

To create a custom easing equation:

extension Ease{
    public static let custom = Ease(equation:{ (t, b, c, d) in
        //Play with code here!
        if t < d/2 {return Ease.inBack.equation(t*2, b, c/2, d)}
        return Ease.outElastic.equation((t*2)-d, b+c/2, c/2, d)
    })
}

And use it:

Tween(myView)
    .ease(.custom)
    .to(.key(\.frame, CGRect(x:20.0, y:20.0, width:280.0, height:280.0)))
    .play()

Timeline

Add a Tween or animate with Timeline?

It depends on what do you want, a Tween only animates “to” desired value taking the current value of the property as origin, that allows your App to be more dynamic, each Tween is destroyed immediately after completing the animation.

Timeline stores “from” and “to” values of each Tween, contains a collection of reusable Tweens, to create Timeline and add Tweens use this code:

let myTimeline = Timeline()
.add(
    myTween1, 
    myTween2
    //etc...
)
.play()

You can interact with Timeline play modes, the default value is Play once, it stops when finished, to change Tmeline play mode:

Loop, repeat forever

myTimeline.playMode(.loop)

Loop

Ping Pong, forward and reverse

myTimeline.playMode(.pingPong)

Ping Pong

To remove a Timeline from Engine simply call stop().

myTimeline.stop()

Perform parallax scrolling effects controlling your timeline with UIScrollView:

Timeline scroll

TimelineInspector

You can use the Timeline inspector to debug and edit Tweens

Visualize Tweens in real time:

Visualize Tweens in real time!

Edit Tweens:

Edit Tweens Scale timeline editor

To create Timeline inspector:

let myInspector = TimelineInspector(timeline:myTimeline)
addSubview(myInspector)

PDFImageView

Cut with the image dependency and easily import your vector assets using PDFImageView, forget to export to SVG and other formats iOs offers native support for PDF with CoreGraphics, this class simply renders one pdf inside a UIImageView

To load your asset named "bee.pdf" from App bundle:

let myAsset = PDFImageView(bundlename:"bee")
addSubview(myAsset)

You can increase or reduce the size of your assets with a simple property:

myAsset.scale = 1.5

Aims

Create more complex and impressive animations using Aims

Aims

PathAim

Control motion with paths:

Path aim Text path aim

let myPathAim = PathAim(target:myAsset)
myPathAim.path = myBezierPath

To change location at path change this property value:

myPathAim.interpolation = 0.5

And simply animate path interpolation:

Tween(myPathAim) 
.from(.key(\.interpolation, 0.0))
.to(.key(\.interpolation, 1.0))
.play()

You can export your paths to code from illustrator with this simple Script: https://github.com/alexrvarela/generatePathCode

RotationAim

Animate rotation of any view

Rotation aim

let myRotationAim = RotationAim(target:myView)

Tween(myRotationAim)
.from(.key(\.angle, 90.0))
.to(.key(\.angle, 360.0))
.play()

ArcAim

Create Arc animations

Arc aims

let myArcAim = ArcAim(target:myView)

//Set desired radius
myArcAim.radius = 100.0

//Animate arc angle
Tween(myArcAim)
.from(.key(\.arcAngle, 0.0))
.to(.key(\.arcAngle, 360.0))
.play()

StringAim

Animate text transitions

String aims

//Create string aim
let stringAim = StringAim(target:myUILabel, keyPath:\UILabel.text)
stringAim.from = "hello"
stringAim.to = "hola"

//Set initial interpolation
stringAim.interpolation = 0.0

//Animate, using timeline to repeat forever.
Timeline(

    //Create tween with StringAim target and animate interpolation.
    Tween(stringAim)
    .delay(0.5)
    .duration(0.5)
    .from(.key(\.interpolation, 0.0))
    .to(.key(\.interpolation, 1.0))
    .onComplete { self.swapText() }
    
)
.mode(.loop)
.play()

Play with everything, combine different types of Aim:

Mix different aims

TweenVisualizer

Visualize all tweens and timelines in real time

Create a TweenVisualizer and attach it to Tweener's update loop :

let visualizer = TweenVisualizer()
visualizer.center = viewController.view.center
Tweener.addVisualizer(visualizer)

//Add to UIView
addSubview(visualizer)

To detach visualizer from update loop just use this code:

Tweener.removeVisualizer(visualizer)

Visualizer

Also, you can drag, pinch and resize visualizer at your convenience, to resize just drag the bottom-right corner: Drag Pinch Resize

This library was created to give dynamism to UI elements, if you are looking to make more complex animations I recommend you implement them with Lottie.

Contributions

Pull requests are welcome! The next release will include: SwiftUI samples, watchOs & tvOs samples and unit tests.

Authors

  • Alejandro Ramírez Varela - Initial work - alexrvarela

License

This project is licensed under the MIT License - see the LICENSE file for details

Acknowledgments

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].