A simple keyframe-based animation framework for UIKit. Perfect for scrolling app intros.

Related tags

ViewPager JazzHands
Overview

Open Source at IFTTT

Jazz Hands

CocoaPods Version Build Status Coverage Status

Jazz Hands is a simple keyframe-based animation framework for UIKit. Animations can be controlled via gestures, scroll views, KVO, or ReactiveCocoa.

Jazz Hands

Jazz Hands is used extensively in IF and DO by IFTTT for iPhone and iPad, most famously in the app intro.

##Demo App

Open JazzHandsDemo.xcworkspace to see a simple demonstration of moving, scaling, fading, and transforming views in a scrolling app intro.

To run the example project, clone the repo, and run pod install from the Example directory.

##JazzHands in Swift

Looking to incorporate Jazz Hands into your Swift project? Check out RazzleDazzle, our brand new scrolling keyframe animations library reimagined in Swift.

##Installation

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

pod "JazzHands"

You may alternatively just copy the contents of the JazzHands folder into your project.

##Quick Start

First, add JazzHands to your UIViewController.

#import <IFTTTJazzHands.h>

Now, create an Animator to manage all of the animations in this UIViewController.

@property (nonatomic, strong) IFTTTAnimator *animator;

// later...

self.animator = [IFTTTAnimator new];

Create an animation for a view that you want to animate. There are multiple types of animation that can be applied to a view. For this example, we'll use IFTTTAlphaAnimation, which fades a view in and out.

IFTTTAlphaAnimation *alphaAnimation = [IFTTTAlphaAnimation animationWithView: viewThatYouWantToAnimate];

Register the animation with the animator.

[self.animator addAnimation: alphaAnimation];

Add some keyframes to the animation. Let's fade this view out between times 30 and 60.

[alphaAnimation addKeyframeForTime:30 alpha:1.f];
[alphaAnimation addKeyframeForTime:60 alpha:0.f];

Now, to animate the view, tell the animator what time it is. For example, to tie this animation to a UIScrollView, notify the animator of time in the scroller's delegate method.

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
  [super scrollViewDidScroll:scrollView];
  [self.animator animate:scrollView.contentOffset.x];
}

This will produce an effect where the view will be fully faded in and visible for scroll positions 0 to 30. Between scroll positions 30 and 60, the view will fade out to be invisible, and it will stay faded out for scroll positions greater than 60.

##Animation Types

