{"id":2350,"url":"https://github.com/yapstudios/YapAnimator","last_synced_at":"2025-08-06T12:31:56.473Z","repository":{"id":44392502,"uuid":"91012013","full_name":"yapstudios/YapAnimator","owner":"yapstudios","description":"Your fast and friendly physics-based animation system.","archived":false,"fork":false,"pushed_at":"2021-06-10T21:50:02.000Z","size":390,"stargazers_count":1939,"open_issues_count":5,"forks_count":78,"subscribers_count":41,"default_branch":"master","last_synced_at":"2024-11-30T10:05:30.267Z","etag":null,"topics":["animation","design","ios","mac","macos","macosx","motion","physics-simulation","swift"],"latest_commit_sha":null,"homepage":"https://yapstudios.com","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yapstudios.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":"2017-05-11T18:37:32.000Z","updated_at":"2024-11-19T07:04:15.000Z","dependencies_parsed_at":"2022-07-14T21:16:51.901Z","dependency_job_id":null,"html_url":"https://github.com/yapstudios/YapAnimator","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yapstudios%2FYapAnimator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yapstudios%2FYapAnimator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yapstudios%2FYapAnimator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yapstudios%2FYapAnimator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yapstudios","download_url":"https://codeload.github.com/yapstudios/YapAnimator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228587307,"owners_count":17941443,"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":["animation","design","ios","mac","macos","macosx","motion","physics-simulation","swift"],"created_at":"2024-01-05T20:16:11.546Z","updated_at":"2024-12-09T13:30:35.201Z","avatar_url":"https://github.com/yapstudios.png","language":"Swift","readme":"![YapAnimatorLogo](Docs/header.gif)\n\n**YapAnimator** is your fast and friendly physics-based animation system. YapAnimator was built with ease-of-use in mind, keeping *you* sane and your designer very, *very* happy. All animations are interruptable, include completion blocks, and allow you to apply forces to them (e.g. adding the velocity from a gesture in a transition). We've included `Animatable` protocol conformance for some commonly animated types (`CG` types), but it's really easy to add conformance to any other type. **You can animate anything** that you can represent and compose with an array of `Double`s — view properties, music volume, morphing between bezier paths, colors, smoothing brush strokes, the list goes on… use your imagination!\n\n[![Build Status](https://travis-ci.org/yapstudios/YapAnimator.svg?branch=master)](https://travis-ci.org/yapstudios/YapAnimator)\n[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/YapAnimator.svg)](https://img.shields.io/cocoapods/v/YapAnimator.svg)\n[![Platform](https://img.shields.io/cocoapods/p/YapAnimator.svg?style=flat)](http://cocoadocs.org/docsets/YapAnimator)\n\n## Why use YapAnimator?\n\nBecause it's insanely easy to use and makes beautiful animations, that's why. There are other physics-based animation systems out there (e.g. UIKit's spring animations, Facebook's Pop), but they still require writing too much code, bookkeeping, and hand-holding for our taste. YapAnimator represents a distilled n-th iteration of code that we've been using in our own apps for years. We find it invaluable in our day-to-day and think that you will too.\n\n## Built-in Extensions\n\nYapAnimator comes with a handy extension bolted on to `CALayer` and `UIView`/`NSView`, providing one-liner animations under the `animatedLayer` and `animated` properties, respectively.\n\n![CircleAnimationExample](Docs/squirclemorph.gif)\n\n```swift\nfunc handle(gesture: UIPanGestureRecognizer) {\n\n\tif gesture.state == .began {\n\t\tsquircle.animated.cornerRadius.animate(to: squircle.bounds.width / 2.0)\n\t\tsquircle.animated.rotationZ.animate(to: .pi)\n\telse if gesture.state == .changed {\n\t\tsquircle.animated.position.instant(to: gesture.location(in: nil))\n\t} else if gesture.state == .ended {\n\t\tsquircle.animated.position.animate(to: self.view.center)\n\t\tsquircle.animated.cornerRadius.animate(to: 0)\n\t\tsquircle.animated.rotationZ.animate(to: 0)\n\t}\n}\n```\n\n## Custom Animators\n\nCreating a custom animator is straightforward:\n\n- `initialValue` This sets the initial value of the animator and informs it what type it will be animating.\n- `willBegin` Called just before motion starts. Return the actual value of the property that you'll be animating. This allows the animator to sync up with that value in case it was changed outside of the scope of the animator. *(optional)*\n- `eachFrame` Called each frame of the animation — this is typically where you'd apply the animator's `current.value` to the property that you're animating. You can also use it to check values to trigger other actions / animations.\n\n```swift\nframeAnimator = YapAnimator(initialValue: square.frame, willBegin: { [unowned self] in\n\treturn self.square.frame\n}, eachFrame: { [unowned self] (animator) in\n\tself.square.frame = animator.current.value\n})\n```\n\n![SquareFrameExample](Docs/squareframe.gif)\n\n```swift\nframeAnimator.bounciness = 1.5\n\nframeAnimator.animate(to: square.frame.insetBy(dx: -50, dy: -50), completion: { animator, wasInterrupted in\n\tif !wasInterrupted {\n\t\t// animate back to the original value\n\t\tanimator.animate(to: animator.current.value.insetBy(dx: 50, dy: 50))\n\t}\n})\n```\n\n## Questions?\n\nFeel free to [ask your question in an issue](https://github.com/yapstudios/YapAnimator/issues/new). We will respond there, and  amend this read me/start a wiki if the answer seems like it would benefit others.\n\n## Credits\n\nYapAnimator is owned and maintained by [Yap Studios](http://www.yapstudios.com).\n","funding_links":[],"categories":["UI","Libs","Swift","Animation [🔝](#readme)"],"sub_categories":["Animation","Other free courses"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyapstudios%2FYapAnimator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyapstudios%2FYapAnimator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyapstudios%2FYapAnimator/lists"}