Giter Site home page Giter Site logo

tweenkit's Introduction

TweenKit

CI Status Version License Platform Twitter

TweenKit is a powerful animation library that allows you to animate (or 'tween') anything. TweenKit's animations are also scrubbable, perfect for building awesome onboarding experiences!

tweenkit

Download the example project to see how these animations were created

TweenKit's animations are:

  • Reversible
  • Repeatable
  • Groupable
  • Sequenceable
  • Scrubbable
  • Quick and easy to use!

Example

The example project contains a collection of examples of how to use TweenKit. Run Example.xcodeproj

Installation

TweenKit is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "TweenKit"

Importing TweenKit

Add import TweenKit to the top of the files you want to use TweenKit from

Creating an ActionScheduler

Create an instance of ActionScheduler to run your animations. You should retain the scheduler, so it's best made as a property on your View Controller.

let scheduler = ActionScheduler()

Actions

TweenKit's animations are composed of 'Actions'. These are small animation units that can be chained or grouped to build complex animations. Once you have created an action, you can tell the scheduler to run it.

scheduler.run(action: myAction)

Animating a view's frame

Anything that conforms to the 'Tweenable' protocol, can be animated.

CGRect, CGFloat, Double, Float, UIColor, and other common objects already adopt the 'Tweenable' out of the box.

We can use TweenKit's InterpolationAction to animate a view's frame:

let fromRect = CGRect(x: 50, y: 50, width: 40, height: 40)
let toRect = CGRect(x: 100, y: 100, width: 200, height: 100)
        
let action = InterpolationAction(from: fromRect,
                                 to: toRect,
                                 duration: 1.0,
                                 easing: .exponentialInOut) {
                                    [unowned self] in self.redView.frame = $0
}
        
scheduler.run(action: action)

basictween

Grouping actions

Using an ActionGroup, several animations can be run at once. For instance, we can change a view's frame and it's background color:

// Create a move action
let fromRect = CGRect(x: 50, y: 50, width: 40, height: 40)
let toRect = CGRect(x: 100, y: 100, width: 200, height: 100)
        
let move = InterpolationAction(from: fromRect,
                                 to: toRect,
                                 duration: 2.0,
                                 easing: .elasticOut) {
                        [unowned self] in self.squareView.frame = $0
}
        
// Create a color change action
let changeColor = InterpolationAction(from: UIColor.red,
                                      to: UIColor.orange,
                                      duration: 2.0,
                                      easing: .exponentialOut) {
                        [unowned self] in self.squareView.backgroundColor = $0
}
        
// Make a group to run them at the same time
let moveAndChangeColor = ActionGroup(actions: move, changeColor)
scheduler.run(action: moveAndChangeColor)

grouptween

Running actions in sequence

Using an ActionSequence, several animations can be run in order. This time, we can use supply a closure as the 'from' parameter, to animate the view from it's current frame:

let moveOne = InterpolationAction(from: { [unowned self] in self.squareView.frame },
                                  to: CGRect(x: 120, y: 80, width: 50, height: 50),
                                  duration: 1,
                                  easing: .exponentialInOut) {
                                   [unowned self] in self.squareView.frame = $0
}
        
let moveTwo = InterpolationAction(from: { [unowned self] in self.squareView.frame },
                                  to: CGRect(x: 70, y: 120, width: 130, height: 130),
                                  duration: 1,
                                  easing: .exponentialInOut) {
                                    [unowned self] in self.squareView.frame = $0
}
        
let moveTwice = ActionSequence(actions: moveOne, moveTwo)
scheduler.run(action: moveTwice)

sequencetween

Repeating actions

Use RepeatAction to repeat your actions, or RepeatForeverAction to repeat an action forever. You can easily contruct these using the repeated(times:) and repeatedForever methods on any action:

let repeatedForever = myAction.repeatedForever()
scheduler.run(action: repeatedForever)

Yoyo

If you want your action to go back and forth, you can use a YoyoAction. These can be easily constructed by calling the yoyo() method on any action:

let move = InterpolationAction(from: { [unowned self] in self.squareView.frame },
                               to: CGRect(x: 250, y: 100, width: 100, height: 100),
                               duration: 1,
                               easing: .exponentialInOut) {
                                [unowned self] in self.squareView.frame = $0
}
        
