{"id":2332,"url":"https://github.com/jhurray/JHChainableAnimations","last_synced_at":"2025-08-02T23:33:03.044Z","repository":{"id":31265984,"uuid":"34827714","full_name":"jhurray/JHChainableAnimations","owner":"jhurray","description":"Easy to read and write chainable animations in Objective-C and Swift","archived":false,"fork":false,"pushed_at":"2018-01-04T04:22:10.000Z","size":1708,"stargazers_count":3228,"open_issues_count":10,"forks_count":308,"subscribers_count":99,"default_branch":"master","last_synced_at":"2024-11-09T13:39:37.555Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/jhurray.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}},"created_at":"2015-04-30T01:36:02.000Z","updated_at":"2024-11-03T21:33:09.000Z","dependencies_parsed_at":"2022-08-21T03:50:10.111Z","dependency_job_id":null,"html_url":"https://github.com/jhurray/JHChainableAnimations","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhurray%2FJHChainableAnimations","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhurray%2FJHChainableAnimations/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhurray%2FJHChainableAnimations/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jhurray%2FJHChainableAnimations/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jhurray","download_url":"https://codeload.github.com/jhurray/JHChainableAnimations/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224008023,"owners_count":17240292,"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-01-05T20:16:11.094Z","updated_at":"2024-12-06T17:31:00.485Z","avatar_url":"https://github.com/jhurray.png","language":"Objective-C","funding_links":[],"categories":["UI","Objective-C","Animation"],"sub_categories":["Animation","Other free courses"],"readme":"\u003cimg src=\"./img/logo.png\" \u003e\u003c/img\u003e\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd width=75%\"\u003e\n\u003cimg src=\"./img/JHChainableAnimationsExample1.png\" width=\"100%\" \u003e\u003c/img\u003e\n\u003c/td\u003e\n\u003ctd width=25%\"\u003e\n\u003cimg src=\"./Gifs/JHChainableAnimationsExample1.gif\"\u003e\u003c/img\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd width=\"75%\"\u003e\n\u003cimg src=\"./img/JHChainableAnimationsExample2.png\" width=\"100%\" \u003e\u003c/img\u003e\n\u003c/td\u003e\n\u003ctd width=\"25%\"\u003e\n\u003cimg src=\"./Gifs/JHChainableAnimationsExample2.gif\"\u003e\u003c/img\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd width=\"75%\"\u003e\n\u003cimg src=\"./img/JHChainableAnimationsExample3.png\" \u003e\u003c/img\u003e\n\u003c/td\u003e\n\u003ctd width=\"25%\"\u003e\n\u003cimg src=\"./Gifs/JHChainableAnimationsExample3.gif\" \u003e\u003c/img\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n![language](https://img.shields.io/badge/Language-Objective--C-8E44AD.svg)\n![language](https://img.shields.io/badge/Language-Swift-8E44AD.svg)\n![Version](https://img.shields.io/badge/Pod-%20v3.0.1%20-96281B.svg)\n![Build Status](https://img.shields.io/badge/build-passing-brightgreen.svg)\n![MIT License](https://img.shields.io/github/license/mashape/apistatus.svg)\n![Platform](https://img.shields.io/badge/platform-%20iOS%20-lightgrey.svg)\n![Platform](https://img.shields.io/badge/platform-%20tvOS%20-lightgrey.svg)\n\n## Whats new in version 3.x?\n* Swiftier syntax\n* Swift 4 support\n* Bug fixes and improvements\n\n## Whats new in version 2.x?\n* Re-architected from the ground up, no more hacking UIView 🛠\n* Added pre-animation and post-animation hooks for each animation step ⛓\n* Added pause and resume functionality ⏯\n* Added repeat animation functionality 🔂\n* Added friendly Swift interface in separate framework 🔥🕊\n\n## Whats wrong with animations?\n\nCAAnimations and UIView animations are extremely powerful, but it is difficult to chain multiple animations together, especially while changing anchor points. \n\nFurthermore, complicated animations are difficult to read. \n\nSay I want to move myView 50 pixels to the right with spring and then change the background color with inward easing when the movement has finished:\n\n### The Old Way\n\n```objective-c\n    [UIView animateWithDuration:1.0\n                          delay:0.0\n         usingSpringWithDamping:0.8\n          initialSpringVelocity:1.0\n                        options:0 animations:^{\n                            CGPoint newPosition = self.myView.frame.origin;\n                            newPosition.x += 50;\n                            self.myView.frame.origin = newPosition;\n    } completion:^(BOOL finished) {\n        [UIView animateWithDuration:0.5\n                              delay:0.0\n                            options:UIViewAnimationOptionCurveEaseIn\n                         animations:^{\n            self.myView.backgroundColor = [UIColor purpleColor];\n        } completion:nil];\n    }];\n```\n\nThats pretty gross huh... With JHChainableAnimations it is one line of code. \n\n### Using JHChainableAnimations\n\n```objective-c\nJHChainableAnimator *animator = [[JHChainableAnimator alloc] initWithView:self.myView];\nanimator.moveX(50).spring.thenAfter(1.0).makeBackground([UIColor purpleColor]).easeIn.animate(0.5);\n```\n\nThere are also a lot of really good animation libraries out there such as [RBBAnimation](https://github.com/robb/RBBAnimation), [DCAnimationKit](https://github.com/daltoniam/DCAnimationKit), and [PMTween](https://github.com/poetmountain/PMTween),  but they still fall short of having powerful chainable animations AND easy to read/write syntax. \n\n## Installation\nThere are a few ways you can add this framework to your project. The Objective-C framework is called `JHChainableAnimations` and the Swift framework is called `ChainableAnimations`. More notes on Swift usage can be found [here](#swift)\n\n### Cocoapods\n\n##### Objective-C\n\n```ruby\npod 'JHChainableAnimations', '~\u003e 3.0.1'\n```\nThen add the following:\n\n```objective-c\n#import \u003cJHChainableAnimations/JHChainableAnimations.h\u003e\n```\n\n\n##### Swift\n```ruby\npod 'ChainableAnimations', '~\u003e 3.0.1'\n```\nThen add the following:\n\n```swift\nimport ChainableAnimations\n```\n\n### Carthage\nAdd the following to your `Cartfile`\n\n```ruby\ngithub \"jhurray/JHChainableAnimations\" ~\u003e 3.0.1\n```\n##### Objective-C\nAdd the `JHChainableAnimations` framework to your project.\n\n##### Swift\nAdd the `ChainableAnimations` framework to your project.\n\n\n### Add to project Manually\nEither clone the repo and manually add the Files in [JHChainableAnimations](./JHChainableAnimations)\n\n\n## Usage\n\n### Creating an Animator\n\nTo create an instance of `JHChainableAnimator` you must call the `initWithView:` method.\n\n```objective-c\nJHChainableAnimator *animator = [[JHChainableAnimator alloc] initWithView:self.myView];\n```\n\n### Animating\n\nChainable properties like `moveX(x)` must come between the view and the `animate(t)` function\n\nBelow is an example of how to double an objects size over the course of one second. \n\n```objective-c\nanimator.makeScale(2.0).animate(1.0);\n```\n\n### Combining Animations\n\nIf you want to move the view while you scale it, add another chainable property. Order is not important\n\n```objective-c\nanimator.makeScale(2.0).moveXY(100, 50).animate(1.0);\n// the same as animator.moveXY(100, 50).makeScale(2.0).animate(1.0);\n```\n\nA full list of chainable properties can be found [here](#chainables)\n\n### Chaining Animations\n\nTo chain animations seperate the chains with the `thenAfter(t)` function.\n\nBelow is an example of how to scale and object for 0.5 seconds, and then move it for 1 second when that is done.\n\n```objective-c\nanimator.makeScale(2.0).thenAfter(0.5).moveXY(100, 50).animate(1.0);\n```\n\n### Animation Effects\n\nTo add an animation effect, call the effect method after the chainable property you want it to apply to.\n\nBelow is an example of scaling a view with a spring effect.\n\n```objective-c\nanimator.makeScale(2.0).spring.animate(1.0);\n```\n\nIf you add 2 to the same chainable property the second will cancel the first out. \n\n```objective-c\nanimator.makeScale(2.0).bounce.spring.animate(1.0);\n// The same as animator.makeScale(2.0).spring.animate(1.0);\n```\n\nA full list of animation effect properties can be found [here](#effects)\n\n### Anchoring\nTo anchor your view call an achoring method at some point in an animation chain. Like effects, calling one after another in the same chain will cancel the first out. \n\nBelow is an example of rotating a view around different anchor points\n\n```objective-c\nanimator.rotateZ(180).anchorTopLeft.thenAfter(1.0).rotateZ(90).anchorCenter.animate(1.0);\n\n// animator.rotateZ(90).anchorTopLeft.anchorCenter == animator.rotateZ(90).anchorCenter\n```\n\nA full list of anchor properties can be found [here](#anchors)\n\n### Delays\nTo delay an animation call the `wait(t)` or `delay(t)` chainable property.\n\nBelow is an example of moving a view after a delay of 0.5 seconds\n\n```objective-c\nanimator.moveXY(100, 50).wait(0.5).animate(1.0);\n// The same as animator.moveXY(100, 50).delay(0.5).animate(1.0);\n```\n\n### Completion\nTo run code after an animation finishes set the `completionBlock` property of your animator or call the `animateWithCompletion(t, completion)*`function.\n\n```objective-c\nanimator.makeX(0).animateWithCompletion(1.0, ^{\n\tNSLog(@\"Animation Done\");\n});\n```\n\nIs the same as: \n\n```objective-c\nanimator.completionBlock = ^{\n\tNSLog(@\"Animation Done\");\n};\nanimator.makeX(0).animate(1.0);\n```\n\n### Repeating Animations\nYou can repeat an animation by replacing the `thenAfter(time)` method with the `repeat(time, count)` method. This will repeat the previously defined animations. \n\n```objective-c\n// The animator will double its scale 3 times for 0.5 seconds each before it calls `moveXY` and finishes the animation\nanimator.makeScale(2.0).repeat(0.5, 3).moveXY(100, 50).animate(1.0);\n```\n\nYou can repeat the last part of an animation by calling `animateWithRepeat(time, count)`.\n\n```objective-c\n// The animator will double its scale then rotate by 90 degrees 3 times for 1 second each.\nanimator.makeScale(2.0).thenAfter(0.5).rotate(90). animateWithRepeat(1.0, 3);\n```\n\n### Pausing and Cancelling\nTo Pause the animation, call the `pause` method on the animator. When you call pause, the current animation in the chain will complete but nothing beyod that will be executed. You can use the `isPaused` and `isAnimating` readonly properties to inspect state. If an animation is paused but not stopped, it will still evaluate as `animating`.\n\nTo resume in a paused state, call the `resume` method on the animator.\n\nTo stop animation and clear state, call the `stop` method on the animator.\n\n```objective-c\n// In this case the `moveX` animation will execute but the `moveY` will not\n// If `resume` is called `moveY` will be executed\n// If `stop` is called, nothing will be executed and the animator will get a fresh state\nanimator.moveX(10).thenAfter(0.5).moveY(10).animate(0.5);\n[animator pause];\n```\n\n### Callbacks\nYou can hook into the different steps of the animation process by calling the `preAnimationBlock(block)`, `animationBlock(block)`, and `postAnimationBlock(block)` methods. All take a simple block `void(^)()` as an argument. Order of calling these in the animation chain does not matter.\n\n```objective-c\nanimator.moveX(10).preAnimationBlock(^{ \n\tNSLog(@\"before the first animation\");\n }).thenAfter(1.0).postAnimationBlock(^{\n \tNSLog(@\"After the second animation\");\n }).moveY(10).animate(1.0);\n```\n\n\n### Bezier Paths\nYou can also animate a view along a [UIBezierPath](https://developer.apple.com/library/ios/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/BezierPaths/BezierPaths.html). Create a `UIBezierPath *` instance, then add points or curves or lines to it and use it in a chainable property.\n\n```objective-c\nUIBezierPath *path = [UIBezierPath bezierPath];\n[path moveToPoint:self.myView.center];\n[path addLineToPoint:CGPointMake(25, 400)];\n[path addLineToPoint:CGPointMake(300, 500)];\nanimator.moveOnPath(path).animate(1.0);\n```\nAnimation effects do not work on path movements.\n\n\n## \u003ca name=\"autolayout\"\u003e\u003c/a\u003eUsing with Auto Layout\n\n### Transforms\n\nUse the **transform** chainable properties. These are better for views constrained with Autolayout. You should not mix these with other chainable properties \n\n```objective-c\nanimatorForViewWithConstraints.transformX(50).transformScale(2).animate(1.0);\n```\n\n## \u003ca name=\"swift\"\u003e\u003c/a\u003eUsing with Swift\n\nUsing JHChainableAnimations with [Swift](https://developer.apple.com/swift/) is now a little more readable in version `2.x`. I created a separate framework for swift that provides a class called `ChainableAnimator`. This is a thin wrapper over `JHChainableAnimator` that has a slightly more readable syntax.\n\n```swift\nlet animator = ChainableAniamtor(view: myView)\nanimator.moveX(x: 50).thenAfter(t: 1.0).rotate(angle: 360).bounce.animate(t:1.0)\n```\nAll Objective-C methods map to a swift method.\n\n## \u003ca name=\"chainables\"\u003e\u003c/a\u003eChainable Properties\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003cth\u003e\nProperty\n\u003c/th\u003e\n\u003cth\u003e\nTakes a...\n\u003c/th\u003e\n\u003cth\u003e\nUsage\n\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableRect) makeFrame;\n\u003c/td\u003e\n\u003ctd\u003e\nCGRect\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeFrame(rect).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableRect) makeBounds;\n\u003c/td\u003e\n\u003ctd\u003e\nCGRect\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeBounds(rect).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableSize) makeSize;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: width, CGFloat: height)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeSize(10, 20).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainablePoint) makeOrigin;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: x, CGFloat: y)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeOrigin(10, 20).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainablePoint) makeCenter;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: x, CGFloat: y)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeCenter(10, 20).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) makeX;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeX(10).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) makeY;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeY(10).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) makeWidth;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeWidth(10).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) makeHeight;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeHeight(10).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) makeOpacity;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeOpacity(10).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableColor) makeBackground;\n\u003c/td\u003e\n\u003ctd\u003e\n(UIColor: color)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeBackground(color).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableColor) makeBorderColor;\n\u003c/td\u003e\n\u003ctd\u003e\n(UIColor: color)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeBorderColor(color).animate(1.0);\n\u003c/td\u003e\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) makeBorderWidth;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeBorderWidth(3.0).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) makeCornerRadius;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeCornerRadius(3.0).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) makeScale;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeScale(2.0).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) makeScaleX;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeScaleX(2.0).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) makeScaleY;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeScaleY(2.0).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainablePoint) makeAnchor;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: x, CGFloat: y)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.makeAnchor(0.5, 0.5).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) moveX;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.moveX(50).animate(1.0)\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) moveY;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.moveY(50).animate(1.0)\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainablePoint) moveXY;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: x, CGFloat: y)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.moveXY(100, 50).animate(1.0)\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) moveHeight;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.moveHeight(50).animate(1.0)\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) moveWidth;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.moveWidth(50).animate(1.0)\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableDegrees) rotateX;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: angle) #not radians!\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.rotateX(360).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableDegrees) rotateY;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: angle) #not radians!\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.rotateY(360).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableDegrees) rotateZ;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: angle) #not radians!\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.rotateZ(360).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainablePolarCoordinate) movePolar;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat: radius, CGFloat: angle)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.movePolar(30, 90).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableBezierPath) moveOnPath;\n\u003c/td\u003e\n\u003ctd\u003e\n(UIBezierPath *path)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.moveOnPath(path).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableBezierPath) moveAndRotateOnPath;\n\u003c/td\u003e\n\u003ctd\u003e\n(UIBezierPath *path)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.moveAndRotateOnPath(path).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableBezierPath) moveAndReverseRotateOnPath;\n\u003c/td\u003e\n\u003ctd\u003e\n(UIBezierPath *path)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.moveAndReverseRotateOnPath(path).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) transformX;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.transformX(50).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) transformX;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.transformX(50).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) transformY;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.transformY(50).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) transformZ;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.transformZ(50).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainablePoint) transformXY;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat x, CGFloat y)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.transformXY(50, 100).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) transformScale;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.transformScale(50).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) transformScaleX;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.transformScaleX(50).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableFloat) transformScaleY;\n\u003c/td\u003e\n\u003ctd\u003e\n(CGFloat f)\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.transformScaleY(50).animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n- (JHChainableAnimator *) transformIdentity;\n\u003c/td\u003e\n\u003ctd\u003e\nNothing\n\u003c/td\u003e\n\u003ctd\u003e\nanimator.transformIdentity.animate(1.0);\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n## \u003ca name=\"effects\"\u003e\u003c/a\u003eAnimation Effects\n\n\u003cimg src=\"./img/JHChainableAnimationsEffects.png\" width=\"95%\"\u003e\n\u003cimg src=\"./img/JHChainableAnimationsEasing.png\" width=\"95%\" height=\"500px\"\u003e\n\nA quick look at these funcs can be found [here](http://easings.net/)\n\nThese animation functions were taken from a cool keyframe animation library that can be found [here](https://github.com/NachoSoto/NSBKeyframeAnimation)\n\nThey are based off of JQuery easing functions that can be found [here](http://gsgd.co.uk/sandbox/jquery/easing/jquery.easing.1.3.js)\n\n## \u003ca name=\"anchors\"\u003e\u003c/a\u003eAnchoring\n\n\u003cimg src=\"./img/JHChainableAnimationsAnchors.png\" height=\"200px\"\u003e\n\nInfo on anchoring can be found [here](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreAnimation_guide/CoreAnimationBasics/CoreAnimationBasics.html#//apple_ref/doc/uid/TP40004514-CH2-SW3)\n\n\n## To Do\nI have gotten a ton of great suggestions of what to do next. If you think this is missing anything please let me know! The following is what I plan on working on in no particular order.\n\n* OSX port\n* Constraint animator\n\n## Contact Info \u0026\u0026 Contributing\n\nFeel free to email me at [jhurray33@gmail.com](mailto:jhurray33@gmail.com?subject=JHChainableAnimations). I'd love to hear your thoughts on this, or see examples where this has been used.\n\n[MIT License](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjhurray%2FJHChainableAnimations","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjhurray%2FJHChainableAnimations","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjhurray%2FJHChainableAnimations/lists"}