{"id":2366,"url":"https://github.com/cats-oss/Sica","last_synced_at":"2025-08-06T12:31:47.159Z","repository":{"id":48785568,"uuid":"138561639","full_name":"cats-oss/Sica","owner":"cats-oss","description":":deer: Simple Interface Core Animation. Run type-safe animation sequencially or parallelly","archived":false,"fork":false,"pushed_at":"2021-11-30T21:46:54.000Z","size":13096,"stargazers_count":1056,"open_issues_count":1,"forks_count":57,"subscribers_count":36,"default_branch":"master","last_synced_at":"2024-12-01T04:21:18.743Z","etag":null,"topics":["animation","carthage","cocoapods","ios","macos","swift","swift-package-manager","tvos"],"latest_commit_sha":null,"homepage":"","language":"Swift","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/cats-oss.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":"2018-06-25T07:55:06.000Z","updated_at":"2024-10-03T01:51:16.000Z","dependencies_parsed_at":"2022-07-26T00:47:00.258Z","dependency_job_id":null,"html_url":"https://github.com/cats-oss/Sica","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cats-oss%2FSica","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cats-oss%2FSica/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cats-oss%2FSica/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cats-oss%2FSica/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cats-oss","download_url":"https://codeload.github.com/cats-oss/Sica/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228740029,"owners_count":17965180,"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","carthage","cocoapods","ios","macos","swift","swift-package-manager","tvos"],"created_at":"2024-01-05T20:16:12.028Z","updated_at":"2024-12-09T13:30:34.536Z","avatar_url":"https://github.com/cats-oss.png","language":"Swift","readme":"# Simple Interface Core Animation\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"./resources/logo.png\" alt=\"Sica\" width=\"70%\" height=\"70%\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"http://img.shields.io/badge/platform-iOS | tvOS | macOS-blue.svg?style=flat\" alt=\"Platform\" /\u003e\n  \u003ca href=\"https://developer.apple.com/swift\"\u003e\n    \u003cimg src=\"http://img.shields.io/badge/Swift-4.1%20|%204.2|%205.0-brightgreen.svg?style=flat\" alt=\"Language\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/Carthage/Carthage\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat\" alt=\"Carthage\" /\u003e\n  \u003c/a\u003e\n  \u003cbr /\u003e\n  \u003ca href=\"https://github.com/apple/swift-package-manager\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg?style=flat\" alt=\"Swift Package Manager\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://cocoapods.org/pods/Sica\"\u003e\n    \u003cimg src=\"https://img.shields.io/cocoapods/v/Sica.svg?style=flat\" alt=\"Version\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://cocoapods.org/pods/Sica\"\u003e\n    \u003cimg src=\"https://img.shields.io/cocoapods/l/Sica.svg?style=flat\" alt=\"License\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\nSica can execute various animations sequentially or parallelly.\n\n## Features\n- Animation with duration and delay\n- parallel / sequence animation\n- Easings\n- Springs\n- Transition\n\n## Requirements\n- Xcode 9.3 or greater\n- iOS 9 or greater\n- tvOS 10.0 or greater\n- macOS 10.11 or greater\n- Swift 4.2 (since 0.3.4)\n\n\n## Installation\n\n### Carthage\n\nIf you’re using [Carthage](https://github.com/Carthage/Carthage), simply add\nSica to your `Cartfile`:\n\n```ruby\ngithub \"cats-oss/Sica\"\n```\n\n### CocoaPods\n\nSica is available through [CocoaPods](https://cocoapods.org). To instal\nit, simply add the following line to your Podfile:\n\n```ruby\npod 'Sica'\n```\n\n### Swift Package Manager\nSica is available through `SwiftPM`, create ` Package.swift` and add `dependencies` value\n```Package.swift\ndependencies: [\n    .package(url: \"https://github.com/cats-oss/Sica.git\", from: \"0.4.1\")\n]\n```\nSee also: [GitHub - j-channings/swift-package-manager-ios: Example of how to use SPM v4 to manage iOS dependencies](https://github.com/j-channings/swift-package-manager-ios)\n\n## Usage\n\n### Sample Animation\n\n#### Sequence Animation\nIf you set `.sequence`, sequence animation is shown.\n```swift\nlet animator = Animator(view: sampleView)\nanimator\n    .addBasicAnimation(keyPath: .positionX, from: 50, to: 150, duration: 2, timingFunction: .easeOutExpo)\n    .addSpringAnimation(keyPath: .boundsSize, from: sampleView.frame.size, to: CGSize(width: 240, height: 240), damping: 12, mass: 1, stiffness: 240, initialVelocity: 0, duration: 1)\n    .run(type: .sequence)\n```\n![SequenceAnimation](resources/sequenceAnimation.gif)\n\n\n#### Parallel Animation\nIf you set `.parallel`, parallel animation is shown.\n```swift\nlet animator = Animator(view: sampleView)\nanimator\n    .addBasicAnimation(keyPath: .positionX, from: 50, to: 150, duration: 5, timingFunction: .easeOutExpo)\n    .addBasicAnimation(keyPath: .transformRotationZ, from: 0, to: CGFloat.pi, duration: 3, timingFunction: .easeOutExpo)\n    .run(type: .parallel)\n```\n![ParallelAnimation](resources/parallelAnimation.gif)\n\n\n\n#### Forever Animation\nIf you set `forever` before calling `run`, forever animation is shown.\n```swift\nlet animator = Animator(view: sampleView)\nanimator\n    .addBasicAnimation(keyPath: .positionX, from: 50, to: 150, duration: 2, timingFunction: .easeOutExpo)\n    .addBasicAnimation(keyPath: .positionX, from: 150, to: 50, duration: 2, timingFunction: .easeOutExpo)\n    .forever(autoreverses: false)\n    .run(type: .sequence)\n```\n![Forever](resources/forever.gif)\n\n#### Cancel\nIf you want to cancel animation, you should call `cancel`.\n```swift\nlet animator = Animator(view: sampleView)\n/*\nAdd animation and run\n*/\nanimator.cancel() // Animation cancel\n```\n\n#### Remove Added Animations\nIf you call `run` and then you call add animation method, no animation will be added.\nIf you use animator again, you call `removeAll` before `addBasicAnimation` or `addSpringAnimation` or `addTransitionAnimation`.\n```swift\nlet animator = Animator(view: sampleView)\n/*\nAdd animation and run\n*/\n\n// Bad\nanimator.addBasicAnimation() // 🙅 you can't add animation\n\n// Good\nanimator.removeAll()\n        .addBasicAnimation() // 🙆 You can add animation.\n```\n\n\n## Functions\n### Add Animation\n```swift\n    public func addBasicAnimation\u003cT\u003e(keyPath: Sica.AnimationKeyPath\u003cT\u003e, from: T, to: T, duration: Double, delay: Double = default, timingFunction: Sica.TimingFunction = default) -\u003e Self where T : AnimationValueType\n    public func addSpringAnimation\u003cT\u003e(keyPath: Sica.AnimationKeyPath\u003cT\u003e, from: T, to: T, damping: CGFloat, mass: CGFloat, stiffness: CGFloat, initialVelocity: CGFloat, duration: Double, delay: Double = default, timingFunction: Sica.TimingFunction = default) -\u003e Self where T : AnimationValueType\n    public func addTransitionAnimation(startProgress: Float, endProgress: Float, type: Sica.Transition, subtype: Sica.TransitionSub, duration: Double, delay: Double = default, timingFunction: Sica.TimingFunction = default) -\u003e Self\n```\n\n### Add Animation Option\n```swift\n    public func delay(_ delay: Double) -\u003e Self\n    public func forever(autoreverses: Bool = default) -\u003e Self\n```\n\n### Animation Operation\n```swift\n    public func run(type: Sica.Animator.AnimationPlayType, isRemovedOnCompletion: Bool = default, completion: (() -\u003e Swift.Void)? = default)\n    public func cancel()\n    public func removeAll() -\u003e Self\n```\n\n## Extensions\n\nYou can access sica property in `UIView` and `CALayer`.\n\n```swift\nlet view = UIView(frame: ...)\nview.sica\n    .addBasicAnimation(keyPath: .positionX, from: 50, to: 150, duration: 2, timingFunction: .easeOutExpo)\n    .run(type: .sequence)\n```\n\n```swift\nlet layer = CALayer()\nlayer.sica\n    .addBasicAnimation(keyPath: .positionX, from: 50, to: 150, duration: 2, timingFunction: .easeOutExpo)\n    .run(type: .sequence)\n```\n\n## Support\n\n### Animation\n- CABasicAnimation\n- CATransition\n- CASpringAnimation\n\n### AnimationPlayType\nyou can choose animation play type\n- run animation sequentially\n- run animation parallelly\n\n### EasingFunctions\nyou can choose various timing functions\n\n![EasingFunctions](resources/EasingFunctions.gif)\n\n### KeyPaths Table\n|Sica|KeyPath|\n|:-:|:-:|\n|`.anchorPoint`|`anchorPoint`|\n|`.backgroundColor`|`backgroundColor`|\n|`.borderColor`|`borderColor`|\n|`.borderWidth`|`borderWidth`|\n|`.bounds`|`bounds`|\n|`.contents`|`contents`|\n|`.contentsRect`|`contentsRect`|\n|`.cornerRadius`|`cornerRadius`|\n|`.filters`|`filters`|\n|`.frame`|`frame`|\n|`.hidden`|`hidden`|\n|`.mask`|`mask`|\n|`.masksToBounds`|`masksToBounds`|\n|`.opacity`|`opacity`|\n|`.path`|`path`|\n|`.position`|`position`|\n|`.shadowColor`|`shadowColor`|\n|`.shadowOffset`|`shadowOffset`|\n|`.shadowOpacity`|`shadowOpacity`|\n|`.shadowPath`|`shadowPath`|\n|`.shadowRadius`|`shadowRadius`|\n|`.sublayers`|`sublayers`|\n|`.sublayerTransform`|`sublayerTransform`|\n|`.transform`|`transform`|\n|`.zPosition`|`zPosition`|\n\n#### Anchor Point\n|Sica|KeyPath|\n|:-:|:-:|\n|`.anchorPointX`|`anchorPoint.x`|\n|`.anchorPointy`|`anchorPoint.y`|\n\n#### Bounds\n|Sica|KeyPath|\n|:-:|:-:|\n|`.boundsOrigin`|`bounds.origin`|\n|`.boundsOriginX`|`bounds.origin.x`|\n|`.boundsOriginY`|`bounds.origin.y`|\n|`.boundsSize`|`bounds.size`|\n|`.boundsSizeWidth`|`bounds.size.width`|\n|`.boundsSizeHeight`|`bounds.size.height`|\n\n#### Contents\n|Sica|KeyPath|\n|:-:|:-:|\n|`.contentsRectOrigin`|`contentsRect.origin`|\n|`.contentsRectOriginX`|`contentsRect.origin.x`|\n|`.contentsRectOriginY`|`contentsRect.origin.y`|\n|`.contentsRectSize`|`contentsRect.size`|\n|`.contentsRectSizeWidth`|`contentsRect.size.width`|\n|`.contentsRectSizeHeight`|`contentsRect.size.height`|\n\n#### Frame\n|Sica|KeyPath|\n|:-:|:-:|\n|`.frameOrigin`|`frame.origin`|\n|`.frameOriginX`|`frame.origin.x`|\n|`.frameOriginY`|`frame.origin.y`|\n|`.frameSize`|`frame.size`|\n|`.frameSizeWidth`|`frame.size.width`|\n|`.frameSizeHeight`|`frame.size.height`|\n\n#### Position\n|Sica|KeyPath|\n|:-:|:-:|\n|`.positionX`|`position.x`|\n|`.positionY`|`position.y`|\n\n\n#### Shadow Offset\n|Sica|KeyPath|\n|:-:|:-:|\n|`.shadowOffsetWidth`|`shadowOffset.width`|\n|`.shadowOffsetHeight`|`shadowOffset.height`|\n\n#### Sublayer Transform\n|Sica|KeyPath|\n|:-:|:-:|\n|`.sublayerTransformRotationX`|`sublayerTransform.rotation.x`|\n|`.sublayerTransformRotationY`|`sublayerTransform.rotation.y`|\n|`.sublayerTransformRotationZ`|`sublayerTransform.rotation.z`|\n|`.sublayerTransformScaleX`|`sublayerTransform.scale.x`|\n|`.sublayerTransformScaleY`|`sublayerTransform.scale.y`|\n|`.sublayerTransformScaleZ`|`sublayerTransform.scale.z`|\n|`.sublayerTransformTranslationX`|`sublayerTransform.translation.x`|\n|`.sublayerTransformTranslationY`|`sublayerTransform.translation.y`|\n|`.sublayerTransformTranslationZ`|`sublayerTransform.translation.z`|\n\n#### Transform\n|Sica|KeyPath|\n|:-:|:-:|\n|`.transformRotationX`|`transform.rotation.x`|\n|`.transformRotationY`|`transform.rotation.y`|\n|`.transformRotationZ`|`transform.rotation.z`|\n|`.transformScaleX`|`transform.scale.x`|\n|`.transformScaleY`|`transform.scale.y`|\n|`.transformScaleZ`|`transform.scale.z`|\n|`.transformTranslationX`|`transform.translation.x`|\n|`.transformTranslationY`|`transform.translation.y`|\n|`.transformTranslationZ`|`transform.translation.z`|\n\n\n## License\nSica is available under the MIT license. See the [LICENSE file](https://github.com/cats-oss/Sica/blob/master/LICENSE) for more info.\n","funding_links":[],"categories":["UI","Libs","Swift","HarmonyOS","Animation [🔝](#readme)"],"sub_categories":["Animation","Windows Manager"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcats-oss%2FSica","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcats-oss%2FSica","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcats-oss%2FSica/lists"}