scheduler.run(action: move.yoyo().repeatedForever() )

yoyotween

Arc Actions

ArcAction can animate any object that conforms to Tweenable2DCoordinate in a circular motion.

By creating some ArcActions in a staggared Group, we can easily create an activity indicator:

// Create an ArcAction for each circle layer
let actions = circleLayers.map{
    layer -> ArcAction<CGPoint> in
            
    let action = ArcAction(center: self.view.center,
                           radius: radius,
                           startDegrees: 0,
                           endDegrees: 360,
                           duration: 1.3) {
                            [unowned layer] in layer.center = $0
    }
    action.easing = .sineInOut
    return action
}
        
// Run the actions in a staggered group
let group = ActionGroup(staggered: actions, offset: 0.125)
        
// Repeat forever
let repeatForever = group.repeatedForever()
        
// Run the action
scheduler.run(action: repeatForever)

activityindicator

Bezier Actions

Objects can be animated along a bezier path using BezierAction. The callback supplies both position and rotation.

BezierAction can animate any value that conforms to the Tweenable2DCoordinate protocol.

let action = BezierAction(path: bezierPath, duration: 4.0) {
    [unowned self] (postion, rotation) in
            
    self.rocketImageView.center = postion
            
    let rocketRotation = CGFloat(rotation.value)
    self.rocketImageView.transform = CGAffineTransform(rotationAngle: rocketRotation)
}
    
action.easing = .exponentialInOut
        
scheduler.run(action: action)

rocket

Scrubbable actions

Scrubbable Actions are great for building unique onboarding experiences.

Instead of adding the action to a scheduler, create an ActionScrubber instance:

let move = InterpolationAction(from: { [unowned self] in self.squareView.frame },
                               to: CGRect(x: 130, y: 100, width: 100, height: 100),
                               duration: 1,
                               easing: .elasticOut) {
                                [unowned self] in self.squareView.frame = $0
}
        
self.actionScrubber = ActionScrubber(action: move)

// Scrub the action in a UISlider callback
func sliderChanged(slider: UISlider) {
    actionScrubber.update(t: Double(slider.value))
}

scrubbabletween

Animating your own objects

By adding conformance to the Tweenable protocol, anything can be animated. You decide what it means to 'tween' your object, making this a flexible approach.

For instance, by conforming String to Tweenable we can turn a bat into a cat:

InterpolationAction(from: "bat",
                    to: "cat",
                    duration: 4,
                    easing: .exponentialInOut) {
                     [unowned self] in self.label.text = $0
}

battocat

Other Stuff

Use DelayAction to add a delay in to a sequence

Use CallBlockAction to trigger a callback at any point in a sequence

Author

Steve Barnegren

[email protected]

@stevebarnegren

License

TweenKit is available under the MIT license. See the LICENSE file for more info.

tweenkit's People

Contributors

beaunouvelle avatar idonjose avatar jride avatar stevebarnegren avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tweenkit's Issues

Tap gesture in Onboarding?

Hello!

Is it possible to add tap gesture in on-boarding?

So that user could go to the next screen not only with swipe but also with tap (come back to the previous screen only with swipe, obviously).

Thank you.

Support Swift Package Manager in Xcode 11

👋

Hey! Appreciate Xcode 11 has only just been published into beta but getting this in early so that when Xcode 11 is released it's not a surprise or last minute job for anyone :)

Xcode 11 has incredible support for Swift Package Manager, including for iOS projects, and people will be expecting to replace pods with Packages. From what I can see it doesn't look like TweenKit yet supports SPM (which is expected because SPM was never officially supported for iOS until now), so would be good to start thinking about it.

How to Change the Onboarding Sequence

Thank you for the work! The animation seems very easy to do!

In the examples, how can I change the sequence of the animations? Tried to edit this in the OnboardingExampleViewController but it still doesn't change which animation comes first and so on. Pointers will be very appreciated!

 return ActionGroup(actions:
                [introAction,
                 rocketAction,
                 starsAction,
                 makeClockAction(),
                 makeTkAttributesAction(),
                 makeBackgroundColorsAction()]
            ) 