Jazz Hands supports several types of animations:

  • IFTTTAlphaAnimation animates the alpha property (creates fade effects).
  • IFTTTRotationAnimation animates a rotation transform in degrees (for rotation effects).
  • IFTTTBackgroundColorAnimation animates the backgroundColor property.
  • IFTTTCornerRadiusAnimation animates the layer.cornerRadius property.
  • IFTTTHideAnimation animates the hidden property (hides and shows views).
  • IFTTTScaleAnimation applies a scaling transform (to scale view sizes).
  • IFTTTTranslationAnimation applies a translation transform (to translate view position).
  • IFTTTTransform3DAnimation animates the layer.transform property (for 3D transforms).
  • IFTTTTextColorAnimation animates the textColor property of a UILabel.
  • IFTTTFillColorAnimation animates the fillColor property of a CAShapeLayer.
  • IFTTTStrokeStartAnimation animates the strokeStart property of a CAShapeLayer (does not work with IFTTTStrokeEndAnimation).
  • IFTTTStrokeEndAnimation animates the strokeEnd property of a CAShapeLayer (does not work with IFTTTStrokeStartAnimation).
  • IFTTTPathPositionAnimation animates the layer.position property of a UIView.
  • IFTTTConstraintConstantAnimation animates an AutoLayout constraint constant.
  • IFTTTConstraintMultiplierAnimation animates an AutoLayout constraint constant as a multiple of an attribute of another view (to offset or resize views based on another view's size)
  • IFTTTScrollViewPageConstraintAnimation animates an AutoLayout constraint constant to place a view on a scroll view page (to position views on a scrollView using AutoLayout)
  • IFTTTFrameAnimation animates the frame property (moves and sizes views. Not compatible with AutoLayout).

##More Examples

Easy Paging Scrollview Layouts in an AutoLayout World

JazzHands's keepView:onPage: method of the IFTTTAnimatedPagingScrollViewController is a super easy way to lay out a paging scroll view that does what you expect it to when your app is rotated or used in the new split-screen iPad views of iOS9, a notoriously tricky aspect of getting your apps fully AutoLayout-ready. JazzHands sets up an AutoLayout-friendly paging scroll view controller for you, and all you need to do to make your layout respond properly to any view size changes is tell JazzHands which page you'd like things on.

As a bonus, because it's built on top of the animations library, you can even tell JazzHands that you'd like one of your views to show up on multiple pages while other views scroll past, with a single call to keepView:onPages:.

To see the new JazzHands 2.0 AutoLayout magic in action, check out the example project.

###ReactiveCocoa

Say you want to perform some animations based on a UITableView's scroll offset, but you don't want to be the delegate for that table? ReactiveCocoa is perfect for that.

[RACObserve(self.tableView, contentOffset) subscribeNext:^(NSValue *value) {
	CGFloat y = self.tableView.contentOffset.y;
	[self.animator animate:y];
}];

KVO

Or, maybe you want to animate some views based upon the position of another view? Jazz Hands works well with KVO.

- (void)viewDidLoad
{
  [self.viewToMirror addObserver:self
                      forKeyPath:@"frame"
                         options:NSKeyValueObservingOptionInitial
                         context:nil];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context {

  if ([keyPath isEqualToString:@"frame"]) {
    [self.animator animate:CGRectGetMinY(self.viewToMirror.frame)];
  } else {
    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
  }
}

Gestures

Jazz Hands is flexible enough that it can accept timer input from many different types of sources, including UIGestureRecognizer.

- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer
{
	[self.animator animate:[recognizer locationOfTouch:0 inView:self.view].x];
}

Notes

An animator can only handle one animation per type per view. If you want multiple animations of the same type on a view, use keyframes.

IFTTTFrameAnimation is not compatible with AutoLayout or any of the constraint animations.

Looking for libraries to build awesome keyframe animations like JazzHands on Android? Check out SparkleMotion.

Contributors

Contributing

  1. Fork it ( https://github.com/[my-github-username]/JazzHands/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Copyright 2015 IFTTT Inc.

Comments
  • Animation does not work fluent

    Animation does not work fluent

    I tried the following animation:

    First I created a view:

        self.phoneScreen = UIImageView(image: UIImage(named: "screenBlank")!)
        self.phoneScreen?.frame = CGRectMake(0, 0, self.phoneScreen!.frame.width/2, self.phoneScreen!.frame.height/2)
        self.phoneScreen?.center = self.view.center
        self.scrollView.addSubview(self.phoneScreen!)
    

    Then I created the animation:

    let phoneScreenAnimation: IFTTTFrameAnimation = IFTTTFrameAnimation(view: self.phoneScreen!)
        self.animator.addAnimation(phoneScreenAnimation)
    
        phoneScreenAnimation.addKeyFrame(IFTTTAnimationKeyFrame(time: timeForPage(1), andFrame: self.phoneScreen!.frame))
        phoneScreenAnimation.addKeyFrame(IFTTTAnimationKeyFrame(time: timeForPage(2), andFrame: CGRectOffset(self.phoneScreen!.frame, self.view.frame.size.width, 0)))
    

    The function timeForPage is based on your example.

    Here is the problem. The animation is running correctly from page 1 to page 2. The problem is that is not very smooth. It shakes a bit, or lets say it vibrates a bit while running. The shaking is around the x axis while the translation is running. It looks like there is a lot of computation and that the rendering of the view could not handle painting that fast. Is there something wrong with my code or is there a better way to move a view from page 1 to page 2?

    opened by confile 15
  • Speed up adding keyframes

    Speed up adding keyframes

    Hi,

    Adding keyframes seems to regenerate the animation timeline at each new frame. I understand that to change the behaviour you would have to break the compatibility with previous versions so I propose adding a macro or something to disable the behavior, combined with a new method like commitKeyframes or createTimeline that would sort keyframes and generate the timeline. Also maybe adding an optional parameter (BOOL)commit to the addKeyFrame method on the animation base class could be also nice.

    By implementing this I dropped my animation creations from 1.86s down to 0.85s on iPhone4/iOS6. Agreed, I do have a lot of animations, but still this could still be a nice improvement!

    I can make a pull request if you want, but I reckon you may prefer do it yourself(ves).

    Keep up the good work!

    PS: if there is any other room for improvement, I would love to hear about it!

    opened by dvkch 10
  • Implement IFTTTMaskEffectRevealFromCenter animation in IFTTTMaskAnimation

    Implement IFTTTMaskEffectRevealFromCenter animation in IFTTTMaskAnimation

    Not sure if anyone else would find this useful, but I implemented a circular mask animation. This animation will mask a view to a circle starting in the center at visibility 0 and work it's way to the outside at visibility 1.0.

    Initially I thought I could use the corner radius animation for what I needed, but I wanted the radius to be calculated automatically.

    opened by jsm174 8
  • Corner radius animation

    Corner radius animation

    Added corner radius animation feature.

    from: https://github.com/IFTTT/JazzHands/issues/1495

    @jhersh here it is. If I need to do anything else let me know.

    opened by nunogoncalves 8
  • Installation issue

    Installation issue

    By simple drag and drop of the src files in custom project. I get 10 errors of similiar kind. What is the myth behind ? Unknown type name 'IFTTTFrameAnimation'; did you mean 'IFTTTAnimation'?

    opened by yunas 8
  • Handle Gestures

    Handle Gestures

    In your pan example you wrote:

    - (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
      [self.animator animate:[recognizer locationOfTouch:0 inView:self.view]];
    }
    

    This is wrong because locationOfTouchwill return a CGPoint is there a way to fix that?

    opened by confile 7
  • Help to put a UIImageView to the right or to the left

    Help to put a UIImageView to the right or to the left

    Hello,

    I do not see the way to make the animation that you have on your gif on the page 4 and 5. First at all I can not put the UIImageView where I want to on the next page move it.

    I can put it where I want on Y axis but not on the X axis. On your Unicorn example you have everything centered on the X axis but not moved to the right or the left. Could you help me?

    Thanks in advance

    opened by javiergonzper 6
  • Added angle animations for rotation animations and better examples

    Added angle animations for rotation animations and better examples

    Added a new IFTTTAngleAnimation class along with some updates to examples to demonstrate other constructors as well as multiple keyframe initialization.

    opened by Zanfa 6
  • Swift DSL for JazzHands

    Swift DSL for JazzHands

    Hi,

    I created a Swift DSL for JazzHands. You can find it here:

    https://github.com/confile/JazzHandsSwift

    It would be great if you could linke to this DSL if you like it.

    question 
    opened by confile 5
  • CAShapeLayer: strokeStart, strokeEnd, fillColor properties animation

    CAShapeLayer: strokeStart, strokeEnd, fillColor properties animation

    Hi, in this PR I've added an initializer, with a CALayer, to IFTTTAnimation and 3 IFTTTAnimation subclasses to animate:

    • CAShapeLayer.strokeStart
    • CAShapeLayer.strokeEnd
    • CAShapeLayer.fillColor

    Here's an example animation for strokeEnd (from 1 to 0) and fillColor (from blue to clear):

    anim1

    opened by pNre 5
  • Invalid frame position when using demo view controller

    Invalid frame position when using demo view controller

    Hi,

    I am trying out your library and I am quickly facing a strange issue. The demo project runs fine on iOS6-7-8 and iPhone 4-5-6 (even after enabling iPhone 6 screen support), though if I use the exact same code in my own app it fails. Literally the same code, except for the added #import <UIKit/UIKit.h> in the view controller header.

    The exception is thrown at line 24 of the view controller class: self.view.frame = animationFrame.frame; with exception CALayer position contains NaN: [nan nan].

    Here is a link to the sample project: https://github.com/dvkch/JazzHandsBug1063 .

    Thanks for taking time to look into this, Stan

    opened by dvkch 4
  • Broken hide animation!!!

    Broken hide animation!!!

    Previously, I had this code:

    - (void)setView:(UIView *)view hiddenAtEndOfAnimation:(BOOL)hidden atPage:(Page)page {
    
    	IFTTTHideAnimation *hideAnimation = [[IFTTTHideAnimation alloc] initWithView:view];
    
    	[hideAnimation addKeyFrame:[[IFTTTAnimationKeyFrame alloc] initWithTime:page.left andHidden:!hidden]];
    	[hideAnimation addKeyFrame:[[IFTTTAnimationKeyFrame alloc] initWithTime:page.right - 1 andHidden:!hidden]];
    
    	[hideAnimation addKeyFrame:[[IFTTTAnimationKeyFrame alloc] initWithTime:page.right andHidden:hidden]];
    
    	[self.contentAnimator addAnimation:hideAnimation];
    }
    

    but with the latest version, this is impossible, as there is no simple init that only sets the view. Highly dissapointed.

    opened by revolter 1
  • HOW TO EXECUTE ANIMATION WITH UIVIEWCONTROLLER?

    HOW TO EXECUTE ANIMATION WITH UIVIEWCONTROLLER?

    I apologize if this question seems basic to some, but I am a bit of a newbie. I have tried for hours to tweak the demo code to make the animation execute on a normal uiviewcontroller (not the scrollview that they provide). I would really appreciate any feedback. Is this possible? Thank you!

    opened by jamesesterbrookerwin 0
  • Animation issue in iOS 7.0.3

    Animation issue in iOS 7.0.3

    Hi, I used your JazzHands to build a app guide page. and found a little issue about position of animation issue in iOS 7.0.3 while in other version of iOS is fine. I made a demo about how that issue appears. here is the repo : https://github.com/lane128/WLJazzHandsDemo

    here is the incorrect position after animation. (iOS 7.0.3) image image here is the correct position after animation (iOS > 7.0.3) image

    Hope you can help me to solve it. Thanks.

    opened by lane128 0
Releases(2.0.3)
  • 2.0.3(Jul 22, 2015)

    New Features

    • Added left, right and center options to keepView:onPage: and keepView:onPages: to add more fine-tuned AutoLayout control.
    • Added IFTTTPathPositionAnimation to animate a view moving along a bezier path, as seen in the paper airplane animation in the demo app.

    New Demo App

    • Major update to the JazzHands Demo App to show off our new animations.

    Bug Fix

    • Fixed a bug in the Filmstrip when interpolating between black/white and other colors, and optimized performance of the Filmstrip by removing runtime type checks. Thanks to @RodolfoAntonici and @gazsp for the detective work on this!
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0(Jun 22, 2015)

    JazzHands 2.0!

    • Updated to work better with AutoLayout with new types of constraint animations
    • Added a new IFTTTAnimatedPagingScrollViewController for quick-start AutoLayout-friendly animated paging scroll view animations.
    • Added new keepView:onPage and keepView:onPages methods for much more simplicity in animating view positions on paging scrollviews, and much easier AutoLayout-friendly scrollviews.
    • Updated Demo app to show how to create a fully AutoLayout-friendly paging animated scrollview, perfect for use with rotation or the new iOS9 Split Screen multitasking.
    • Changed to simpler syntax for adding keyframes
    • Updated to animate CGFloat times, to simplify keyframe times and work more smoothly on Retina displays.
    • Switched from a pre-generated array of interpolated animation values to interpolating at any point between keyframes on demand, for faster animation creation and far fewer allocations when adding keyframes.
    • Replaced IFTTTAngleAnimation with IFTTTRotationAnimation, which takes degrees instead of radians.
    • Fixed Transform animations to work together. Now IFTTTScaleAnimation, IFTTTRotationAnimation, and IFTTTTranslationAnimation can all be used on the same view without conflicting.
    • Increased unit test coverage.
    • Made IFTTTAnimation easy to subclass with your own custom animation types (see MyCustomAnimation in the Demo app for an example of how easy this is).
    • Added Interpolatable protocol to define how to interpolate between values of different types.

    New Animations

    • Added IFTTTFillColorAnimation, IFTTTStrokeStartAnimation, and IFTTTStrokeEndAnimation - thanks @pNre!
    • Added IFTTTTextColorAnimation - thanks @revolter!
    Source code(tar.gz)
    Source code(zip)
  • 0.2.1(Mar 11, 2015)

  • 0.2.0(Feb 16, 2015)

  • 0.0.4(Mar 17, 2014)

Owner
IFTTT
Every thing works better together.
IFTTT
A custom ViewPager title strip which gives continuous feedback to the user when scrolling

SmartTabLayout A custom ViewPager title strip which gives continuous feedback to the user when scrolling. This library has been added some features an

ogaclejapan 7k Jan 1, 2023
An android ViewPager extension allowing infinite scrolling

NO LONGER MAINTAINED LoopingViewPager An android ViewPager extension allowing infinite scrolling. You can use it with "standart" PagerAdapter (inflati

Leszek Mzyk 992 Nov 10, 2022
Android library for fluid tablayout animation as seen on Snapchat.

SnapTabLayout Show some ❤️ and star the repo to support the project This library is the implementation of TabLayout as seen on popular messaging app S

Niranjan Kurambhatti 714 Dec 25, 2022
Android ViewPager template with cool animation.

glazy-viewpager ViewPager template with cool animation. Preview Dependencies compile 'com.android.support:palette-v7:25.2.0' Usage Refer the implement

Kannan Anbarasan 251 Nov 29, 2022
Don't write a ViewPager Adapter! Hook up your ViewPager to your data model using Android Data Binding Framework. With Kotlin support!

Don't write a ViewPager Adapter! Hook up your ViewPager to your data model using Android Data Binding Framework. Show some ❤️ ?? Sweet and short libra

Rakshak R.Hegde 180 Nov 18, 2022
A simple app that consumes The Ricky & Morty API to display the tv show characters, was trying to learn about pagination with the paging 3 library

Ricky&MortyAPIDemo A simple app that consumes The Rick and Morty API which is a REST and GraphQL API based on the television show Rick and Morty. I wa

Joel Kanyi 9 Jul 12, 2022
Combine ViewPager and Animations to provide a simple way to create applications' guide pages.

WoWoViewPager WoWoViewPager combines ViewPager and Animations to provide a simple way to create applications' guide pages. When users are dragging WoW

黄伟平 2.7k Dec 30, 2022
A beautiful way to introduce users to your app

Onboarding A beautiful way to introduce users to you app Using a regular ViewPager with a custom transformer with callbacks we can achieve this effect

Eoin Fogarty 1.5k Dec 17, 2022
Android App of Pager

Pager Pager allows you to communicate with people without any infrastructure based services like cellular network or Wifi. We make this possible by tr

Akshat Tiwari 0 Dec 1, 2021
Perfect replacement for startActivityForResult(), based on the Activity Result API.

ActivityResultLauncher English | 中文 Activity Result API is an official tool used to replace the method of startActivityForResult() and onActivityResul

DylanCai 167 Nov 30, 2022
Android library (AAR). Highly configurable, easily extendable deep zoom view for displaying huge images without loss of detail. Perfect for photo galleries, maps, building plans etc.

Subsampling Scale Image View A custom image view for Android, designed for photo galleries and displaying huge images (e.g. maps and building plans) w

null 7.4k Jan 8, 2023
Pixel perfect for design layout android

Pixelperfect Pixel perfect helps you design layouts according to the resolution of your users' device Follow the steps below to implement : dependen

null 10 Oct 23, 2022
LiveData 数据倒灌:别问,问就是不可预期 - Perfect alternative to SingleLiveEvent, supporting multiple observers.

前言 大家好,我是《Jetpack MVVM Best Practice》作者 KunMinX。 今天提到的 “数据倒灌” 一词,缘于我为了方便理解和记忆 “页面在 ‘二进宫’ 时收到旧数据推送” 的情况,而在 2019 年 自创并在网上传播的 关于此类现象的概括。 它主要发生在:通过 Shared

KunMinX 924 Jan 5, 2023
Bulletin helps you to "swipe" through your favorite events in the campus and gives you the perfect match for your better experience

Bulletin helps you to "swipe" through your favorite events in the campus and gives you the perfect match for your better experience. Right swipe to add event to your calendar and left swipe to view the next event.

GDSC Navrachana University 7 Feb 11, 2022
An Android view for displaying repeated continuous side scrolling images. This can be used to create a parallax animation effect.

Scrolling Image View An Android view for displaying repeated continuous side scrolling images. This can be used to create a parallax animation effect.

Q42 1.8k Dec 27, 2022
GoolgePlusLayout is a custom layout that plays animation on the children views while scrolling as the layout in the Google Plus (android) main page

Google Plus Layout Google Plus Layout is a custom layout that support playing animation on child view(s) in a serialize manner like the the main

Ahmed Nammari 224 Nov 25, 2022
A Jetpack Compose Collapsing Top Bar, that expands or collapses based on the scrolling of a content

CollapsingTopBarCompose A Jetpack Compose Collapsing Top Bar, that expands or collapses based on the scrolling of a content Centered expanded title an

Germain Kevin 139 Dec 26, 2022
Charts/graphs library for Android compatible with API 8+, several chart types with support for scaling, scrolling and animations

HelloCharts for Android Charting library for Android compatible with API 8+(Android 2.2). Works best when hardware acceleration is available, so API 1

Leszek Wach 7.4k Jan 6, 2023
An image loading and caching library for Android focused on smooth scrolling

Glide | View Glide's documentation | 简体中文文档 | Report an issue with Glide Glide is a fast and efficient open source media management and image loading

Bump Technologies 33.2k Jan 7, 2023