{"id":15027661,"url":"https://github.com/ifttt/jazzhands","last_synced_at":"2025-05-13T23:06:26.926Z","repository":{"id":10904859,"uuid":"13200787","full_name":"IFTTT/JazzHands","owner":"IFTTT","description":"A simple keyframe-based animation framework for UIKit. Perfect for scrolling app intros.","archived":false,"fork":false,"pushed_at":"2024-07-30T13:01:27.000Z","size":3051,"stargazers_count":6393,"open_issues_count":15,"forks_count":674,"subscribers_count":120,"default_branch":"main","last_synced_at":"2025-04-05T21:59:34.015Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://ifttt.github.io","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/IFTTT.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-09-29T22:03:15.000Z","updated_at":"2025-04-04T17:08:06.000Z","dependencies_parsed_at":"2022-07-14T01:40:33.976Z","dependency_job_id":"8056b1a9-9563-400f-849a-1aa5fa887a34","html_url":"https://github.com/IFTTT/JazzHands","commit_stats":{"total_commits":155,"total_committers":30,"mean_commits":5.166666666666667,"dds":0.8,"last_synced_commit":"e5f99bf5d2e6b5c1e70b5dc852a90c20e2db03ef"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IFTTT%2FJazzHands","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IFTTT%2FJazzHands/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IFTTT%2FJazzHands/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IFTTT%2FJazzHands/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/IFTTT","download_url":"https://codeload.github.com/IFTTT/JazzHands/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247953845,"owners_count":21024100,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-24T20:06:51.396Z","updated_at":"2025-04-09T01:21:07.795Z","avatar_url":"https://github.com/IFTTT.png","language":"Objective-C","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Open Source at IFTTT](http://ifttt.github.io/images/open-source-ifttt.svg)](http://ifttt.github.io)\n\n![Jazz Hands](./Example/Docs/jazzhands_banner.jpg)\n\n[![CocoaPods Version](https://img.shields.io/cocoapods/v/JazzHands.svg)](http://cocoadocs.org/docsets/JazzHands) [![Build Status](https://travis-ci.org/IFTTT/JazzHands.svg?branch=master)](https://travis-ci.org/IFTTT/JazzHands) [![Coverage Status](https://coveralls.io/repos/IFTTT/JazzHands/badge.svg)](https://coveralls.io/r/IFTTT/JazzHands)\n\nJazz Hands is a simple keyframe-based animation framework for UIKit. Animations can be controlled via gestures, scroll views, KVO, or ReactiveCocoa.\n\n![Jazz Hands](./Example/Docs/jazzhands-demo.gif)\n\nJazz Hands is used extensively in [IF and DO by IFTTT for iPhone and iPad](https://ifttt.com/products), most famously in the app intro.\n\n##Demo App\n\nOpen `JazzHandsDemo.xcworkspace` to see a simple demonstration of moving, scaling, fading, and transforming views in a scrolling app intro.\n\nTo run the example project, clone the repo, and run `pod install` from the `Example` directory.\n\n##JazzHands in Swift\n\nLooking to incorporate Jazz Hands into your Swift project? Check out [`RazzleDazzle`](https://github.com/IFTTT/RazzleDazzle), our brand new scrolling keyframe animations library reimagined in Swift.\n\n##Installation\n\n`JazzHands` is available through [CocoaPods](http://cocoapods.org). To install\nit, simply add the following line to your `Podfile`:\n\n```\npod \"JazzHands\"\n```\n\nYou may alternatively just copy the contents of the `JazzHands` folder into your project.\n\n##Quick Start\n\nFirst, add `JazzHands` to your UIViewController.\n\n```objc\n#import \u003cIFTTTJazzHands.h\u003e\n```\n\nNow, create an Animator to manage all of the animations in this UIViewController.\n\n```objc\n@property (nonatomic, strong) IFTTTAnimator *animator;\n\n// later...\n\nself.animator = [IFTTTAnimator new];\n```\n\nCreate an animation for a view that you want to animate. There are multiple\ntypes of animation that can be applied to a view. For this example, we'll use\n`IFTTTAlphaAnimation`, which fades a view in and out.\n\n```objc\nIFTTTAlphaAnimation *alphaAnimation = [IFTTTAlphaAnimation animationWithView: viewThatYouWantToAnimate];\n```\n\nRegister the animation with the animator.\n\n```objc\n[self.animator addAnimation: alphaAnimation];\n```\n\nAdd some keyframes to the animation. Let's fade this view out between times 30 and 60.\n\n```objc\n[alphaAnimation addKeyframeForTime:30 alpha:1.f];\n[alphaAnimation addKeyframeForTime:60 alpha:0.f];\n```\n\nNow, 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.\n\n```objc\n- (void)scrollViewDidScroll:(UIScrollView *)scrollView\n{\n  [super scrollViewDidScroll:scrollView];\n  [self.animator animate:scrollView.contentOffset.x];\n}\n```\n\nThis 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.\n\n##Animation Types\n\nJazz Hands supports several types of animations:\n\n+ **IFTTTAlphaAnimation** animates the `alpha` property _(creates fade effects)_.\n+ **IFTTTRotationAnimation** animates a rotation transform in degrees _(for rotation effects)_.\n+ **IFTTTBackgroundColorAnimation** animates the `backgroundColor` property.\n+ **IFTTTCornerRadiusAnimation** animates the `layer.cornerRadius` property.\n+ **IFTTTHideAnimation** animates the `hidden` property _(hides and shows views)_.\n+ **IFTTTScaleAnimation** applies a scaling transform _(to scale view sizes)_.\n+ **IFTTTTranslationAnimation** applies a translation transform _(to translate view position)_.\n+ **IFTTTTransform3DAnimation** animates the `layer.transform` property _(for 3D transforms)_.\n+ **IFTTTTextColorAnimation** animates the `textColor` property of a `UILabel`.\n+ **IFTTTFillColorAnimation** animates the `fillColor` property of a `CAShapeLayer`.\n+ **IFTTTStrokeStartAnimation** animates the `strokeStart` property of a `CAShapeLayer` _(does not work with IFTTTStrokeEndAnimation)_.\n+ **IFTTTStrokeEndAnimation** animates the `strokeEnd` property of a `CAShapeLayer` _(does not work with IFTTTStrokeStartAnimation)_.\n+ **IFTTTPathPositionAnimation** animates the `layer.position` property of a `UIView`.\n+ **IFTTTConstraintConstantAnimation** animates an `AutoLayout` constraint constant.\n+ **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)_\n+ **IFTTTScrollViewPageConstraintAnimation** animates an `AutoLayout` constraint constant to place a view on a scroll view page _(to position views on a scrollView using AutoLayout)_\n+ **IFTTTFrameAnimation** animates the `frame` property _(moves and sizes views. Not compatible with AutoLayout)_.\n\n##More Examples\n\n### Easy Paging Scrollview Layouts in an AutoLayout World\n`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.\n\nAs 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:`.\n\nTo see the new JazzHands 2.0 AutoLayout magic in action, check out the example project.\n\n###ReactiveCocoa\n\nSay 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.\n\n```objc\n[RACObserve(self.tableView, contentOffset) subscribeNext:^(NSValue *value) {\n\tCGFloat y = self.tableView.contentOffset.y;\n\t[self.animator animate:y];\n}];\n```\n\n### KVO\n\nOr, maybe you want to animate some views based upon the position of another view? Jazz Hands works well with KVO.\n\n```objc\n- (void)viewDidLoad\n{\n  [self.viewToMirror addObserver:self\n                      forKeyPath:@\"frame\"\n                         options:NSKeyValueObservingOptionInitial\n                         context:nil];\n}\n\n- (void)observeValueForKeyPath:(NSString *)keyPath\n                      ofObject:(id)object\n                        change:(NSDictionary *)change\n                       context:(void *)context {\n\n  if ([keyPath isEqualToString:@\"frame\"]) {\n    [self.animator animate:CGRectGetMinY(self.viewToMirror.frame)];\n  } else {\n    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];\n  }\n}\n```\n\n### Gestures\n\nJazz Hands is flexible enough that it can accept timer input from many different types of sources, including `UIGestureRecognizer`.\n\n```objc\n- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer\n{\n\t[self.animator animate:[recognizer locationOfTouch:0 inView:self.view].x];\n}\n```\n\n## Notes\n\nAn animator can only handle one animation per type per view. If you want multiple animations of the same type on a view, use keyframes.\n\nIFTTTFrameAnimation is not compatible with AutoLayout or any of the constraint animations.\n\nLooking for libraries to build awesome keyframe animations like JazzHands on Android? Check out [`SparkleMotion`](https://github.com/IFTTT/SparkleMotion).\n\n## Contributors\n\n* [Devin Foley](https://github.com/devinfoley), creator.\n* [Laura Skelton](https://github.com/lauraskelton)\n\n## Contributing\n\n1. Fork it ( https://github.com/[my-github-username]/JazzHands/fork )\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\nCopyright 2015 IFTTT Inc.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fifttt%2Fjazzhands","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fifttt%2Fjazzhands","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fifttt%2Fjazzhands/lists"}