Enhancement - ZwischenzugAction / and repeat sequences / use in tableviewcells / collectionviews

Thanks for quick response Steve on previous ticket.
Heads up - I made a lot of progress on my view rotating label.
Here's a peak.
https://drive.google.com/file/d/0B-w3I-xzXGu0eFZhTnVLaGNYS3c/view

a couple things from stand point of consuming the library

  1. not sure if you play chess - but I need a way to have some action in between actions.
    I looked into the scheduleAction but there was no blocks to inject some method.
    perhaps you could consider down the track adding such an ZwischenzugAction ? or exposing a block on ScheduledAction or document if it's already possible?.

  2. I see there's a repeat method for actions. -
    I couldn't see how to do this on a sequence.

from my code class above

I have this class
https://gist.github.com/johndpope/4897dc5070abce8637886fe9310b9b1b#file-gistfile1-txt-L88

on last line - I simply want to call
let cycleSequence = ActionSequence(actions: moveLeft,bankLabelRight,cycleLeftAgain )
scheduler.run(action: cycleSequence , repeat: forever) // <- keep looping

  1. also - I couldn't see how to remove scheduler actions on destruction of cells.
    seems like my cells in tableview are being recycled causing some havoc.

enhancement - expose primitive values/variables or document methods to allow hooking into variables changing

I used to use this library in objective-c days
https://github.com/danielebogo/PRTween
Perhaps you could cherry pick helpful stuff.

I want to hook into a value that gets updated.
I want to have a ticker style uilabel that rotates when the length is too long.

I'm using snapkit through out project / thus far code looks like this (not full functional)
I want my label's left offset to change over a duration. eg.

UIView.animate(
           withDuration:5.0,
           delay: 0.0,
           options: [UIViewAnimationOptions.curveLinear, UIViewAnimationOptions.beginFromCurrentState, UIViewAnimationOptions.repeat],
           animations: {
              self.labelXoffset = 45 // want a way to hook into a tween value.
               self.label.snp.updateConstraints { (make) -> Void in
                   make.left.equalTo(self.labelXoffset)
               }

       },
           completion: { _ in
               
       })

https://gist.github.com/johndpope/5eef5fab18ad20b467b8da81032fa83f

Should ActionScheduler's animations property be public?

While implementing a "snap" animation, I came across a minor issue. I'd like to prevent a new snap animation from being scheduled before the previous has finished. I simply cancel the previous animation when scheduling a new one:

if let snapAnim = snapAnim
{
    tkScheduler.remove(animation: snapAnim)
}

However, if the animation has already played out, I get an error in console: "Can't find animation to remove". It would be convenient if I could check to see if the scheduler already contains an animation in order to avoid the message. Not sure if you'd rather expose the animations property or implement a contains method. I can do either.

Tween CAShapeLayer path?

Is it possible with this library to create an animation from one path value to another, like with CABasicAnimation, but unlike CABasicAnimation make it scrubbable?

Onboarding loop animations?

Is it possible to somehow make a loop of those swipe animations in onboarding?

So that a user could swipe it without necessity to swipe back.

RepeatForeverAction.update(elapsedTime:) crash

SDK version: TweenKit (1.0.1)
issue: Some iphone devices crashed report from Xcode-Window-Organizer-Crashes.
iOS version: 13.1.3,13.3,13.4.1,13.6,13.6.1,14.0 etc.
Screenshot is like below:
截屏2020-09-23 下午5 42 51

It is like that crashes happened at
let repeatNumber = Int(elapsedTime / action.duration)
So is it possible action.duration to be equal to zero? or other reasons?

I can not figure it out temporarily, hope you can help.
Thank you very much.

UIPageViewController BarItem transition animations

Hey @SteveBarnegren your probably the perfect person to ask for this. Im using a UIPageViewController library (Tabman) to create a UI to swipe between pages where the NavBarItems animate between page swipes with ease-In functions to create a fluid feel like the example below from the app "tbh app". I have a repo I'm working with to replicate this found here. Technically in my example I use a UIView with UIButtons as Im not sure UIBarButtonItem positions can be animated

So far Im failing because it involves animating each barItem with ease-In functions and would like to get your thoughts on how I can leverage TweenKit to achieve this.

nav

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.