The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .travis.yml
├── Cartfile.resolved
├── Carthage
    └── Build
    │   └── iOS
    │       ├── 04BF2A7D-66CE-3F86-B5F4-63F27CD81E10.bcsymbolmap
    │       ├── 606D9ABB-D3D8-36C3-86CB-C50A0CCD2B2E.bcsymbolmap
    │       ├── AD87FA74-D7DD-3D31-B584-CE1A434CDD09.bcsymbolmap
    │       ├── B0A91A2F-DEE4-33E5-9145-CE7AE04AD4B6.bcsymbolmap
    │       ├── E17F6DD3-E41B-3903-A200-819DA6E97DE1.bcsymbolmap
    │       ├── FC36580D-9EB2-3A3A-A3CD-FCD3F10DEA18.bcsymbolmap
    │       ├── Stellar.framework.dSYM
    │           └── Contents
    │           │   ├── Info.plist
    │           │   └── Resources
    │           │       └── DWARF
    │           │           └── Stellar
    │       └── Stellar.framework
    │           ├── Headers
    │               ├── Stellar-Swift.h
    │               └── Stellar.h
    │           ├── Info.plist
    │           ├── Modules
    │               ├── Stellar.swiftmodule
    │               │   ├── arm.swiftdoc
    │               │   ├── arm.swiftmodule
    │               │   ├── arm64.swiftdoc
    │               │   ├── arm64.swiftmodule
    │               │   ├── i386.swiftdoc
    │               │   ├── i386.swiftmodule
    │               │   ├── x86_64.swiftdoc
    │               │   └── x86_64.swiftmodule
    │               └── module.modulemap
    │           └── Stellar
├── LICENSE
├── Package.swift
├── README.md
├── Sources
    ├── AnimationContext.swift
    ├── AnimationSequence.swift
    ├── AnimationStep.swift
    ├── AnimationType.swift
    ├── AnimatorCoordinator.swift
    ├── AttachmentConfigurable.swift
    ├── BasicChainable.swift
    ├── BasicConfigurable.swift
    ├── CALayer+AnimateBehavior.swift
    ├── CALayer+DriveAnimationBehaviors.swift
    ├── CALayer+Stellar.swift
    ├── Chainable.swift
    ├── DriveAnimateBehaviors.swift
    ├── DynamicItem+Behavior.swift
    ├── DynamicItem.swift
    ├── DynamicItemBasic.swift
    ├── DynamicItemGravity.swift
    ├── GravityConfigurable.swift
    ├── Interpolatable.swift
    ├── Physical.swift
    ├── SnapConfigurable.swift
    ├── StepControllable.swift
    ├── TimingFunction.swift
    ├── TimingSolvable.swift
    ├── TimingType.swift
    ├── UIDynamicBehavior+Commit.swift
    ├── UIView+AnimateBehavior.swift
    ├── UIView+Stellar.swift
    ├── UnitBezier.swift
    ├── Value+Physical.swift
    └── Vectorial.swift
├── Stellar.podspec
├── StellarDemo
    ├── Stellar
    │   ├── Info.plist
    │   └── Stellar.h
    ├── StellarDemo.xcodeproj
    │   ├── project.pbxproj
    │   ├── project.xcworkspace
    │   │   ├── contents.xcworkspacedata
    │   │   └── xcuserdata
    │   │   │   └── August.xcuserdatad
    │   │   │       └── UserInterfaceState.xcuserstate
    │   ├── xcshareddata
    │   │   └── xcschemes
    │   │   │   ├── Stellar.xcscheme
    │   │   │   └── StellarDemo.xcscheme
    │   └── xcuserdata
    │   │   └── August.xcuserdatad
    │   │       ├── xcdebugger
    │   │           └── Breakpoints_v2.xcbkptlist
    │   │       └── xcschemes
    │   │           └── xcschememanagement.plist
    ├── StellarDemo
    │   ├── AppDelegate.swift
    │   ├── Assets.xcassets
    │   │   └── AppIcon.appiconset
    │   │   │   └── Contents.json
    │   ├── Ball.swift
    │   ├── Base.lproj
    │   │   ├── LaunchScreen.storyboard
    │   │   └── Main.storyboard
    │   ├── Example1ViewController.swift
    │   ├── Example2ViewController.swift
    │   ├── Example3ViewController.swift
    │   ├── Example4ViewController.swift
    │   ├── Example5ViewController.swift
    │   ├── Example6ViewController.swift
    │   ├── Example7ViewController.swift
    │   ├── Example8ViewController.swift
    │   ├── Info.plist
    │   ├── LiquidView.swift
    │   └── MyPlayground.playground
    │   │   ├── Contents.swift
    │   │   ├── Sources
    │   │       ├── Ball.swift
    │   │       └── Sources
    │   │       │   ├── AnimationContext.swift
    │   │       │   ├── AnimationSequence.swift
    │   │       │   ├── AnimationStep.swift
    │   │       │   ├── AnimationType.swift
    │   │       │   ├── AnimatorCoordinator.swift
    │   │       │   ├── AttachmentConfigurable.swift
    │   │       │   ├── BasicChainable.swift
    │   │       │   ├── BasicConfigurable.swift
    │   │       │   ├── CALayer+AnimateBehavior.swift
    │   │       │   ├── CALayer+DriveAnimationBehaviors.swift
    │   │       │   ├── CALayer+Stellar.swift
    │   │       │   ├── Chainable.swift
    │   │       │   ├── DriveAnimateBehaviors.swift
    │   │       │   ├── DynamicItem+Behavior.swift
    │   │       │   ├── DynamicItem.swift
    │   │       │   ├── DynamicItemBasic.swift
    │   │       │   ├── DynamicItemGravity.swift
    │   │       │   ├── GravityConfigurable.swift
    │   │       │   ├── Interpolatable.swift
    │   │       │   ├── Physical.swift
    │   │       │   ├── SnapConfigurable.swift
    │   │       │   ├── StepControllable.swift
    │   │       │   ├── TimingFunction.swift
    │   │       │   ├── TimingSolvable.swift
    │   │       │   ├── TimingType.swift
    │   │       │   ├── UIDynamicBehavior+Commit.swift
    │   │       │   ├── UILabel+Stellar.swift
    │   │       │   ├── UITextView+Stellar.swift
    │   │       │   ├── UIView+AnimateBehavior.swift
    │   │       │   ├── UIView+FileConfigurable.swift
    │   │       │   ├── UIView+Stellar.swift
    │   │       │   ├── UnitBezier.swift
    │   │       │   ├── Value+Physical.swift
    │   │       │   └── Vectorial.swift
    │   │   ├── contents.xcplayground
    │   │   └── timeline.xctimeline
    ├── StellarDemoTests
    │   ├── Info.plist
    │   └── StellarDemoTests.swift
    ├── StellarDemoUITests
    │   ├── Info.plist
    │   └── StellarDemoUITests.swift
    └── StellarTests
    │   ├── Info.plist
    │   └── StellarTests.swift
├── attachmentCurve.gif
├── balls.gif
├── basicCurve.gif
├── example4.gif
├── example5.gif
├── example6.gif
├── gravityCurve.gif
├── layers.gif
├── lines.gif
├── pushCurve.gif
├── snapCurve.gif
└── title.png


/.travis.yml:
--------------------------------------------------------------------------------
 1 | language: Swift
 2 | xcode_project: StellarDemo.xcodeproj
 3 | before_install:
 4 |   - brew update
 5 |   - brew install carthage
 6 | install: carthage bootstrap --verbose
 7 | xcode_scheme: [Stellar, StellarDemo]
 8 | xcode_sdk: [iphonesimulator8.3]
 9 | osx_image: xcode7.3.1
10 | 
11 | matrix:
12 |   exclude:
13 |     - xcode_scheme: Stellar
14 |       xcode_sdk: iphonesimulator8.3
15 | 
16 | branches:
17 |   only:
18 |     - master
19 | 


--------------------------------------------------------------------------------
/Cartfile.resolved:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/Cartfile.resolved


--------------------------------------------------------------------------------
/Carthage/Build/iOS/B0A91A2F-DEE4-33E5-9145-CE7AE04AD4B6.bcsymbolmap:
--------------------------------------------------------------------------------
1 | BCSymbolMap Version: 2.0
2 | Apple LLVM version 8.1.0 (clang-802.0.41)
3 | /Users/baidu/Library/Developer/Xcode/DerivedData/StellarDemo-bdrzozoakxfmsidxdfvqkvpaffyx/Build/Intermediates/StellarDemo.build/Release-iphoneos/Stellar.build/DerivedSources/Stellar_vers.c
4 | /Users/baidu/MyVendors/Stellar/StellarDemo
5 | 


--------------------------------------------------------------------------------
/Carthage/Build/iOS/E17F6DD3-E41B-3903-A200-819DA6E97DE1.bcsymbolmap:
--------------------------------------------------------------------------------
1 | BCSymbolMap Version: 2.0
2 | Apple LLVM version 8.1.0 (clang-802.0.41)
3 | /Users/baidu/Library/Developer/Xcode/DerivedData/StellarDemo-bdrzozoakxfmsidxdfvqkvpaffyx/Build/Intermediates/StellarDemo.build/Release-iphoneos/Stellar.build/DerivedSources/Stellar_vers.c
4 | /Users/baidu/MyVendors/Stellar/StellarDemo
5 | 


--------------------------------------------------------------------------------
/Carthage/Build/iOS/Stellar.framework.dSYM/Contents/Info.plist:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 3 | <plist version="1.0">
 4 | 	<dict>
 5 | 		<key>CFBundleDevelopmentRegion</key>
 6 | 		<string>English</string>
 7 | 		<key>CFBundleIdentifier</key>
 8 | 		<string>com.apple.xcode.dsym.AR.Stellar</string>
 9 | 		<key>CFBundleInfoDictionaryVersion</key>
10 | 		<string>6.0</string>
11 | 		<key>CFBundlePackageType</key>
12 | 		<string>dSYM</string>
13 | 		<key>CFBundleSignature</key>
14 | 		<string>????</string>
15 | 		<key>CFBundleShortVersionString</key>
16 | 		<string>1.0</string>
17 | 		<key>CFBundleVersion</key>
18 | 		<string>1</string>
19 | 	</dict>
20 | </plist>
21 | 


--------------------------------------------------------------------------------
/Carthage/Build/iOS/Stellar.framework.dSYM/Contents/Resources/DWARF/Stellar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/Carthage/Build/iOS/Stellar.framework.dSYM/Contents/Resources/DWARF/Stellar


--------------------------------------------------------------------------------
/Carthage/Build/iOS/Stellar.framework/Headers/Stellar.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  Stellar.h
 3 | //  Stellar
 4 | //
 5 | //  Created by AugustRush on 6/6/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | //! Project version number for Stellar.
12 | FOUNDATION_EXPORT double StellarVersionNumber;
13 | 
14 | //! Project version string for Stellar.
15 | FOUNDATION_EXPORT const unsigned char StellarVersionString[];
16 | #import "Stellar-Swift.h"
17 | // In this header, you should import all the public headers of your framework using statements like #import <Stellar/PublicHeader.h>
18 | 
19 | 
20 | 


--------------------------------------------------------------------------------
/Carthage/Build/iOS/Stellar.framework/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/Carthage/Build/iOS/Stellar.framework/Info.plist


--------------------------------------------------------------------------------
/Carthage/Build/iOS/Stellar.framework/Modules/Stellar.swiftmodule/arm.swiftdoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/Carthage/Build/iOS/Stellar.framework/Modules/Stellar.swiftmodule/arm.swiftdoc


--------------------------------------------------------------------------------
/Carthage/Build/iOS/Stellar.framework/Modules/Stellar.swiftmodule/arm.swiftmodule:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/Carthage/Build/iOS/Stellar.framework/Modules/Stellar.swiftmodule/arm.swiftmodule


--------------------------------------------------------------------------------
/Carthage/Build/iOS/Stellar.framework/Modules/Stellar.swiftmodule/arm64.swiftdoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/Carthage/Build/iOS/Stellar.framework/Modules/Stellar.swiftmodule/arm64.swiftdoc


--------------------------------------------------------------------------------
/Carthage/Build/iOS/Stellar.framework/Modules/Stellar.swiftmodule/arm64.swiftmodule:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/Carthage/Build/iOS/Stellar.framework/Modules/Stellar.swiftmodule/arm64.swiftmodule


--------------------------------------------------------------------------------
/Carthage/Build/iOS/Stellar.framework/Modules/Stellar.swiftmodule/i386.swiftdoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/Carthage/Build/iOS/Stellar.framework/Modules/Stellar.swiftmodule/i386.swiftdoc


--------------------------------------------------------------------------------
/Carthage/Build/iOS/Stellar.framework/Modules/Stellar.swiftmodule/i386.swiftmodule:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/Carthage/Build/iOS/Stellar.framework/Modules/Stellar.swiftmodule/i386.swiftmodule


--------------------------------------------------------------------------------
/Carthage/Build/iOS/Stellar.framework/Modules/Stellar.swiftmodule/x86_64.swiftdoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/Carthage/Build/iOS/Stellar.framework/Modules/Stellar.swiftmodule/x86_64.swiftdoc


--------------------------------------------------------------------------------
/Carthage/Build/iOS/Stellar.framework/Modules/Stellar.swiftmodule/x86_64.swiftmodule:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/Carthage/Build/iOS/Stellar.framework/Modules/Stellar.swiftmodule/x86_64.swiftmodule


--------------------------------------------------------------------------------
/Carthage/Build/iOS/Stellar.framework/Modules/module.modulemap:
--------------------------------------------------------------------------------
 1 | framework module Stellar {
 2 |   umbrella header "Stellar.h"
 3 | 
 4 |   export *
 5 |   module * { export * }
 6 | }
 7 | 
 8 | module Stellar.Swift {
 9 |     header "Stellar-Swift.h"
10 | }
11 | 


--------------------------------------------------------------------------------
/Carthage/Build/iOS/Stellar.framework/Stellar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/Carthage/Build/iOS/Stellar.framework/Stellar


--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
 1 | The MIT License (MIT)
 2 | 
 3 | Copyright (c) 2016 
 4 | 
 5 | Permission is hereby granted, free of charge, to any person obtaining a copy
 6 | of this software and associated documentation files (the "Software"), to deal
 7 | in the Software without restriction, including without limitation the rights
 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 | 
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 | 
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 | 
23 | 


--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
 1 | //EasyLayout
 2 | //Copyright (c) 2016
 3 | //
 4 | //Permission is hereby granted, free of charge, to any person obtaining a copy
 5 | //of this software and associated documentation files (the "Software"), to deal
 6 | //in the Software without restriction, including without limitation the rights
 7 | //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 8 | //copies of the Software, and to permit persons to whom the Software is
 9 | //furnished to do so, subject to the following conditions:
10 | //
11 | //The above copyright notice and this permission notice shall be included in all
12 | //copies or substantial portions of the Software.
13 | //
14 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | //SOFTWARE.
21 | 
22 | import PackageDescription
23 | 
24 | let package = Package(name: "Stellar")


--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
  1 | <img src="https://github.com/AugustRush/Stellar/blob/master/title.png">
  2 | 
  3 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg)](https://github.com/Carthage/Carthage)
  4 | ![](https://img.shields.io/cocoapods/v/Stellar.svg?label=Current%20Release) [![Packagist](https://img.shields.io/packagist/l/doctrine/orm.svg?maxAge=2592000?style=flat-square)](https://github.com/AugustRush/Stellar/blob/master/LICENSE.md) [![codebeat badge](https://codebeat.co/badges/e91a2d21-b20c-4b2b-a782-e0e2ecd65063)](https://codebeat.co/projects/github-com-augustrush-stellar) [![Travis branch](https://img.shields.io/travis/rust-lang/rust/master.svg?maxAge=2592000?style=flat-square)]() [![Cocoapods badge](https://img.shields.io/cocoapods/p/Stellar.svg?maxAge=2592000?style=flat-square)]()
  5 | 
  6 | A fantastic Physical animation library for swift(Not Just Spring !!!), it is base on UIDynamic and extension to it, friendly APIs make you use it or custom your own animation very easily!
  7 | 
  8 | ## Support
  9 | 
 10 | ### Integration
 11 | #### Cocoapods(iOS 8+)
 12 | * You can use [Cocoapods](https://cocoapods.org/) to install Stellar by adding it to your Podfile:
 13 | 
 14 | ```
 15 | platform :ios, '8.0'
 16 | use_frameworks!
 17 | 
 18 | target 'YourApp' do
 19 |     pod 'Stellar', :git => 'https://github.com/AugustRush/Stellar.git'
 20 | end
 21 | ```
 22 | 
 23 | #### Carthage (iOS 8+)
 24 | * You can use [Carthage](https://github.com/Carthage/Carthage) to install Stellar by adding it to your Cartfile:
 25 | 
 26 | ```
 27 | github "AugustRush/Stellar"
 28 | ```
 29 | 
 30 | #### Manually (iOS 8+)
 31 | To use this library in your project manually you may:
 32 | 
 33 | - for Projects, just drag Stellar [Sources](https://github.com/AugustRush/Stellar/tree/master/Sources) to the project tree
 34 | - for Workspaces, include the whole StellarDemo.xcodeproj
 35 | 
 36 | ### Features
 37 | ```
 38 | - View's Animation
 39 | - Layer's Animation
 40 | - Chainable (every step can be observed)
 41 | - File configurable (come soon)
 42 | ```
 43 | ### Animations
 44 | ```
 45 | - Basic
 46 | - Gravity
 47 | - Snap
 48 | - Attachment
 49 | - Push
 50 | - Collsion(come soon)
 51 | ```
 52 | ### Animatable type
 53 | ```
 54 | - Float
 55 | - CGFloat
 56 | - Double
 57 | - CGSize
 58 | - CGPoint
 59 | - CGRect
 60 | - UIColor
 61 | - ......(Any Intrpolatable)
 62 | ```
 63 | ### Easing Curve (Base Animation)
 64 | 
 65 | ```swift
 66 | - Default
 67 | - EaseIn
 68 | - EaseOut
 69 | - EaseInEaseOut
 70 | - Linear
 71 | - SwiftOut
 72 | - BackEaseIn
 73 | - BackEaseOut
 74 | - BackEaseInOut
 75 | - BounceOut
 76 | - Sine
 77 | - Circ
 78 | - ExponentialIn
 79 | - ExponentialOut
 80 | - ElasticIn
 81 | - ElasticOut
 82 | - BounceReverse
 83 | - Custom(Double, Double, Double, Double)
 84 | ```
 85 | ## On display
 86 | 
 87 | #### Funny demo's gif(s)
 88 | <img src="https://github.com/AugustRush/Stellar/blob/master/example5.gif" width="320">
 89 | <img src="https://github.com/AugustRush/Stellar/blob/master/balls.gif" width="320">
 90 | <img src="https://github.com/AugustRush/Stellar/blob/master/layers.gif" width="320">
 91 | <img src="https://github.com/AugustRush/Stellar/blob/master/example6.gif" width="320">
 92 | 
 93 | #### Chainable 
 94 | 
 95 | 1) Common</br>
 96 | 
 97 | <img src="https://github.com/AugustRush/Stellar/blob/master/lines.gif" width="200">
 98 | 
 99 | ``` swift
100 | for (index,line) in leftLines.enumerate() {
101 |     let delay = Double(index) * 0.2
102 |     
103 |     line.moveX(200).duration(2).easing(.SwiftOut).delay(delay)
104 |         .then().moveX(-200).rotateY(1.43).easing(.SwiftOut)
105 |         .makeColor(UIColor.greenColor()).repeatCount(100)
106 |         .autoreverses().duration(2).animate()
107 |  }
108 |         
109 |  for (index,line) in rightLines.enumerate() {
110 |     let delay = Double(index) * 0.2
111 |     
112 |     line.moveX(-200).duration(2).easing(.SwiftOut).delay(delay)
113 |         .then().moveX(200).rotateY(1.43).easing(.SwiftOut)
114 |         .makeColor(UIColor.purpleColor()).repeatCount(100)
115 |         .autoreverses().duration(2).animate()
116 |  }
117 | ```
118 | 
119 | 2) every step completion observable </br>
120 | 
121 | <img src="https://github.com/AugustRush/Stellar/blob/master/example4.gif" width="200">
122 | 
123 | ``` swift
124 | animateView.makeSize(CGSizeMake(50, 150)).snap(0.3).completion({
125 |                 print("First step")
126 |             })
127 |             .then().moveX(-100).moveY(-50).anchorPoint(CGPointMake(1, 1)).duration(1).completion({
128 |                 print("Second step!")
129 |             })
130 |             .then().rotate(CGFloat(M_PI)).attachment(0.3, frequency: 0.8).completion({
131 |                 print("Third step!")
132 |             })
133 |             .then().moveY(500).completion({
134 |                 print("last step, all completion")
135 |             })
136 |             .animate()
137 | ```
138 | 
139 | ----------
140 | #### Snap Curve
141 | <img src="https://github.com/AugustRush/Stellar/blob/master/snapCurve.gif">
142 | 
143 | #### Attachment Curve
144 | <img src="https://github.com/AugustRush/Stellar/blob/master/attachmentCurve.gif">
145 | 
146 | #### Gravity Curve
147 | <img src="https://github.com/AugustRush/Stellar/blob/master/gravityCurve.gif">
148 | 
149 | #### Push Curve
150 | <img src="https://github.com/AugustRush/Stellar/blob/master/pushCurve.gif">
151 | 
152 | #### Basic Curve
153 | <img src="https://github.com/AugustRush/Stellar/blob/master/basicCurve.gif">
154 | 
155 | ### To do
156 | ```
157 | - File configurable
158 | - Easily Interactive Animations
159 | - Collision
160 | - Mutilple View/Layer performance
161 | - More demos
162 | ```
163 | ### Licence
164 | ```
165 | Copyright (c) 2016 
166 | 
167 | Permission is hereby granted, free of charge, to any person obtaining a copy
168 | of this software and associated documentation files (the "Software"), to deal
169 | in the Software without restriction, including without limitation the rights
170 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
171 | copies of the Software, and to permit persons to whom the Software is
172 | furnished to do so, subject to the following conditions:
173 | 
174 | The above copyright notice and this permission notice shall be included in all
175 | copies or substantial portions of the Software.
176 | 
177 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
178 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
179 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
180 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
181 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
182 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
183 | SOFTWARE.
184 | ```
185 | 


--------------------------------------------------------------------------------
/Sources/AnimationContext.swift:
--------------------------------------------------------------------------------
  1 | //Copyright (c) 2016
  2 | //
  3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  4 | //
  5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  6 | //
  7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  8 | 
  9 | import UIKit
 10 | 
 11 | internal class AnimationContext: NSObject, UIDynamicAnimatorDelegate, AnimationSequenceDelegate {
 12 |     fileprivate weak var object: DriveAnimateBehaviors!
 13 |     fileprivate var mutipleSequences = [AnimationSequence]()
 14 |     
 15 |     //MARK: init method
 16 |     init(object: DriveAnimateBehaviors) {
 17 |         self.object = object
 18 |     }
 19 |     
 20 |     //MARK: public methods
 21 |     func addAnimationType(_ type: AnimationType) {
 22 |         let step = lastStep()
 23 |         step.types.append(type)
 24 |     }
 25 |     
 26 |     func changeDuration(_ d: CFTimeInterval) {
 27 |         let step = lastStep()
 28 |         step.duration = d
 29 |     }
 30 |     
 31 |     func changeDelay(_ d: CFTimeInterval) {
 32 |         let step = lastStep()
 33 |         step.delay = d
 34 |     }
 35 |     
 36 |     func changeAutoreverses(_ a: Bool) {
 37 |         let step = lastStep()
 38 |         step.autoreverses = a
 39 |     }
 40 |     
 41 |     func changeRepeatCount(_ count: Int) {
 42 |         let step = lastStep()
 43 |         step.repeatCount = count
 44 |     }
 45 |     
 46 |     func changeCompletion(_ c: @escaping () -> Void) {
 47 |         let step = lastStep()
 48 |         step.completion = c
 49 |     }
 50 |     
 51 |     func changeEasing(_ e: TimingFunctionType) {
 52 |         let step = lastStep()
 53 |         step.timing = e
 54 |     }
 55 |     
 56 |     func changeMainType(_ type: AnimationStyle) {
 57 |         let step = lastStep()
 58 |         let lastAnimationType = step.types.last
 59 |         guard let _ = lastAnimationType else {
 60 |             print("You should defined animaton first!")
 61 |             return
 62 |         }
 63 |         
 64 |         lastAnimationType!.mainType = type
 65 |     }
 66 |     
 67 |     func makeNextStep() {
 68 |         let step = AnimationStep()
 69 |         lastSequence().addStep(step)
 70 |     }
 71 |     
 72 |     @discardableResult
 73 |     func makeNextSequence() -> AnimationSequence {
 74 |         let sequence = AnimationSequence(object: self.object)
 75 |         sequence.delegate = self
 76 |         mutipleSequences.append(sequence)
 77 |         
 78 |         return sequence
 79 |     }
 80 |     
 81 |     func commit() {
 82 |         //start all sequence
 83 |         for sequence in mutipleSequences {
 84 |             sequence.start()
 85 |         }
 86 |         //make a temple sequence for next step
 87 |         makeNextSequence()
 88 |     }
 89 |     
 90 |     func removeAllRemaining() {
 91 |         for sequence in mutipleSequences {
 92 |             sequence.removeAllSteps()
 93 |         }
 94 |         mutipleSequences.removeAll()
 95 |     }
 96 |     
 97 |     
 98 |     //MARK: private methods
 99 |     
100 |     fileprivate func lastSequence() -> AnimationSequence {
101 |         var sequence = mutipleSequences.last
102 |         if sequence == nil {
103 |             sequence = makeNextSequence()
104 |         }
105 | 
106 |         return sequence!
107 |     }
108 |     
109 |     fileprivate func lastStep() -> AnimationStep {
110 |         let sequence = lastSequence()
111 |         var step = sequence.last()
112 |         if step == nil {
113 |             step = AnimationStep()
114 |             sequence.addStep(step!)
115 |         }
116 |         return step!
117 |     }
118 |     
119 |     //MARK: AnimationSequenceDelegate methods
120 |     
121 |     func animationSequenceDidComplete(_ sequence: AnimationSequence) {
122 |         let index = mutipleSequences.firstIndex(of: sequence)
123 |         if index != nil {
124 |             mutipleSequences.remove(at: index!)
125 |         }
126 |     }
127 | }
128 | 
129 | 


--------------------------------------------------------------------------------
/Sources/AnimationSequence.swift:
--------------------------------------------------------------------------------
  1 | //Copyright (c) 2016
  2 | //
  3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  4 | //
  5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  6 | //
  7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  8 | 
  9 | import UIKit
 10 | 
 11 | protocol AnimationSequenceDelegate: class {
 12 |     func animationSequenceDidComplete(_ sequence: AnimationSequence);
 13 | }
 14 | 
 15 | internal class AnimationSequence: NSObject, UIDynamicAnimatorDelegate {
 16 |     var steps: [AnimationStep] = Array()
 17 |     weak var view: DriveAnimateBehaviors!
 18 |     weak var delegate: AnimationSequenceDelegate?
 19 |     var isRuning = false
 20 |     lazy var animator: UIDynamicAnimator = {
 21 |         let animator = UIDynamicAnimator()
 22 |         animator.delegate = self
 23 |         return animator
 24 |     }()
 25 |     
 26 |     //MARK: init method
 27 |     
 28 |     init(object: DriveAnimateBehaviors) {
 29 |         self.view = object
 30 |     }
 31 |     
 32 |     //MARK: internal method
 33 |     func addStep(_ step: AnimationStep) {
 34 |         steps.append(step)
 35 |     }
 36 |     
 37 |     func last() -> AnimationStep? {
 38 |         return steps.last
 39 |     }
 40 |     
 41 |     func start() {
 42 |         if !isRuning {
 43 |             isRuning = true
 44 |             excuteFirstStepIfExist()
 45 |         }
 46 |     }
 47 |     
 48 |     func removeAllSteps() {
 49 |         steps.removeAll()
 50 |     }
 51 |     
 52 |     fileprivate func excuteFirstStepIfExist() {
 53 |         
 54 |         if self.view == nil {
 55 |             return
 56 |         }
 57 |         
 58 |         let step = steps.first
 59 |         
 60 |         if let step = step {
 61 |             //if step has no animation types it must be the last temple step
 62 |             if step.types.count == 0 {
 63 |                 steps.removeFirst()
 64 |                 popFirstStepIfExsist()
 65 |                 return
 66 |             }
 67 |             
 68 |             for type in step.types {
 69 |                 let behavior = view.behavior(forType: type, step: step)
 70 |                 animator.addBehavior(behavior)
 71 |             }
 72 |             
 73 |         } else {
 74 |             popFirstStepIfExsist()
 75 |         }
 76 |     }
 77 |     
 78 |     fileprivate func popFirstStepIfExsist() {
 79 |         if !steps.isEmpty {
 80 |             let step = steps.first!
 81 |             //excute completion
 82 |             step.completion?()
 83 |             steps.removeFirst()
 84 |         } else {
 85 |             // all steps has completion
 86 |             self.delegate?.animationSequenceDidComplete(self)
 87 |         }
 88 |     }
 89 |     
 90 |     //MARK: UIDynamicAnimatorDelegate methods
 91 |     func dynamicAnimatorDidPause(_ animator: UIDynamicAnimator) {
 92 |         animator.removeAllBehaviors()
 93 |         popFirstStepIfExsist()
 94 |         excuteFirstStepIfExist()
 95 |     }
 96 |     
 97 |     func dynamicAnimatorWillResume(_ animator: UIDynamicAnimator) {
 98 |         
 99 |     }
100 | }
101 | 


--------------------------------------------------------------------------------
/Sources/AnimationStep.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | internal class AnimationStep {
12 |     var types = [AnimationType]()
13 |     var duration: CFTimeInterval = 0.25
14 |     var timing: TimingFunctionType = .default
15 |     var delay: CFTimeInterval = 0.0
16 |     var autoreverses: Bool = false
17 |     var repeatCount: Int = 0
18 |     var completion: (() -> Void)?
19 | }
20 | 


--------------------------------------------------------------------------------
/Sources/AnimationType.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | enum AnimationSubType {
12 |     case moveX(CGFloat)
13 |     case moveY(CGFloat)
14 |     case moveXY(CGFloat,CGFloat)//Layer
15 |     case moveTo(CGPoint)
16 |     case color(UIColor)
17 |     case alpha(CGFloat)
18 |     case opacity(Float)//Layer
19 |     case rotateX(CGFloat)
20 |     case rotateY(CGFloat)
21 |     case rotate(CGFloat)
22 |     case rotateXY(CGFloat)
23 |     case width(CGFloat)
24 |     case height(CGFloat)
25 |     case size(CGSize)
26 |     case frame(CGRect)
27 |     case bounds(CGRect)
28 |     case scaleX(CGFloat)
29 |     case scaleY(CGFloat)
30 |     case scaleXY(CGFloat,CGFloat)
31 |     case cornerRadius(CGFloat)
32 |     case borderWidth(CGFloat)
33 |     case shadowRadius(CGFloat)
34 |     case zPosition(CGFloat)
35 |     case anchorPoint(CGPoint)
36 |     case anchorPointZ(CGFloat)
37 |     case shadowOffset(CGSize)
38 |     case shadowColor(UIColor)
39 |     case shadowOpacity(Float)
40 |     case tintColor(UIColor)
41 | //    UILabel,UITextView...
42 |     case textColor(UIColor)
43 | }
44 | 
45 | //temp record for animation type
46 | internal class AnimationType {
47 |     var mainType: AnimationStyle
48 |     var subType: AnimationSubType
49 |     
50 |     init (type: AnimationStyle, subType: AnimationSubType) {
51 |         self.mainType = type
52 |         self.subType = subType
53 |     }
54 | }
55 | 


--------------------------------------------------------------------------------
/Sources/AnimatorCoordinator.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | internal class AnimatorCoordinator: NSObject, UIDynamicAnimatorDelegate {
12 |     static let shared = AnimatorCoordinator()
13 |     fileprivate var activedAnimators: [UIDynamicAnimator] = Array()
14 |     fileprivate var basicAnimator = UIDynamicAnimator()
15 |     
16 |     //MARK: public methods    
17 |     func addBasicBehavior(_ b: UIDynamicBehavior) {
18 |         basicAnimator.addBehavior(b)
19 |     }
20 |     func addBehavior(_ b: UIDynamicBehavior) {
21 |         addBehaviors([b])
22 |     }
23 |     
24 |     func addBehaviors(_ behaviors: [UIDynamicBehavior]) {
25 |         
26 |         let animator = activedAnimators.last
27 |         for b in behaviors {
28 |             
29 |             if let exsist = animator {
30 |                 switch b {
31 |                 case b as UIGravityBehavior:
32 |                     fallthrough
33 |                 case b as UICollisionBehavior:
34 |                     createAnimator(b)
35 |                 default:
36 |                     exsist.addBehavior(b)
37 |                 }
38 |    
39 |             } else {
40 |                 createAnimator(b)
41 |             }
42 |         }
43 |     }
44 |     
45 |     fileprivate func createAnimator(_ behavior: UIDynamicBehavior) {
46 |         let animator = UIDynamicAnimator()
47 |         animator.delegate = self
48 |         animator.addBehavior(behavior)
49 |         activedAnimators.append(animator)
50 |     }
51 | 
52 |     
53 |     //MARK: UIDynamicAnimatorDelegate methods
54 |     
55 |     func dynamicAnimatorDidPause(_ animator: UIDynamicAnimator) {
56 |         let index = activedAnimators.firstIndex(of: animator)
57 |         activedAnimators.remove(at: index!)
58 |     }
59 |     
60 |     func dynamicAnimatorWillResume(_ animator: UIDynamicAnimator) {
61 |         //
62 |     }
63 | }
64 | 


--------------------------------------------------------------------------------
/Sources/AttachmentConfigurable.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | public protocol AttachmentConfigurable: BasicChainable {
12 |     func attachment(_ damping: CGFloat, frequency: CGFloat) -> Self
13 | }
14 | 


--------------------------------------------------------------------------------
/Sources/BasicChainable.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | public protocol BasicChainable: Chainable {
12 |     func moveX(_ increment: CGFloat) -> Self
13 |     func moveY(_ increment: CGFloat) -> Self
14 |     func moveTo(_ point: CGPoint) -> Self
15 |     func makeColor(_ color: UIColor) -> Self
16 |     func makeAlpha(_ alpha: CGFloat) -> Self
17 |     func rotate(_ z: CGFloat) -> Self
18 |     func rotateX(_ x: CGFloat) -> Self
19 |     func rotateY(_ y: CGFloat) -> Self
20 |     func rotateXY(_ xy: CGFloat) -> Self
21 |     func makeWidth(_ width: CGFloat) -> Self
22 |     func makeHeight(_ height: CGFloat) -> Self
23 |     func makeSize(_ size: CGSize) -> Self
24 |     func makeFrame(_ frame: CGRect) -> Self
25 |     func makeBounds(_ bounds: CGRect) -> Self
26 |     func scaleX(_ x: CGFloat) -> Self
27 |     func scaleY(_ y: CGFloat) -> Self
28 |     func scaleXY(_ x: CGFloat, _ y: CGFloat) -> Self
29 |     func cornerRadius(_ radius: CGFloat) -> Self
30 |     func borderWidth(_ width: CGFloat) -> Self
31 |     func shadowRadius(_ radius: CGFloat) -> Self
32 |     func zPosition(_ position: CGFloat) -> Self
33 |     func anchorPoint(_ point: CGPoint) -> Self
34 |     func anchorPointZ(_ z: CGFloat) -> Self
35 |     func shadowOffset(_ offset: CGSize) -> Self
36 |     func shadowColor(_ color: UIColor) -> Self
37 |     func shadowOpacity(_ opacity: Float) -> Self
38 |     func makeTintColor(_ color: UIColor) -> Self
39 |     func completion(_ c: @escaping () -> Void) -> Self
40 | }
41 | 


--------------------------------------------------------------------------------
/Sources/BasicConfigurable.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | public protocol BasicConfigurable: BasicChainable {
12 |     func duration(_ d: CFTimeInterval) -> Self
13 |     func easing(_ type: TimingFunctionType) -> Self
14 |     func delay(_ d: CFTimeInterval) -> Self
15 |     func reverses() -> Self
16 |     func repeatCount(_ count: Int) -> Self
17 | }
18 | 


--------------------------------------------------------------------------------
/Sources/CALayer+DriveAnimationBehaviors.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  CALayer+DriveAnimationBehaviors.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 6/21/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import Foundation
10 | 


--------------------------------------------------------------------------------
/Sources/Chainable.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | public protocol Chainable {
12 |     //Chainable methods
13 |     func then() -> Self
14 |     func animate() -> Void
15 | }
16 | 


--------------------------------------------------------------------------------
/Sources/DriveAnimateBehaviors.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  DriveAnimateBehaviors.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 6/21/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | protocol DriveAnimateBehaviors: class {
12 |     func behavior(forType type: AnimationType, step: AnimationStep) -> UIDynamicBehavior
13 | }
14 | 


--------------------------------------------------------------------------------
/Sources/DynamicItem+Behavior.swift:
--------------------------------------------------------------------------------
  1 | //Copyright (c) 2016
  2 | //
  3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  4 | //
  5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  6 | //
  7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  8 | 
  9 | import UIKit
 10 | 
 11 | enum PhysicalDirection {
 12 |     case left
 13 |     case right
 14 |     case up
 15 |     case down
 16 |     case Angle(CGFloat)
 17 |     case vector(CGFloat,CGFloat)
 18 |     
 19 |     func angle() -> CGFloat {
 20 |         switch self {
 21 |         case .Angle(let a):
 22 |             return a
 23 |         case .vector(let x, let y):
 24 |             return atan2(y, x)
 25 |         case .left:
 26 |             return atan2(0, -1)
 27 |         case .right:
 28 |             return atan2(0, 1)
 29 |         case .up: 
 30 |             return atan2(-1, 0)
 31 |         case .down: 
 32 |             return atan2(1, 0)
 33 |         }
 34 |     }
 35 | }
 36 | 
 37 | extension UIDynamicItem {
 38 |     
 39 |     //gravity
 40 |     func gravityBehavior(_ magnitude: CGFloat = 1.0, direction: PhysicalDirection = .down) -> UIGravityBehavior {
 41 |         let gravity = UIGravityBehavior()
 42 |         switch direction {
 43 |         case .Angle(let a):
 44 |             gravity.setAngle(a, magnitude: magnitude)
 45 |         case .left:
 46 |             gravity.gravityDirection = CGVector(dx: -1, dy: 0)
 47 |         case .right:
 48 |             gravity.gravityDirection = CGVector(dx: 1, dy: 0)
 49 |         case .up:
 50 |             gravity.gravityDirection = CGVector(dx: 0, dy: -1)
 51 |         case .down:
 52 |             gravity.gravityDirection = CGVector(dx: 0, dy: 1)
 53 |         case .vector(let x, let y):
 54 |             gravity.gravityDirection = CGVector(dx: x, dy: y)
 55 |         }
 56 |         gravity.magnitude = magnitude
 57 |         gravity.addItem(self)
 58 |         return gravity
 59 |     }
 60 | 
 61 |     //snap
 62 |     func snapBehavior(_ toPoint: CGPoint, damping: CGFloat = 0.5) -> UISnapBehavior {
 63 |         let snap = UISnapBehavior(item: self,snapTo: toPoint)
 64 |         snap.damping = damping
 65 |         return snap
 66 |     }
 67 |     
 68 |     //attachment
 69 |     func attachmentBehavior(_ toAnchor: CGPoint, length: CGFloat = 0.0, damping: CGFloat = 0.5, frequency: CGFloat = 1.0) -> UIAttachmentBehavior {
 70 |         let attachment = UIAttachmentBehavior(item: self,attachedToAnchor: toAnchor)
 71 |         attachment.length = length
 72 |         attachment.damping = damping
 73 |         attachment.frequency = frequency
 74 |         return attachment
 75 |     }
 76 |     
 77 |     func attachmentBehavior(_ toItem: UIDynamicItem, damping: CGFloat = 0.5, frequency: CGFloat = 1.0) -> UIAttachmentBehavior {
 78 |         let attachment = UIAttachmentBehavior(item: self,attachedTo: toItem)
 79 |         attachment.damping = damping
 80 |         attachment.frequency = frequency
 81 |         return attachment
 82 |     }
 83 |     
 84 |     func attachmentBehavior(_ toItem: UIDynamicItem, damping: CGFloat = 0.5, frequency: CGFloat = 1.0, length: CGFloat = 0.0) -> UIAttachmentBehavior {
 85 |         let attachment = UIAttachmentBehavior(item: self,attachedTo: toItem)
 86 |         attachment.damping = damping
 87 |         attachment.length = length
 88 |         attachment.frequency = frequency
 89 |         return attachment
 90 |     }
 91 |     
 92 |     //push
 93 |     func pushBehavior(_ direction: CGVector, mode:UIPushBehavior.Mode = .instantaneous, magnitude: CGFloat = 1.0) -> UIPushBehavior {
 94 |         let push = UIPushBehavior(items: [self], mode: mode)
 95 |         push.pushDirection = direction
 96 |         push.magnitude = magnitude
 97 |         return push
 98 |     }
 99 |     
100 |     func pushBehavior(_ direction: PhysicalDirection, mode:UIPushBehavior.Mode = .continuous, magnitude: CGFloat = 1.0) -> UIPushBehavior {
101 |         let push = UIPushBehavior(items: [self], mode: mode)
102 |         switch direction {
103 |         case .Angle(let a):
104 |             push.setAngle(a, magnitude: magnitude)
105 |         case .left:
106 |             push.pushDirection = CGVector(dx: -1, dy: 0)
107 |         case .right:
108 |             push.pushDirection = CGVector(dx: 1, dy: 0)
109 |         case .up:
110 |             push.pushDirection = CGVector(dx: 0, dy: -1)
111 |         case .down:
112 |             push.pushDirection = CGVector(dx: 0, dy: 1)
113 |         case .vector(let x, let y):
114 |             push.pushDirection = CGVector(dx: x, dy: y)
115 |         }
116 |         
117 |         push.magnitude = magnitude
118 |         return push
119 |     }
120 | 
121 |     
122 |     func pushBehavior(_ angle: CGFloat, mode:UIPushBehavior.Mode = .instantaneous, magnitude: CGFloat = 1.0) -> UIPushBehavior {
123 |         let push = UIPushBehavior(items: [self], mode: mode)
124 |         push.angle = angle
125 |         push.magnitude = magnitude
126 |         return push
127 |     }
128 |     
129 |     //collision
130 |     func collisionBehavior(_ mode: UICollisionBehavior.Mode = .boundaries) -> UICollisionBehavior {
131 |         let collision = UICollisionBehavior()
132 |         collision.collisionMode = mode
133 |         collision.addItem(self)
134 |         return collision
135 |     }
136 |     
137 |     func collisionBehavior(_ mode: UICollisionBehavior.Mode = .boundaries, path: UIBezierPath) -> UICollisionBehavior {
138 |         let collision = UICollisionBehavior()
139 |         collision.collisionMode = mode
140 |         let identifier = String(describing: Unmanaged.passUnretained(self).toOpaque())
141 |         collision.addBoundary(withIdentifier: identifier as NSCopying, for: path)
142 |         collision.addItem(self)
143 |         return collision
144 |     }
145 |     
146 |     func collisionBehavior(_ mode: UICollisionBehavior.Mode = .boundaries, fromPoint: CGPoint, toPoint: CGPoint) -> UICollisionBehavior {
147 |         let collision = UICollisionBehavior()
148 |         collision.collisionMode = mode
149 |         let identifier = String(describing: Unmanaged.passUnretained(self).toOpaque())
150 |         collision.addBoundary(withIdentifier: identifier as NSCopying, from: fromPoint, to: toPoint)
151 |         collision.addItem(self)
152 |         return collision
153 |     }
154 |     
155 |     //itemBehavior
156 |     func itemBehavior(_ elasticity: CGFloat = 0.5, friction: CGFloat = 0.5, density: CGFloat = 1, resistance: CGFloat = 0, angularResistance: CGFloat = 0, allowsRotation: Bool = true) -> UIDynamicItemBehavior {
157 |         let behavior = UIDynamicItemBehavior()
158 |         behavior.addItem(self)
159 |         behavior.elasticity = elasticity
160 |         behavior.friction = friction
161 |         behavior.density = density
162 |         behavior.resistance = resistance
163 |         behavior.angularResistance = angularResistance
164 |         behavior.allowsRotation = allowsRotation
165 |         return behavior
166 |     }
167 | }
168 | 


--------------------------------------------------------------------------------
/Sources/DynamicItem.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | //for 4 latitude
12 | final class DynamicItem<T: Vectorial>: NSObject, UIDynamicItem {
13 |     
14 |     var from: T
15 |     var to: T
16 |     var render: (T) -> Void
17 |     var complete = false
18 |     var boundaryLimit = false
19 |     var completion: (() -> Void)?
20 |     internal var fromR: Vector4
21 |     internal var toR: Vector4
22 |     weak var behavior: UIDynamicBehavior!
23 |     fileprivate var change: (x: Double,y: Double,z: Double,w: Double)
24 |     var referenceChangeLength: Double
25 |     
26 |     init(from: T, to: T, render: @escaping (T) -> Void) {
27 |         self.from = from
28 |         self.to = to
29 |         self.render = render
30 |         //
31 |         self.fromR = from.reverse()
32 |         self.toR = to.reverse()
33 |         //
34 |         let x = toR.one - fromR.one
35 |         let y = toR.two - fromR.two
36 |         let z = toR.three - fromR.three
37 |         let w = toR.four - fromR.four
38 |         self.change = (x,y,z,w)
39 |         //
40 |         let originChange = sqrt(x*x + y*y)
41 |         let sizeChange = sqrt(z*z + w*w)
42 |         self.referenceChangeLength = max(originChange, sizeChange)
43 |     }
44 |     
45 |     deinit {
46 |         self.render(to)
47 |         complete = true
48 |         completion?()
49 |     }
50 |     
51 |     //MARK: Update frame
52 |     
53 |     func updateFrame() {
54 |         let yChange = fabs(Double(center.y))
55 |         let progress = yChange / referenceChangeLength
56 |         let curX = fromR.one + change.x * progress;
57 |         let curY = fromR.two + change.y * progress;
58 |         let curZ = fromR.three + change.z * progress;
59 |         let curW = fromR.four + change.w * progress;
60 |         
61 |         let rect = Vector4.init((curX.isNaN ? 0 : curX,curY.isNaN ? 0 : curY,curZ.isNaN ? 0 : curZ,curW.isNaN ? 0 : curZ))
62 |         var curV = from.convert(rect)
63 |         if progress >= 1.0 {
64 |             if boundaryLimit {
65 |                 curV = to
66 |                 behavior.cancel()
67 |                 complete = true
68 |             }
69 |         }
70 |         self.render(curV)
71 |     }
72 |     
73 |     //MARK: UIDynamicItem protocol
74 |     var center: CGPoint = CGPoint.zero {
75 |         didSet {
76 |             updateFrame()
77 |         }
78 |     }
79 |     
80 |     var transform: CGAffineTransform = CGAffineTransform.identity
81 |     var bounds: CGRect {
82 |         get {
83 |             return CGRect(x: -50.0, y: -50.0, width: 100.0, height: 100.0)
84 |         }
85 |     }
86 | }
87 | 


--------------------------------------------------------------------------------
/Sources/DynamicItemBasic.swift:
--------------------------------------------------------------------------------
  1 | //Copyright (c) 2016
  2 | //
  3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  4 | //
  5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  6 | //
  7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  8 | 
  9 | import UIKit
 10 | 
 11 | private let SolveForReverse = { (f: CFTimeInterval) in
 12 |     return 1 - f
 13 | }
 14 | 
 15 | private let SolveForUnReverse = { (f: CFTimeInterval) in
 16 |     return f
 17 | }
 18 | 
 19 | final class DynamicItemBasic<T: Interpolatable>: NSObject, UIDynamicItem, TimingType {
 20 |     
 21 |     var duration: CFTimeInterval = 0.25
 22 |     var delay: CFTimeInterval = 0.0
 23 |     var timingFunction: TimingSolvable = TimingFunctionType.default.easing()
 24 |     var from: T
 25 |     var to: T
 26 |     var render: (T) -> Void
 27 |     var autoreverses = false
 28 |     var repeatCount = 0
 29 |     var completion: ((Bool) -> Void)?
 30 |     var speed: Double = 1.0
 31 |     var timeOffset: CFTimeInterval = 0.0 {
 32 |         didSet {
 33 |             updateFrame()
 34 |         }
 35 |     }
 36 |     
 37 |     weak var behavior: UIDynamicBehavior?
 38 |     //External data to store (performance)
 39 |     fileprivate var externalData: Any?
 40 |     fileprivate var complete = false
 41 |     fileprivate var isReversing = false
 42 |     fileprivate var solveProgress = SolveForUnReverse
 43 |     fileprivate lazy var beginTime: CFTimeInterval = {
 44 |         return CACurrentMediaTime()
 45 |     }()
 46 |     fileprivate lazy var epsilon: Double = {
 47 |         return 1.0 / (self.duration * 1000.0)
 48 |     }()
 49 |     
 50 |     //MARK: Life cycle methods
 51 |     init(from: T, to: T, render: @escaping (T) -> Void) {
 52 |         self.from = from
 53 |         self.to = to
 54 |         self.render = render
 55 |         
 56 |         if let fromColor = from as? UIColor {
 57 |             let fromInfo = fromColor.colorInfo()
 58 |             let toColor = to as! UIColor
 59 |             let toInfo = toColor.colorInfo()
 60 |             self.externalData = (fromInfo,toInfo)
 61 |         }
 62 |     }
 63 |     
 64 |     deinit {
 65 |         //do some thing
 66 |     }
 67 |     
 68 |     //MARK: update frame
 69 |     fileprivate func updateFrame() {
 70 |         let startTime = beginTime
 71 |         var currentTime = CACurrentMediaTime() - startTime - delay
 72 |         currentTime = max(0, currentTime) * speed + timeOffset
 73 |         var progress = currentTime / duration
 74 |         if progress >= 1.0 {
 75 |             isReversing = autoreverses ? !isReversing : false
 76 |             if repeatCount == 0 {
 77 |                 if isReversing {
 78 |                     progress = 0.0
 79 |                     beginTime = CACurrentMediaTime()
 80 |                     solveProgress = SolveForReverse
 81 |                 } else {
 82 |                     progress = 1.0
 83 |                     behavior?.cancel()
 84 |                     complete = true
 85 |                     self.completion?(complete)
 86 |                 }
 87 |             }else {
 88 |                 if isReversing == false {
 89 |                     repeatCount -= 1
 90 |                     solveProgress = SolveForUnReverse
 91 |                 } else {
 92 |                     solveProgress = SolveForReverse
 93 |                 }
 94 |                 progress = 0.0
 95 |                 beginTime = CACurrentMediaTime()
 96 |             }
 97 |         }
 98 |         let solveP = solveProgress(progress)
 99 |         let adjustProgress = timingFunction.solveOn(solveP, epslion: epsilon)
100 |         let value = from.interpolate(adjustProgress, to: to, externalData: externalData)
101 |         self.render(value)
102 |     }
103 |     
104 |     //MARK: UIDynamicItem protocol
105 |     var center: CGPoint = CGPoint.zero {
106 |         didSet {
107 |             updateFrame()
108 |         }
109 |     }
110 |     
111 |     var transform: CGAffineTransform = CGAffineTransform.identity
112 |     var bounds: CGRect {
113 |         get {
114 |             return CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0)
115 |         }
116 |     }
117 | }
118 | 


--------------------------------------------------------------------------------
/Sources/DynamicItemGravity.swift:
--------------------------------------------------------------------------------
  1 | //Copyright (c) 2016
  2 | //
  3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  4 | //
  5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  6 | //
  7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  8 | 
  9 | import UIKit
 10 | 
 11 | class DynamicItemGravity<T: Interpolatable>: NSObject, UIDynamicItem {
 12 |     
 13 |     var from: T!
 14 |     var to: T!
 15 |     var magnitude = 1.0
 16 |     var render: (T) -> Void
 17 |     var completion: (() -> Void)?
 18 |     var boundary = true
 19 |     weak var behavior: UIDynamicBehavior?
 20 |     //private vars
 21 |     fileprivate var referenceChangedLength: Double = 0.0
 22 |     //External data to store (performance)
 23 |     fileprivate var externalData: Any?
 24 |     fileprivate lazy var beginTime = {
 25 |         return CACurrentMediaTime()
 26 |     }()
 27 |     
 28 |     //MARK: init method
 29 |     init(from: T, to: T, render: @escaping (T) -> Void) {
 30 |         self.from = from
 31 |         self.to = to
 32 |         self.render = render
 33 |         super.init()
 34 |         caculateReferenceChangedLength()
 35 |     }
 36 |     
 37 |     deinit {
 38 |         self.completion?()
 39 |     }
 40 |     
 41 |     //MARK: private methods
 42 |     fileprivate func caculateReferenceChangedLength() {
 43 |         switch from {
 44 |         case let f as CGFloat:
 45 |             let t = to as! CGFloat
 46 |             referenceChangedLength = Double(abs(t - f))
 47 |             
 48 |         case let f as Float:
 49 |             let t = to as! Float
 50 |             referenceChangedLength = Double(abs(t - f))
 51 |             
 52 |         case let f as Double:
 53 |             let t = to as! Double
 54 |             referenceChangedLength = abs(t - f)
 55 |             
 56 |         case let f as CGSize:
 57 |             let t = to as! CGSize
 58 |             let w = abs(t.width - f.width)
 59 |             let h = abs(t.height - f.height)
 60 |             referenceChangedLength = max(Double(w), Double(h))
 61 | 
 62 |         case let f as CGPoint:
 63 |             let t = to as! CGPoint
 64 |             let x = abs(t.x - f.x)
 65 |             let y = abs(t.y - f.y)
 66 |             referenceChangedLength = max(Double(x), Double(y))
 67 |             
 68 |         case let f as CGRect:
 69 |             let t = to as! CGRect
 70 |             let xChange = abs(t.minX - f.minX)
 71 |             let yChange = abs(t.minY - f.minY)
 72 |             let wChange = abs(t.width - f.width)
 73 |             let hChange = abs(t.height - f.height)
 74 |             let originC = hypot(xChange, yChange)
 75 |             let sizeC = hypot(wChange, hChange)
 76 |             referenceChangedLength = max(Double(originC), Double(sizeC))
 77 |             
 78 |         case let f as UIColor:
 79 |             let t = to as! UIColor
 80 |             let fromInfo = f.colorInfo()
 81 |             let toInfo = t.colorInfo()
 82 |             let hueChange = abs(toInfo.hue - fromInfo.hue)
 83 |             let brightnessChange = abs(toInfo.brightness - fromInfo.brightness)
 84 |             let saturationChange = abs(toInfo.saturation - fromInfo.saturation)
 85 |             let alphaChange = abs(toInfo.alpha - fromInfo.alpha)
 86 |             let oneC = hypot(hueChange, saturationChange) * 1000.0
 87 |             let twoC = hypot(brightnessChange, alphaChange) * 1000.0
 88 |             referenceChangedLength = max(Double(oneC), Double(twoC))
 89 |             externalData = (fromInfo,toInfo)
 90 |             
 91 |         default:
 92 |             referenceChangedLength = 1000.0
 93 |        
 94 |         }
 95 |     }
 96 |     
 97 |     fileprivate func updateFrame() {
 98 |         if referenceChangedLength <= 0.0 {
 99 |             behavior?.cancel()
100 |             return
101 |         }
102 |         var currentTime = CACurrentMediaTime() - beginTime
103 |         currentTime = max(0.0, currentTime)
104 |         let offset = gravityOffset(currentTime)
105 |         var progress = offset / referenceChangedLength
106 |         if progress >= 1.0 {
107 |             if boundary {
108 |                 progress = 1.0
109 |                 behavior?.cancel()
110 |             }
111 |         }
112 |         
113 |         let value = from.interpolate(progress, to: to, externalData: externalData)
114 |         render(value)
115 |     }
116 |     
117 |     fileprivate func gravityOffset(_ t: CFTimeInterval) -> Double {
118 |         return t * t * 1000.0 * magnitude;
119 |     }
120 |     
121 |     //MARK: UIDynamicItem protocol
122 |     var center: CGPoint = CGPoint.zero {
123 |         didSet {
124 |             updateFrame()
125 |         }
126 |     }
127 |     
128 |     var transform: CGAffineTransform = CGAffineTransform.identity
129 |     var bounds: CGRect {
130 |         get {
131 |             return CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0)
132 |         }
133 |     }
134 | }
135 | 


--------------------------------------------------------------------------------
/Sources/GravityConfigurable.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | public protocol GravityConfigurable: BasicChainable {
12 |     func gravity(_ magnitude: Double) -> Self
13 | }
14 | 


--------------------------------------------------------------------------------
/Sources/Interpolatable.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import Foundation
10 | 
11 | public protocol Interpolatable: Vectorial {
12 |     func interpolate(_ progress: Double, to: Self, externalData: Any?) -> Self
13 | }
14 | 


--------------------------------------------------------------------------------
/Sources/Physical.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | public protocol Physical: Interpolatable {}
12 | 
13 | extension Physical {
14 |     public func fall(to: Self,magnitude: Double = 1.0, render: @escaping (Self) -> Void, completion: (() -> Void)? = nil) {
15 |         let item = DynamicItemGravity(from: self, to: to, render: render)
16 |         let push = item.pushBehavior(.down)
17 |         item.behavior = push
18 |         item.magnitude = magnitude
19 |         item.completion = completion
20 |         push.commitToBasic()
21 |     }
22 |     
23 |     public func snap(to: Self, damping: CGFloat = 0.5,render: @escaping (Self) -> Void, completion: (() -> Void)? = nil) {
24 |         let item = DynamicItem(from: self, to: to, render: render)
25 |         let toP = CGPoint.init(x: 0, y: CGFloat(item.referenceChangeLength))
26 |         let snap = item.snapBehavior(toP, damping: damping)
27 |         item.behavior = snap
28 |         item.completion = completion
29 |         snap.commit()
30 |     }
31 |     
32 |     public func attachment(to: Self,damping: CGFloat = 0.5, frequency: CGFloat = 0.5,render: @escaping (Self) -> Void, completion: (() -> Void)? = nil) {
33 |         let item = DynamicItem(from: self, to: to,render: render)
34 |         let toP = CGPoint.init(x: 0, y: CGFloat(item.referenceChangeLength))
35 |         let attachment = item.attachmentBehavior(toP, length: 0.0, damping: damping, frequency: frequency)
36 |         item.behavior = attachment
37 |         item.completion = completion
38 |         attachment.commit()
39 |     }
40 |     
41 |     public func pushed(to: Self,render: @escaping (Self) -> Void, completion: (() -> Void)? = nil) {
42 |         let item = DynamicItem(from: self,to: to,render: render)
43 |         let direction = CGVector(dx: item.toR.one - item.fromR.one, dy: item.toR.two - item.fromR.two)
44 |         let push = item.pushBehavior(direction, mode: .instantaneous, magnitude: 1.0)
45 |         item.behavior = push
46 |         item.boundaryLimit = true
47 |         item.completion = completion
48 |         push.commit()
49 |     }
50 |     
51 |     public func animate(to: Self, duration: CFTimeInterval = 0.25, delay: CFTimeInterval = 0.0, type: TimingFunctionType = .default, autoreverses: Bool = false, repeatCount: Int = 0, render: @escaping (Self) -> Void, completion: ((Bool) -> Void)? = nil) {
52 |         let basicItem = DynamicItemBasic(from: self, to: to, render: render)
53 |         let push = basicItem.pushBehavior(.down)
54 |         basicItem.behavior = push
55 |         basicItem.duration = duration
56 |         basicItem.timingFunction = type.easing()
57 |         basicItem.completion = completion
58 |         basicItem.delay = delay
59 |         basicItem.autoreverses = autoreverses
60 |         push.commitToBasic()
61 |     }
62 | }
63 | 
64 | 
65 | 


--------------------------------------------------------------------------------
/Sources/SnapConfigurable.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | public protocol SnapConfigurable: BasicChainable {
12 |     func snap(_ damping: CGFloat) -> Self
13 | }
14 | 


--------------------------------------------------------------------------------
/Sources/StepControllable.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import Foundation
10 | 
11 | public protocol StepControllable {
12 |     //remove all remaining from excute sequence
13 |     func cancelAllRemaining()
14 |     //will add more methods to control animation steps
15 | }


--------------------------------------------------------------------------------
/Sources/TimingFunction.swift:
--------------------------------------------------------------------------------
  1 | //Copyright (c) 2016
  2 | //
  3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  4 | //
  5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  6 | //
  7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  8 | import Foundation
  9 | 
 10 | /// A set of preset bezier curves.
 11 | public enum TimingFunctionType {
 12 |     /// Equivalent to `kCAMediaTimingFunctionDefault`.
 13 |     case `default`
 14 |     
 15 |     /// Equivalent to `kCAMediaTimingFunctionEaseIn`.
 16 |     case easeIn
 17 |     
 18 |     /// Equivalent to `kCAMediaTimingFunctionEaseOut`.
 19 |     case easeOut
 20 |     
 21 |     /// Equivalent to `kCAMediaTimingFunctionEaseInEaseOut`.
 22 |     case easeInEaseOut
 23 |     
 24 |     /// No easing.
 25 |     case linear
 26 |     
 27 |     /// Inspired by the default curve in Google Material Design.
 28 |     case swiftOut
 29 |     /// 
 30 |     case backEaseIn
 31 |     ///
 32 |     case backEaseOut
 33 |     ///
 34 |     case backEaseInOut
 35 |     ///
 36 |     case bounceOut
 37 |     ///
 38 |     case sine
 39 |     ///
 40 |     case circ
 41 |     ///
 42 |     case exponentialIn
 43 |     ///
 44 |     case exponentialOut
 45 |     ///
 46 |     case elasticIn
 47 |     ///
 48 |     case bounceReverse
 49 |     ///
 50 |     case elasticOut
 51 |     /// custom
 52 |     case custom(Double, Double, Double, Double)
 53 |     
 54 |     
 55 |     func easing() -> TimingSolvable {
 56 |         switch self {
 57 |         case .default:
 58 |             return UnitBezier(p1x: 0.25, p1y: 0.1, p2x: 0.25, p2y: 1.0)
 59 |         case .easeIn:
 60 |             return UnitBezier(p1x: 0.42, p1y: 0.0, p2x: 1.0, p2y: 1.0)
 61 |         case .easeOut:
 62 |             return UnitBezier(p1x: 0.0, p1y: 0.0, p2x: 0.58, p2y: 1.0)
 63 |         case .easeInEaseOut:
 64 |             return UnitBezier(p1x: 0.42, p1y: 0.0, p2x: 0.58, p2y: 1.0)
 65 |         case .linear: 
 66 |             return UnitBezier(p1x: 0.0, p1y: 0.0, p2x: 1.0, p2y: 1.0)
 67 |         case .swiftOut: 
 68 |             return UnitBezier(p1x: 0.4, p1y: 0.0, p2x: 0.2, p2y: 1.0)
 69 |         case .backEaseIn:
 70 |             return EasingContainer(easing: { (t: Double) in
 71 |                 return t * t * t - t * sin(t * .pi)
 72 |             })
 73 |         case .backEaseOut:
 74 |             return EasingContainer(easing: { (t: Double) in
 75 |                 let f = (1 - t);
 76 |                 return 1 - (f * f * f - f * sin(f * .pi));
 77 |             })
 78 |         case .backEaseInOut:
 79 |             return EasingContainer(easing: { (t: Double) in
 80 |                 if(t < 0.5) {
 81 |                     let f = 2 * t;
 82 |                     return 0.5 * (f * f * f - f * sin(f * .pi));
 83 |                 } else {
 84 |                     let f = (1.0 - (2.0 * t - 1.0));
 85 |                     let cubic = f * f * f
 86 |                     return 0.5 * (1.0 - (cubic - f * sin(f * .pi))) + 0.5;
 87 |                 }
 88 |             })
 89 |         case .bounceOut:
 90 |             return EasingContainer(easing: { (t: Double) in
 91 |                 if(t < 4/11.0){
 92 |                     return (121 * t * t)/16.0;
 93 |                 } else if(t < 8/11.0){
 94 |                     return (363/40.0 * t * t) - (99/10.0 * t) + 17/5.0;
 95 |                 }else if(t < 9/10.0){
 96 |                     return (4356/361.0 * t * t) - (35442/1805.0 * t) + 16061/1805.0;
 97 |                 }else{
 98 |                     return (54/5.0 * t * t) - (513/25.0 * t) + 268/25.0;
 99 |                 }
100 |             })
101 |         case .sine:
102 |             return EasingContainer(easing: { (t: Double) in
103 |                 return 1 - cos( t * .pi / 2.0)
104 |             })
105 |         case .circ:
106 |             return EasingContainer(easing: { (t: Double) in
107 |                 return 1 - sqrt( 1.0 - t * t )
108 |             })
109 |         case .exponentialIn:
110 |             return EasingContainer(easing: { (t: Double) in
111 |                 return (t == 0.0) ? t : pow(2, 10 * (t - 1))
112 |             })
113 |         case .exponentialOut:
114 |             return EasingContainer(easing: { (t: Double) in
115 |                 return (t == 1.0) ? t : 1 - pow(2, -10 * t)
116 |             })
117 |         case .elasticIn:
118 |             return EasingContainer(easing: { (t: Double) in
119 |                 return sin(13.0 * (.pi / 2.0) * t) * pow(2, 10 * (t - 1))
120 |             })
121 |         case .elasticOut:
122 |             return EasingContainer(easing: { (t: Double) in
123 |                 return sin(-13.0 * (.pi / 2.0) * (t + 1)) * pow(2, -10 * t) + 1.0;
124 |             })
125 |         case .bounceReverse:
126 |             return EasingContainer(easing: { (t: Double) in
127 |                 var bounce: Double = 4.0
128 |                 var pow2 = 0.0
129 |                 
130 |                 repeat {
131 |                     bounce = bounce - 1.0
132 |                     pow2 = pow(2, bounce)
133 |                 } while (t < (pow2 - 1.0 ) / 11.0)
134 |                 
135 |                 return 1 / pow( 4, 3 - bounce ) - 7.5625 * pow( ( pow2 * 3 - 2 ) / 22 - t, 2 );
136 |             })
137 |         case .custom(let p1x,let p1y,let p2x,let p2y):
138 |             return UnitBezier(p1x: p1x, p1y: p1y, p2x: p2x, p2y: p2y)
139 |         }
140 |     }
141 | }
142 | 
143 | class EasingContainer: TimingSolvable {
144 |     let easing: (Double) -> Double
145 |     
146 |     init(easing: @escaping (Double) -> Double) {
147 |         self.easing = easing
148 |     }
149 |     
150 |     //
151 |     func solveOn(_ time: Double, epslion: Double) -> Double {
152 |         return self.easing(time)
153 |     }
154 | }
155 | 
156 | 
157 | 


--------------------------------------------------------------------------------
/Sources/TimingSolvable.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  TimingSolvable.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 6/28/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import Foundation
10 | 
11 | protocol TimingSolvable {
12 |     func solveOn(_ time: Double, epslion: Double) -> Double
13 | }
14 | 


--------------------------------------------------------------------------------
/Sources/TimingType.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import Foundation
10 | 
11 | protocol TimingType {
12 |     var duration: CFTimeInterval { get set }
13 |     var delay: CFTimeInterval { get set }
14 |     var timingFunction: TimingSolvable { get set }
15 |     var autoreverses: Bool { get set }
16 |     var repeatCount: Int { get set }
17 |     var speed: Double { get set }
18 |     var timeOffset: CFTimeInterval { get set }
19 | }


--------------------------------------------------------------------------------
/Sources/UIDynamicBehavior+Commit.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | internal extension UIDynamicBehavior {
12 |     
13 |     func commit() {
14 |         AnimatorCoordinator.shared.addBehavior(self)
15 |     }
16 |         
17 |     func cancel() {
18 |         self.dynamicAnimator?.removeBehavior(self)
19 |     }
20 |     
21 |     func commitToBasic() {
22 |         AnimatorCoordinator.shared.addBasicBehavior(self)
23 |     }
24 | }
25 | 


--------------------------------------------------------------------------------
/Sources/UnitBezier.swift:
--------------------------------------------------------------------------------
  1 | //Copyright (c) 2016
  2 | //
  3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  4 | //
  5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  6 | //
  7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  8 | 
  9 | import Foundation
 10 | import CoreGraphics
 11 | 
 12 | public typealias Scalar = Double
 13 | /// A bezier curve, often used to calculate timing functions.
 14 | public struct UnitBezier {
 15 |     
 16 |     /// The horizontal component of the first control point.
 17 |     public var p1x: Scalar
 18 |     
 19 |     /// The vertical component of the first control point.
 20 |     public var p1y: Scalar
 21 |     
 22 |     /// The horizontal component of the second control point.
 23 |     public var p2x: Scalar
 24 |     
 25 |     /// The vertical component of the second control point.
 26 |     public var p2y: Scalar
 27 |     
 28 |     /// Creates a new `UnitBezier` instance.
 29 |     public init(p1x: Scalar, p1y: Scalar, p2x: Scalar, p2y: Scalar) {
 30 |         self.p1x = p1x
 31 |         self.p1y = p1y
 32 |         self.p2x = p2x
 33 |         self.p2y = p2y
 34 |     }
 35 |     
 36 |     /// Calculates the resulting `y` for given `x`.
 37 |     ///
 38 |     /// - parameter x: The value to solve for.
 39 |     /// - parameter epsilon: The required precision of the result (where `x * epsilon` is the maximum time segment to be evaluated).
 40 |     /// - returns: The solved `y` value.
 41 |     public func solve(_ x: Scalar, epsilon: Scalar) -> Scalar {
 42 |         return UnitBezierSolver(bezier: self).solve(x, eps: epsilon)
 43 |     }
 44 | }
 45 | 
 46 | extension UnitBezier: Equatable { }
 47 | 
 48 | extension UnitBezier: TimingSolvable {
 49 |     func solveOn(_ time: Double, epslion: Double) -> Double {
 50 |         return self.solve(time, epsilon: epslion)
 51 |     }
 52 | }
 53 | 
 54 | /// Equatable.
 55 | public func ==(lhs: UnitBezier, rhs: UnitBezier) -> Bool {
 56 |     return lhs.p1x == rhs.p1x
 57 |         && lhs.p1y == rhs.p1y
 58 |         && lhs.p2x == rhs.p2x
 59 |         && lhs.p2y == rhs.p2y
 60 | }
 61 | 
 62 | 
 63 | // Ported to Swift from WebCore:
 64 | // http://opensource.apple.com/source/WebCore/WebCore-955.66/platform/graphics/UnitBezier.h
 65 | 
 66 | /*
 67 |  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
 68 |  *
 69 |  * Redistribution and use in source and binary forms, with or without
 70 |  * modification, are permitted provided that the following conditions
 71 |  * are met:
 72 |  * 1. Redistributions of source code must retain the above copyright
 73 |  *    notice, this list of conditions and the following disclaimer.
 74 |  * 2. Redistributions in binary form must reproduce the above copyright
 75 |  *    notice, this list of conditions and the following disclaimer in the
 76 |  *    documentation and/or other materials provided with the distribution.
 77 |  *
 78 |  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 79 |  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 80 |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 81 |  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 82 |  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 83 |  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 84 |  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 85 |  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 86 |  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 87 |  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 88 |  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 89 |  */
 90 | 
 91 | 
 92 | private struct UnitBezierSolver {
 93 |     
 94 |     fileprivate let ax: Scalar
 95 |     fileprivate let bx: Scalar
 96 |     fileprivate let cx: Scalar
 97 |     
 98 |     fileprivate let ay: Scalar
 99 |     fileprivate let by: Scalar
100 |     fileprivate let cy: Scalar
101 |     
102 |     init(bezier: UnitBezier) {
103 |         self.init(p1x: bezier.p1x, p1y: bezier.p1y, p2x: bezier.p2x, p2y: bezier.p2y)
104 |     }
105 |     
106 |     init(p1x: Scalar, p1y: Scalar, p2x: Scalar, p2y: Scalar) {
107 |         
108 |         // Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1).
109 |         cx = 3.0 * p1x
110 |         bx = 3.0 * (p2x - p1x) - cx
111 |         ax = 1.0 - cx - bx
112 |         
113 |         cy = 3.0 * p1y
114 |         by = 3.0 * (p2y - p1y) - cy
115 |         ay = 1.0 - cy - by
116 |     }
117 |     
118 |     func sampleCurveX(_ t: Scalar) -> Scalar {
119 |         return ((ax * t + bx) * t + cx) * t
120 |     }
121 |     
122 |     func sampleCurveY(_ t: Scalar) -> Scalar {
123 |         return ((ay * t + by) * t + cy) * t
124 |     }
125 |     
126 |     func sampleCurveDerivativeX(_ t: Scalar) -> Scalar {
127 |         return (3.0 * ax * t + 2.0 * bx) * t + cx
128 |     }
129 |     
130 |     func solveCurveX(_ x: Scalar, eps: Scalar) -> Scalar {
131 |         var t0: Scalar = 0.0
132 |         var t1: Scalar = 0.0
133 |         var t2: Scalar = 0.0
134 |         var x2: Scalar = 0.0
135 |         var d2: Scalar = 0.0
136 |         
137 |         // First try a few iterations of Newton's method -- normally very fast.
138 |         t2 = x
139 |         for _ in 0..<8 {
140 |             x2 = sampleCurveX(t2) - x
141 |             if abs(x2) < eps {
142 |                 return t2
143 |             }
144 |             d2 = sampleCurveDerivativeX(t2)
145 |             if abs(d2) < 1e-6 {
146 |                 break
147 |             }
148 |             t2 = t2 - x2 / d2
149 |         }
150 |         
151 |         // Fall back to the bisection method for reliability.
152 |         t0 = 0.0
153 |         t1 = 1.0
154 |         t2 = x
155 |         
156 |         if t2 < t0 {
157 |             return t0
158 |         }
159 |         if t2 > t1 {
160 |             return t1
161 |         }
162 |         
163 |         while t0 < t1 {
164 |             x2 = sampleCurveX(t2)
165 |             if abs(x2-x) < eps {
166 |                 return t2
167 |             }
168 |             if x > x2 {
169 |                 t0 = t2
170 |             } else {
171 |                 t1 = t2
172 |             }
173 |             t2 = (t1-t0) * 0.5 + t0
174 |         }
175 |         
176 |         return t2
177 |     }
178 |     
179 |     func solve(_ x: Scalar, eps: Scalar) -> Scalar {
180 |         return sampleCurveY(solveCurveX(x, eps: eps))
181 |     }
182 | }
183 | 


--------------------------------------------------------------------------------
/Sources/Vectorial.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | public class Vector4 {
12 |     var one: Double = 0
13 |     var two: Double = 0
14 |     var three: Double = 0
15 |     var four: Double = 0
16 |     
17 |     convenience init(_ fourLatitude: (Double,Double,Double,Double)) {
18 |         self.init()
19 |         self.one = fourLatitude.0
20 |         self.two = fourLatitude.1
21 |         self.three = fourLatitude.2
22 |         self.four = fourLatitude.3
23 |     }
24 | }
25 | 
26 | public protocol Vectorial {
27 |     func convert(_ p: Vector4) -> Self
28 |     func reverse() -> Vector4
29 | }
30 | 


--------------------------------------------------------------------------------
/Stellar.podspec:
--------------------------------------------------------------------------------
 1 | Pod::Spec.new do |s|
 2 |   s.name         = "Stellar"
 3 |   s.version      = "0.67"
 4 |   s.summary      = "An Awesome Physical animation library base on UIDynamic. "
 5 |   s.description  = "A fantastic Physical animation library for swift(Not Just Spring !!!), it is base on UIDynamic and extension to it, friendly APIs make you use it or custom your own animation very easily!"
 6 |   s.homepage     = "https://github.com/AugustRush/Stellar"
 7 |   s.license      = "LICENSE"
 8 |   s.author             = { "AugustRush" => "819373341@qq.com" }
 9 |   s.source       = { :git => "https://github.com/AugustRush/Stellar.git", :tag => "0.67" }
10 |   s.source_files = "Sources", "Sources/*.swift"
11 |   s.platform     = :ios, "8.0"
12 |   s.frameworks = "UIKit", "Foundation"
13 | end
14 | 


--------------------------------------------------------------------------------
/StellarDemo/Stellar/Info.plist:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 3 | <plist version="1.0">
 4 | <dict>
 5 | 	<key>CFBundleDevelopmentRegion</key>
 6 | 	<string>en</string>
 7 | 	<key>CFBundleExecutable</key>
 8 | 	<string>$(EXECUTABLE_NAME)</string>
 9 | 	<key>CFBundleIdentifier</key>
10 | 	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11 | 	<key>CFBundleInfoDictionaryVersion</key>
12 | 	<string>6.0</string>
13 | 	<key>CFBundleName</key>
14 | 	<string>$(PRODUCT_NAME)</string>
15 | 	<key>CFBundlePackageType</key>
16 | 	<string>FMWK</string>
17 | 	<key>CFBundleShortVersionString</key>
18 | 	<string>1.0</string>
19 | 	<key>CFBundleSignature</key>
20 | 	<string>????</string>
21 | 	<key>CFBundleVersion</key>
22 | 	<string>$(CURRENT_PROJECT_VERSION)</string>
23 | 	<key>NSPrincipalClass</key>
24 | 	<string></string>
25 | </dict>
26 | </plist>
27 | 


--------------------------------------------------------------------------------
/StellarDemo/Stellar/Stellar.h:
--------------------------------------------------------------------------------
 1 | //
 2 | //  Stellar.h
 3 | //  Stellar
 4 | //
 5 | //  Created by AugustRush on 6/6/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | #import <UIKit/UIKit.h>
10 | 
11 | //! Project version number for Stellar.
12 | FOUNDATION_EXPORT double StellarVersionNumber;
13 | 
14 | //! Project version string for Stellar.
15 | FOUNDATION_EXPORT const unsigned char StellarVersionString[];
16 | 
17 | // In this header, you should import all the public headers of your framework using statements like #import <Stellar/PublicHeader.h>
18 | 
19 | 
20 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8"?>
2 | <Workspace
3 |    version = "1.0">
4 |    <FileRef
5 |       location = "self:">
6 |    </FileRef>
7 | </Workspace>
8 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo.xcodeproj/project.xcworkspace/xcuserdata/August.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/StellarDemo/StellarDemo.xcodeproj/project.xcworkspace/xcuserdata/August.xcuserdatad/UserInterfaceState.xcuserstate


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo.xcodeproj/xcshareddata/xcschemes/Stellar.xcscheme:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <Scheme
 3 |    LastUpgradeVersion = "1010"
 4 |    version = "1.3">
 5 |    <BuildAction
 6 |       parallelizeBuildables = "YES"
 7 |       buildImplicitDependencies = "YES">
 8 |       <BuildActionEntries>
 9 |          <BuildActionEntry
10 |             buildForTesting = "YES"
11 |             buildForRunning = "YES"
12 |             buildForProfiling = "YES"
13 |             buildForArchiving = "YES"
14 |             buildForAnalyzing = "YES">
15 |             <BuildableReference
16 |                BuildableIdentifier = "primary"
17 |                BlueprintIdentifier = "97019FD51D054ECD00FD6644"
18 |                BuildableName = "Stellar.framework"
19 |                BlueprintName = "Stellar"
20 |                ReferencedContainer = "container:StellarDemo.xcodeproj">
21 |             </BuildableReference>
22 |          </BuildActionEntry>
23 |       </BuildActionEntries>
24 |    </BuildAction>
25 |    <TestAction
26 |       buildConfiguration = "Debug"
27 |       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28 |       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29 |       shouldUseLaunchSchemeArgsEnv = "YES">
30 |       <Testables>
31 |       </Testables>
32 |       <AdditionalOptions>
33 |       </AdditionalOptions>
34 |    </TestAction>
35 |    <LaunchAction
36 |       buildConfiguration = "Debug"
37 |       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
38 |       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
39 |       launchStyle = "0"
40 |       useCustomWorkingDirectory = "NO"
41 |       ignoresPersistentStateOnLaunch = "NO"
42 |       debugDocumentVersioning = "YES"
43 |       debugServiceExtension = "internal"
44 |       allowLocationSimulation = "YES">
45 |       <MacroExpansion>
46 |          <BuildableReference
47 |             BuildableIdentifier = "primary"
48 |             BlueprintIdentifier = "97019FD51D054ECD00FD6644"
49 |             BuildableName = "Stellar.framework"
50 |             BlueprintName = "Stellar"
51 |             ReferencedContainer = "container:StellarDemo.xcodeproj">
52 |          </BuildableReference>
53 |       </MacroExpansion>
54 |       <AdditionalOptions>
55 |       </AdditionalOptions>
56 |    </LaunchAction>
57 |    <ProfileAction
58 |       buildConfiguration = "Release"
59 |       shouldUseLaunchSchemeArgsEnv = "YES"
60 |       savedToolIdentifier = ""
61 |       useCustomWorkingDirectory = "NO"
62 |       debugDocumentVersioning = "YES">
63 |       <MacroExpansion>
64 |          <BuildableReference
65 |             BuildableIdentifier = "primary"
66 |             BlueprintIdentifier = "97019FD51D054ECD00FD6644"
67 |             BuildableName = "Stellar.framework"
68 |             BlueprintName = "Stellar"
69 |             ReferencedContainer = "container:StellarDemo.xcodeproj">
70 |          </BuildableReference>
71 |       </MacroExpansion>
72 |    </ProfileAction>
73 |    <AnalyzeAction
74 |       buildConfiguration = "Debug">
75 |    </AnalyzeAction>
76 |    <ArchiveAction
77 |       buildConfiguration = "Release"
78 |       revealArchiveInOrganizer = "YES">
79 |    </ArchiveAction>
80 | </Scheme>
81 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo.xcodeproj/xcshareddata/xcschemes/StellarDemo.xcscheme:
--------------------------------------------------------------------------------
  1 | <?xml version="1.0" encoding="UTF-8"?>
  2 | <Scheme
  3 |    LastUpgradeVersion = "1010"
  4 |    version = "1.3">
  5 |    <BuildAction
  6 |       parallelizeBuildables = "YES"
  7 |       buildImplicitDependencies = "YES">
  8 |       <BuildActionEntries>
  9 |          <BuildActionEntry
 10 |             buildForTesting = "YES"
 11 |             buildForRunning = "YES"
 12 |             buildForProfiling = "YES"
 13 |             buildForArchiving = "YES"
 14 |             buildForAnalyzing = "YES">
 15 |             <BuildableReference
 16 |                BuildableIdentifier = "primary"
 17 |                BlueprintIdentifier = "97BE88BD1CDDDAD000240523"
 18 |                BuildableName = "StellarDemo.app"
 19 |                BlueprintName = "StellarDemo"
 20 |                ReferencedContainer = "container:StellarDemo.xcodeproj">
 21 |             </BuildableReference>
 22 |          </BuildActionEntry>
 23 |       </BuildActionEntries>
 24 |    </BuildAction>
 25 |    <TestAction
 26 |       buildConfiguration = "Debug"
 27 |       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 28 |       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 29 |       shouldUseLaunchSchemeArgsEnv = "YES">
 30 |       <Testables>
 31 |          <TestableReference
 32 |             skipped = "NO">
 33 |             <BuildableReference
 34 |                BuildableIdentifier = "primary"
 35 |                BlueprintIdentifier = "97BE88D11CDDDAD000240523"
 36 |                BuildableName = "StellarDemoTests.xctest"
 37 |                BlueprintName = "StellarDemoTests"
 38 |                ReferencedContainer = "container:StellarDemo.xcodeproj">
 39 |             </BuildableReference>
 40 |          </TestableReference>
 41 |          <TestableReference
 42 |             skipped = "NO">
 43 |             <BuildableReference
 44 |                BuildableIdentifier = "primary"
 45 |                BlueprintIdentifier = "97BE88DC1CDDDAD000240523"
 46 |                BuildableName = "StellarDemoUITests.xctest"
 47 |                BlueprintName = "StellarDemoUITests"
 48 |                ReferencedContainer = "container:StellarDemo.xcodeproj">
 49 |             </BuildableReference>
 50 |          </TestableReference>
 51 |          <TestableReference
 52 |             skipped = "NO">
 53 |             <BuildableReference
 54 |                BuildableIdentifier = "primary"
 55 |                BlueprintIdentifier = "97019FDE1D054ECD00FD6644"
 56 |                BuildableName = "StellarTests.xctest"
 57 |                BlueprintName = "StellarTests"
 58 |                ReferencedContainer = "container:StellarDemo.xcodeproj">
 59 |             </BuildableReference>
 60 |          </TestableReference>
 61 |       </Testables>
 62 |       <MacroExpansion>
 63 |          <BuildableReference
 64 |             BuildableIdentifier = "primary"
 65 |             BlueprintIdentifier = "97BE88BD1CDDDAD000240523"
 66 |             BuildableName = "StellarDemo.app"
 67 |             BlueprintName = "StellarDemo"
 68 |             ReferencedContainer = "container:StellarDemo.xcodeproj">
 69 |          </BuildableReference>
 70 |       </MacroExpansion>
 71 |       <AdditionalOptions>
 72 |       </AdditionalOptions>
 73 |    </TestAction>
 74 |    <LaunchAction
 75 |       buildConfiguration = "Debug"
 76 |       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
 77 |       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
 78 |       launchStyle = "0"
 79 |       useCustomWorkingDirectory = "NO"
 80 |       ignoresPersistentStateOnLaunch = "NO"
 81 |       debugDocumentVersioning = "YES"
 82 |       debugServiceExtension = "internal"
 83 |       allowLocationSimulation = "YES">
 84 |       <BuildableProductRunnable
 85 |          runnableDebuggingMode = "0">
 86 |          <BuildableReference
 87 |             BuildableIdentifier = "primary"
 88 |             BlueprintIdentifier = "97BE88BD1CDDDAD000240523"
 89 |             BuildableName = "StellarDemo.app"
 90 |             BlueprintName = "StellarDemo"
 91 |             ReferencedContainer = "container:StellarDemo.xcodeproj">
 92 |          </BuildableReference>
 93 |       </BuildableProductRunnable>
 94 |       <AdditionalOptions>
 95 |       </AdditionalOptions>
 96 |    </LaunchAction>
 97 |    <ProfileAction
 98 |       buildConfiguration = "Release"
 99 |       shouldUseLaunchSchemeArgsEnv = "YES"
100 |       savedToolIdentifier = ""
101 |       useCustomWorkingDirectory = "NO"
102 |       debugDocumentVersioning = "YES">
103 |       <BuildableProductRunnable
104 |          runnableDebuggingMode = "0">
105 |          <BuildableReference
106 |             BuildableIdentifier = "primary"
107 |             BlueprintIdentifier = "97BE88BD1CDDDAD000240523"
108 |             BuildableName = "StellarDemo.app"
109 |             BlueprintName = "StellarDemo"
110 |             ReferencedContainer = "container:StellarDemo.xcodeproj">
111 |          </BuildableReference>
112 |       </BuildableProductRunnable>
113 |    </ProfileAction>
114 |    <AnalyzeAction
115 |       buildConfiguration = "Debug">
116 |    </AnalyzeAction>
117 |    <ArchiveAction
118 |       buildConfiguration = "Release"
119 |       revealArchiveInOrganizer = "YES">
120 |    </ArchiveAction>
121 | </Scheme>
122 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo.xcodeproj/xcuserdata/August.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <Bucket
 3 |    type = "1"
 4 |    version = "2.0">
 5 |    <Breakpoints>
 6 |       <BreakpointProxy
 7 |          BreakpointExtensionID = "Xcode.Breakpoint.SymbolicBreakpoint">
 8 |          <BreakpointContent
 9 |             shouldBeEnabled = "Yes"
10 |             ignoreCount = "0"
11 |             continueAfterRunningActions = "No"
12 |             symbolName = ""
13 |             moduleName = "">
14 |             <Locations>
15 |             </Locations>
16 |          </BreakpointContent>
17 |       </BreakpointProxy>
18 |       <BreakpointProxy
19 |          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
20 |          <BreakpointContent
21 |             shouldBeEnabled = "Yes"
22 |             ignoreCount = "0"
23 |             continueAfterRunningActions = "No"
24 |             filePath = "../Sources/UIView+AnimateBehavior.swift"
25 |             timestampString = "516163535.849267"
26 |             startingColumnNumber = "9223372036854775807"
27 |             endingColumnNumber = "9223372036854775807"
28 |             startingLineNumber = "236"
29 |             endingLineNumber = "236"
30 |             landmarkName = "createDynamicBehavior(withStyle:subType:step:)"
31 |             landmarkType = "7">
32 |          </BreakpointContent>
33 |       </BreakpointProxy>
34 |       <BreakpointProxy
35 |          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
36 |          <BreakpointContent
37 |             shouldBeEnabled = "Yes"
38 |             ignoreCount = "0"
39 |             continueAfterRunningActions = "No"
40 |             filePath = "../Sources/UIView+AnimateBehavior.swift"
41 |             timestampString = "516163535.849267"
42 |             startingColumnNumber = "9223372036854775807"
43 |             endingColumnNumber = "9223372036854775807"
44 |             startingLineNumber = "166"
45 |             endingLineNumber = "166"
46 |             landmarkName = "createDynamicBehavior(withStyle:subType:step:)"
47 |             landmarkType = "7">
48 |          </BreakpointContent>
49 |       </BreakpointProxy>
50 |       <BreakpointProxy
51 |          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
52 |          <BreakpointContent
53 |             shouldBeEnabled = "Yes"
54 |             ignoreCount = "0"
55 |             continueAfterRunningActions = "No"
56 |             filePath = "../Sources/UIView+AnimateBehavior.swift"
57 |             timestampString = "516163535.849267"
58 |             startingColumnNumber = "9223372036854775807"
59 |             endingColumnNumber = "9223372036854775807"
60 |             startingLineNumber = "239"
61 |             endingLineNumber = "239"
62 |             landmarkName = "createDynamicBehavior(withStyle:subType:step:)"
63 |             landmarkType = "7">
64 |          </BreakpointContent>
65 |       </BreakpointProxy>
66 |       <BreakpointProxy
67 |          BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
68 |          <BreakpointContent
69 |             shouldBeEnabled = "Yes"
70 |             ignoreCount = "0"
71 |             continueAfterRunningActions = "No"
72 |             filePath = "../Sources/DynamicItem.swift"
73 |             timestampString = "516081338.922453"
74 |             startingColumnNumber = "9223372036854775807"
75 |             endingColumnNumber = "9223372036854775807"
76 |             startingLineNumber = "27"
77 |             endingLineNumber = "27"
78 |             landmarkName = "init(from:to:render:)"
79 |             landmarkType = "7">
80 |          </BreakpointContent>
81 |       </BreakpointProxy>
82 |    </Breakpoints>
83 | </Bucket>
84 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo.xcodeproj/xcuserdata/August.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 3 | <plist version="1.0">
 4 | <dict>
 5 | 	<key>SchemeUserState</key>
 6 | 	<dict>
 7 | 		<key>StellarDemo.xcscheme_^#shared#^_</key>
 8 | 		<dict>
 9 | 			<key>orderHint</key>
10 | 			<integer>0</integer>
11 | 		</dict>
12 | 	</dict>
13 | 	<key>SuppressBuildableAutocreation</key>
14 | 	<dict>
15 | 		<key>97019FD51D054ECD00FD6644</key>
16 | 		<dict>
17 | 			<key>primary</key>
18 | 			<true/>
19 | 		</dict>
20 | 		<key>97019FDE1D054ECD00FD6644</key>
21 | 		<dict>
22 | 			<key>primary</key>
23 | 			<true/>
24 | 		</dict>
25 | 		<key>97BE88BD1CDDDAD000240523</key>
26 | 		<dict>
27 | 			<key>primary</key>
28 | 			<true/>
29 | 		</dict>
30 | 		<key>97BE88D11CDDDAD000240523</key>
31 | 		<dict>
32 | 			<key>primary</key>
33 | 			<true/>
34 | 		</dict>
35 | 		<key>97BE88DC1CDDDAD000240523</key>
36 | 		<dict>
37 | 			<key>primary</key>
38 | 			<true/>
39 | 		</dict>
40 | 	</dict>
41 | </dict>
42 | </plist>
43 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  AppDelegate.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 5/7/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 | 
14 |     var window: UIWindow?
15 | 
16 | 
17 |     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 |         // Override point for customization after application launch.
19 |         return true
20 |     }
21 | 
22 |     func applicationWillResignActive(_ application: UIApplication) {
23 |         // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 |         // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 |     }
26 | 
27 |     func applicationDidEnterBackground(_ application: UIApplication) {
28 |         // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 |         // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 |     }
31 | 
32 |     func applicationWillEnterForeground(_ application: UIApplication) {
33 |         // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 |     }
35 | 
36 |     func applicationDidBecomeActive(_ application: UIApplication) {
37 |         // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 |     }
39 | 
40 |     func applicationWillTerminate(_ application: UIApplication) {
41 |         // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 |     }
43 | 
44 | 
45 | }
46 | 
47 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "images" : [
 3 |     {
 4 |       "idiom" : "iphone",
 5 |       "size" : "20x20",
 6 |       "scale" : "2x"
 7 |     },
 8 |     {
 9 |       "idiom" : "iphone",
10 |       "size" : "20x20",
11 |       "scale" : "3x"
12 |     },
13 |     {
14 |       "idiom" : "iphone",
15 |       "size" : "29x29",
16 |       "scale" : "2x"
17 |     },
18 |     {
19 |       "idiom" : "iphone",
20 |       "size" : "29x29",
21 |       "scale" : "3x"
22 |     },
23 |     {
24 |       "idiom" : "iphone",
25 |       "size" : "40x40",
26 |       "scale" : "2x"
27 |     },
28 |     {
29 |       "idiom" : "iphone",
30 |       "size" : "40x40",
31 |       "scale" : "3x"
32 |     },
33 |     {
34 |       "idiom" : "iphone",
35 |       "size" : "60x60",
36 |       "scale" : "2x"
37 |     },
38 |     {
39 |       "idiom" : "iphone",
40 |       "size" : "60x60",
41 |       "scale" : "3x"
42 |     },
43 |     {
44 |       "idiom" : "ipad",
45 |       "size" : "20x20",
46 |       "scale" : "1x"
47 |     },
48 |     {
49 |       "idiom" : "ipad",
50 |       "size" : "20x20",
51 |       "scale" : "2x"
52 |     },
53 |     {
54 |       "idiom" : "ipad",
55 |       "size" : "29x29",
56 |       "scale" : "1x"
57 |     },
58 |     {
59 |       "idiom" : "ipad",
60 |       "size" : "29x29",
61 |       "scale" : "2x"
62 |     },
63 |     {
64 |       "idiom" : "ipad",
65 |       "size" : "40x40",
66 |       "scale" : "1x"
67 |     },
68 |     {
69 |       "idiom" : "ipad",
70 |       "size" : "40x40",
71 |       "scale" : "2x"
72 |     },
73 |     {
74 |       "idiom" : "ipad",
75 |       "size" : "76x76",
76 |       "scale" : "1x"
77 |     },
78 |     {
79 |       "idiom" : "ipad",
80 |       "size" : "76x76",
81 |       "scale" : "2x"
82 |     },
83 |     {
84 |       "idiom" : "ipad",
85 |       "size" : "83.5x83.5",
86 |       "scale" : "2x"
87 |     },
88 |     {
89 |       "idiom" : "ios-marketing",
90 |       "size" : "1024x1024",
91 |       "scale" : "1x"
92 |     }
93 |   ],
94 |   "info" : {
95 |     "version" : 1,
96 |     "author" : "xcode"
97 |   }
98 | }


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/Ball.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  Ball.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 5/26/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | @IBDesignable
12 | class Ball: UIView {
13 | 
14 |     @IBInspectable var cornerRadius: CGFloat = 15 {
15 |         didSet {
16 |             self.layer.cornerRadius = cornerRadius
17 |         }
18 |     }
19 |     
20 | }
21 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 2 | <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8150" systemVersion="15A204g" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
 3 |     <dependencies>
 4 |         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8122"/>
 5 |     </dependencies>
 6 |     <scenes>
 7 |         <!--View Controller-->
 8 |         <scene sceneID="EHf-IW-A2E">
 9 |             <objects>
10 |                 <viewController id="01J-lp-oVM" sceneMemberID="viewController">
11 |                     <layoutGuides>
12 |                         <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
13 |                         <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
14 |                     </layoutGuides>
15 |                     <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
16 |                         <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
17 |                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
18 |                         <animations/>
19 |                         <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
20 |                     </view>
21 |                 </viewController>
22 |                 <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
23 |             </objects>
24 |             <point key="canvasLocation" x="53" y="375"/>
25 |         </scene>
26 |     </scenes>
27 | </document>
28 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/Example1ViewController.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  GravityViewController.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 5/25/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | class Example1ViewController: UIViewController {
12 | 
13 |     
14 |     @IBOutlet var balls: [UIView]!
15 |     
16 |     override func viewDidLoad() {
17 |         super.viewDidLoad()
18 |         
19 |         self.view.backgroundColor = UIColor(red: 0.97,green: 0.97,blue: 0.97,alpha: 1.0)
20 |         
21 |         self.title = "Basic"
22 |     }
23 |     
24 |     override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
25 |         super.touchesBegan(touches, with: event)
26 |         
27 |         let point = touches.first?.location(in: self.view)
28 |         
29 |         for (index,ball) in balls.enumerated() {
30 |             let center = ball.center
31 |             let interval = 0.1 * Double(index)
32 |             
33 |             center.animate(to: point!,
34 |                              duration: 0.8,
35 |                              delay: interval,
36 |                              type: .swiftOut,
37 |                              render: { (p) in
38 |                                 
39 |                             ball.center = p
40 |                                 
41 |                 }, completion: { (f) in
42 |                  
43 |                     ball.backgroundColor?.animate(to: UIColor.red,
44 |                         duration: 1.4,
45 |                         type: .swiftOut,
46 |                         autoreverses: true,
47 |                         render: { (c) in
48 |                             
49 |                         ball.backgroundColor = c
50 |                     })
51 |                     
52 |                     ball.center.snap(to: center, damping: 0.1
53 |                         , render: { (p) in
54 |                             ball.center = p
55 |                     })
56 |             })
57 |         }
58 |     }
59 |     
60 | }
61 | 
62 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/Example2ViewController.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  ViewController.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 5/7/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | class Example2ViewController: UIViewController {
12 |     
13 |    
14 |     @IBOutlet var balls: [UIView]!
15 |     
16 |     var attachment: UIAttachmentBehavior!
17 |     var animator = UIDynamicAnimator()
18 |     
19 |     
20 |     override func viewDidLoad() {
21 |         super.viewDidLoad()
22 |         
23 |         self.view.backgroundColor = UIColor(red: 0.98,green: 0.98,blue: 0.98,alpha: 1.0)
24 |         
25 |         self.title = "Chainable"
26 |     }
27 | 
28 |     override func didReceiveMemoryWarning() {
29 |         super.didReceiveMemoryWarning()
30 |     }
31 | 
32 |     
33 |     override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
34 |         super.touchesBegan(touches, with: event)
35 |         
36 |         for (index, ball) in balls.enumerated() {
37 |             let move = CGFloat(-20 + index * 20)
38 |             let opacity = Float(1 - 0.2 * CGFloat(index))
39 |             let size = CGSize(width: 20 - CGFloat(index) * 5, height: 20 - CGFloat(index) * 5)
40 |             ball.shadowOpacity(opacity).shadowOffset(size).shadowRadius(5).moveX(-move).moveY(-move).shadowColor(UIColor.gray).duration(2).easing(.bounceOut)
41 |                 .then().moveY(move).moveX(move).shadowOpacity(0).shadowOffset(CGSize.zero).shadowColor(UIColor.clear).duration(1).easing(.bounceOut)
42 |                 .completion({
43 |                     print("all completion")
44 |                 }).animate()
45 |         }
46 |         
47 |         
48 |     }
49 |     
50 |     override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
51 |         super.touchesMoved(touches, with: event)
52 |         
53 |     }
54 |     
55 |     
56 | }
57 | 
58 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/Example3ViewController.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  Example3ViewController.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 5/30/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | class Example3ViewController: UIViewController {
12 | 
13 |     @IBOutlet var leftLines: [Ball]!
14 |     @IBOutlet var rightLines: [Ball]!
15 |     
16 |     override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
17 |         super.touchesEnded(touches, with: event)
18 |         
19 |         for (index,line) in leftLines.enumerated() {
20 |             let delay = Double(index) * 0.2
21 |             line.moveX(200).duration(2).delay(delay)
22 |                 .then().moveX(-200).makeColor(UIColor.green).easing(.linear).repeatCount(100).reverses().duration(2).animate()
23 |             line.makeWidth(80).delay(delay).duration(1).reverses().easing(.linear).repeatCount(100).animate()
24 |         }
25 |         
26 |         for (index,line) in rightLines.enumerated() {
27 |             let delay = Double(index) * 0.2
28 |             line.moveX(-200).duration(2).delay(delay)
29 |                 .then().moveX(200).makeColor(UIColor.purple).easing(.linear).repeatCount(100).reverses().duration(2).animate()
30 |             line.makeWidth(80).delay(delay).duration(1).reverses().easing(.linear).repeatCount(100).animate()
31 |         }
32 | 
33 | 
34 |     }
35 | }
36 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/Example4ViewController.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  Example4ViewController.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 6/1/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | class Example4ViewController: UIViewController {
12 |     
13 |     
14 |     @IBOutlet weak var animateView: Ball!
15 |     
16 |     override func viewDidLoad() {
17 |         super.viewDidLoad()
18 |         
19 |     }
20 |     
21 |     override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
22 |         super.touchesEnded(touches, with: event)
23 |         
24 |         animateView.makeSize(CGSize(width: 50, height: 150)).snap(0.3).completion({
25 |                 print("First step")
26 |             })
27 |             .then().moveX(-100).moveY(-50).anchorPoint(CGPoint(x: 1, y: 1)).duration(1).completion({
28 |                 print("Second step!")
29 |             })
30 |             .then().rotate(.pi).attachment(0.3, frequency: 0.8).completion({
31 |                 print("Third step!")
32 |             })
33 |             .then().moveY(500).gravity().completion({
34 |                 print("last step, all completion")
35 |             })
36 |             .animate()
37 |     }
38 | }
39 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/Example5ViewController.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  Example5ViewController.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 6/1/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | class Example5ViewController: UIViewController {
12 | 
13 |     @IBOutlet weak var cyanView: UIView!
14 |     
15 |     override func viewDidLoad() {
16 |         super.viewDidLoad()
17 |        
18 |     }
19 |     
20 |     override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
21 |         super.touchesBegan(touches, with: event)
22 |         
23 |         let rotation: CGFloat = .pi * 20.0
24 |         cyanView.makeSize(CGSize(width: 100, height: 30)).snap()
25 |             .then().moveY(-100).snap(1)
26 |             .then().rotate(rotation)
27 |                    .duration(2)
28 |                    .easing(.swiftOut)
29 |                    .makeHeight(100)
30 |                    .cornerRadius(50)
31 |             .then().moveY(100).gravity()
32 |             .then().moveY(-80)
33 |             .then().moveY(80).gravity()
34 |             .then().moveY(-40)
35 |             .then().moveY(40).gravity()
36 |             .then().makeWidth(120)
37 |                    .makeHeight(30)
38 |                    .cornerRadius(15)
39 |                    .easing(.swiftOut)
40 |                    .makeColor(UIColor.brown)
41 |             .animate()
42 |         
43 |     }
44 |     
45 |     override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
46 |         super.touchesEnded(touches, with: event)
47 |         //will cancel all remaining animations
48 | //        cyanView.cancelAllRemaining()
49 |     }
50 | }
51 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/Example6ViewController.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  Example6ViewController.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 6/1/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | class Example6ViewController: UIViewController {
12 | 
13 |     //should be have more easily APIs to do
14 |     
15 |     @IBOutlet var views: [UIView]!
16 |     var centerItems: [DynamicItemBasic<CGPoint>] = Array()
17 |     var colorItems: [DynamicItemBasic<UIColor>] = Array()
18 |     
19 |     
20 |     override func viewDidLoad() {
21 |         super.viewDidLoad()
22 |         
23 |         for view in views {
24 |             let basic = DynamicItemBasic(from: view.center,to: CGPoint(x: 160, y: 200), render: { (p) in
25 |                 view.center = p
26 |             })
27 |             basic.duration = 1.0
28 |             basic.speed = 0.0
29 |             basic.timingFunction = TimingFunctionType.swiftOut.easing()
30 |             centerItems.append(basic)
31 |             
32 |             let color = view.backgroundColor!
33 |             let basic1 = DynamicItemBasic(from: color, to: UIColor.red, render: { (c) in
34 |                 view.backgroundColor = c
35 |             })
36 |             basic1.duration = 1.0
37 |             basic1.speed = 0.0
38 |             basic1.timingFunction = TimingFunctionType.swiftOut.easing()
39 |             colorItems.append(basic1)
40 | 
41 |         }
42 |         
43 |     }
44 |     
45 |     @IBAction func sliderValueChanged(_ sender: UISlider) {
46 |         let offset = Double(sender.value)
47 |         for item in centerItems {
48 |             item.timeOffset = offset
49 |         }
50 |         
51 |         for item in colorItems {
52 |             item.timeOffset = offset
53 |         }
54 |     }
55 |    
56 | }
57 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/Example7ViewController.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  Example7ViewController.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 6/8/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | class Example7ViewController: UIViewController {
12 | 
13 |     @IBOutlet weak var button: UIButton!
14 |     
15 |     @IBAction func loadFromJSON(_ sender: AnyObject) {
16 |         
17 |     }
18 | }
19 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/Example8ViewController.swift:
--------------------------------------------------------------------------------
  1 | //
  2 | //  Example8ViewController.swift
  3 | //  StellarDemo
  4 | //
  5 | //  Created by AugustRush on 6/29/16.
  6 | //  Copyright © 2016 August. All rights reserved.
  7 | //
  8 | 
  9 | import UIKit
 10 | 
 11 | class Example8ViewController: UIViewController {
 12 |     @IBOutlet weak var animateView: Ball!
 13 |     
 14 |     @IBAction func segment1ValueChanged(_ sender: UISegmentedControl) {
 15 |         
 16 |         let index = sender.selectedSegmentIndex;
 17 |         
 18 |         switch index {
 19 |         case 0:
 20 |             animateView.moveX(200).duration(1.0).easing(.default).reverses().animate()
 21 |         case 1:
 22 |             animateView.moveX(200).duration(1.0).easing(.easeIn).reverses().animate()
 23 |         case 2:
 24 |             animateView.moveX(200).duration(1.0).easing(.easeOut).reverses().animate()
 25 |         case 3:
 26 |             animateView.moveX(200).duration(1.0).easing(.easeInEaseOut).reverses().animate()
 27 |         default:
 28 |             print("")
 29 |         }
 30 |         
 31 |     }
 32 |     @IBAction func segment2ValueChanged(_ sender: UISegmentedControl) {
 33 |         animateView.frame = CGRect(x: 20,y: 120,width: 40,height: 40)
 34 |         let index = sender.selectedSegmentIndex;
 35 |         
 36 |         switch index {
 37 |         case 0:
 38 |             animateView.moveX(200).duration(1.0).easing(.linear).reverses().animate()
 39 |         case 1:
 40 |             animateView.moveX(200).duration(1.0).easing(.swiftOut).reverses().animate()
 41 |         case 2:
 42 |             animateView.moveX(200).duration(1.0).easing(.backEaseIn).reverses().animate()
 43 |         case 3:
 44 |             animateView.moveX(200).duration(1.0).easing(.backEaseOut).reverses().animate()
 45 |         default:
 46 |             print("")
 47 |         }
 48 | 
 49 |     }
 50 |     @IBAction func segment3ValueChanged(_ sender: UISegmentedControl) {
 51 |         animateView.frame = CGRect(x: 20,y: 120,width: 40,height: 40)
 52 |         let index = sender.selectedSegmentIndex;
 53 |         
 54 |         switch index {
 55 |         case 0:
 56 |             animateView.moveX(200).duration(1.0).easing(.backEaseInOut).reverses().animate()
 57 |         case 1:
 58 |             animateView.moveX(200).duration(1.0).easing(.bounceOut).reverses().animate()
 59 |         case 2:
 60 |             animateView.moveX(200).duration(1.0).easing(.sine).reverses().animate()
 61 |         case 3:
 62 |             animateView.moveX(200).duration(1.0).easing(.circ).reverses().animate()
 63 |         default:
 64 |             print("")
 65 |         }
 66 | 
 67 |     }
 68 |     
 69 |     @IBAction func segment4ValueChanged(_ sender: UISegmentedControl) {
 70 |         animateView.frame = CGRect(x: 20,y: 120,width: 40,height: 40)
 71 |         let index = sender.selectedSegmentIndex;
 72 |         
 73 |         switch index {
 74 |         case 0:
 75 |             animateView.moveX(200).duration(1.0).easing(.exponentialIn).reverses().animate()
 76 |         case 1:
 77 |             animateView.moveX(200).duration(1.0).easing(.exponentialOut).reverses().animate()
 78 |         case 2:
 79 |             animateView.moveX(200).duration(1.0).easing(.elasticIn).reverses().animate()
 80 |         case 3:
 81 |             animateView.moveX(200).duration(1.0).easing(.elasticOut).reverses().animate()
 82 |         default:
 83 |             print("")
 84 |         }
 85 |         
 86 |     }
 87 |     
 88 |     @IBAction func segment5ValueChanged(_ sender: UISegmentedControl) {
 89 |         animateView.frame = CGRect(x: 20,y: 120,width: 40,height: 40)
 90 |         let index = sender.selectedSegmentIndex;
 91 |         
 92 |         switch index {
 93 |         case 0:
 94 |             animateView.moveX(200).duration(1.0).easing(.bounceReverse).reverses().animate()
 95 |         case 1:
 96 |             100.0.animate(to: 200, duration: 1.0, delay: 0.0, type: .swiftOut, autoreverses: false, repeatCount: 0, render: { (d) in
 97 |                 print("current value is \(d)")
 98 |             }, completion: nil)
 99 |         case 2:
100 |             100.0.attachment(to: 200, render: { (d) in
101 |                 print("current value is \(d)")
102 |             })
103 |             
104 |         case 3:
105 |             fallthrough
106 |         default:
107 |             print("")
108 |         }
109 |         
110 |     }
111 | }
112 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/Info.plist:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 3 | <plist version="1.0">
 4 | <dict>
 5 | 	<key>CFBundleDevelopmentRegion</key>
 6 | 	<string>en</string>
 7 | 	<key>CFBundleExecutable</key>
 8 | 	<string>$(EXECUTABLE_NAME)</string>
 9 | 	<key>CFBundleIdentifier</key>
10 | 	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11 | 	<key>CFBundleInfoDictionaryVersion</key>
12 | 	<string>6.0</string>
13 | 	<key>CFBundleName</key>
14 | 	<string>$(PRODUCT_NAME)</string>
15 | 	<key>CFBundlePackageType</key>
16 | 	<string>APPL</string>
17 | 	<key>CFBundleShortVersionString</key>
18 | 	<string>1.0</string>
19 | 	<key>CFBundleSignature</key>
20 | 	<string>????</string>
21 | 	<key>CFBundleVersion</key>
22 | 	<string>1</string>
23 | 	<key>LSRequiresIPhoneOS</key>
24 | 	<true/>
25 | 	<key>UILaunchStoryboardName</key>
26 | 	<string>LaunchScreen</string>
27 | 	<key>UIMainStoryboardFile</key>
28 | 	<string>Main</string>
29 | 	<key>UIRequiredDeviceCapabilities</key>
30 | 	<array>
31 | 		<string>armv7</string>
32 | 	</array>
33 | 	<key>UISupportedInterfaceOrientations</key>
34 | 	<array>
35 | 		<string>UIInterfaceOrientationPortrait</string>
36 | 		<string>UIInterfaceOrientationLandscapeLeft</string>
37 | 		<string>UIInterfaceOrientationLandscapeRight</string>
38 | 	</array>
39 | 	<key>UISupportedInterfaceOrientations~ipad</key>
40 | 	<array>
41 | 		<string>UIInterfaceOrientationPortrait</string>
42 | 		<string>UIInterfaceOrientationPortraitUpsideDown</string>
43 | 		<string>UIInterfaceOrientationLandscapeLeft</string>
44 | 		<string>UIInterfaceOrientationLandscapeRight</string>
45 | 	</array>
46 | </dict>
47 | </plist>
48 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/LiquidView.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  LiquidView.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 6/3/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | class LiquidView: UIView {
12 | 
13 |     override class func layerClass() -> AnyClass {
14 |         return CAShapeLayer.self
15 |     }
16 |     
17 | }
18 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Contents.swift:
--------------------------------------------------------------------------------
 1 | 
 2 | import UIKit
 3 | import PlaygroundSupport
 4 | 
 5 | let container = UIView(frame: CGRect.init(x: 0, y: 0, width: 600, height: 600))
 6 | 
 7 | container.backgroundColor = UIColor(red: 0.97,green: 0.97,blue: 0.97,alpha: 1.0)
 8 | 
 9 | //var balls: [Ball] = Array()
10 | //for i in 0...5 {
11 | //    let ball = Ball(frame: CGRectMake(10,10 + 60 * CGFloat(i),50,50))
12 | //    ball.backgroundColor = UIColor.redColor()
13 | //    container.addSubview(ball)
14 | //    balls.append(ball)
15 | //    
16 | //    ball.moveX(200).duration(2)
17 | //        .delay(Double(i) * 0.1).repeatCount(1)
18 | //        .autoreverses()
19 | //        .animate()
20 | //    
21 | //    ball.makeWidth(200).duration(2).autoreverses().animate()
22 | //}
23 | 
24 | let ball = Ball(frame: CGRect.init(x: 100, y: 100, width: 25, height: 25))
25 | ball.backgroundColor = UIColor.cyan
26 | container.addSubview(ball)
27 | 
28 | //ball.moveX(100).moveY(100).duration(2.5)
29 | //    .then().makeColor(UIColor.purple)
30 | //    .animate()
31 | 
32 | ball.moveX(100).moveY(100).delay(0.5).duration(2)
33 |     .then().makeWidth(160).duration(2).anchorPoint(CGPoint.init(x: 0, y: 0.5))
34 |     .then().rotate(1.5).snap(0.2)
35 |     .then().moveY(500).gravity(100)
36 |     .animate()
37 | 
38 | //let rotation: CGFloat = CGFloat(M_PI) * 20.0
39 | //ball.makeSize(CGSizeMake(100, 30)).gravity()
40 | //    .then().moveY(-100).snap(1)
41 | //    .then().rotate(rotation).duration(2).easing(.SwiftOut).makeHeight(100).cornerRadius(50)
42 | //    .then().moveY(100).gravity()
43 | //    .then().moveY(-80)
44 | //    .then().moveY(80).gravity()
45 | //    .then().moveY(-40)
46 | //    .then().moveY(40).gravity()
47 | //    .then().makeWidth(120).makeHeight(30).cornerRadius(15).easing(.SwiftOut).makeColor(UIColor.brownColor())
48 | //    .animate()
49 | 
50 | /**
51 |  *  @brief Easing Curve
52 |  *
53 |  *  @param 200 move foreard
54 |  */
55 | //ball.moveX(200).easing(.BounceOut).delay(0.5).duration(1).animate()
56 | //ball.moveX(200).easing(.ElasticIn).delay(0.5).duration(1).animate()
57 | //ball.moveX(200).easing(.ElasticOut).delay(0.5).duration(1).animate()
58 | //ball.moveX(200).easing(.Sine).delay(0.5).duration(1).animate()
59 | //ball.moveX(200).easing(.Circ).delay(0.5).duration(1).animate()
60 | //ball.moveX(200).easing(.ExponentialOut).delay(0.5).duration(1).animate()
61 | //ball.moveX(200).easing(.ExponentialIn).delay(0.5).duration(1).animate()
62 | 
63 | ball.moveX(200).easing(.bounceReverse).delay(0.5).duration(3).autoreverses().animate()
64 | 
65 | PlaygroundPage.current.liveView = container
66 | 
67 | //basic curve
68 | 
69 | 100.0.animate(to: 300, duration: 1, delay: 0.0, type: .custom(0.0, 1.39, 1.0, -0.55), autoreverses: false, repeatCount: 0, render: { (d) in
70 |     let y = d
71 |     }, completion: nil)
72 | 
73 | 
74 | 100.0.pushed(to: 300, render: { (d) in
75 |     let y = d
76 |     }, completion: nil)
77 | 
78 | 
79 | 100.0.snap(to: 150, damping: 0.8, render: { (d) in
80 |     let t = d
81 |     }, completion: nil)
82 | 
83 | 100.0.attachment(to: 200, damping: 0.3, frequency: 1, render: { (d) in
84 |     let y = d
85 |     }, completion: nil)
86 | 
87 | //100.0.fallTo(200, magnitude: 0.6, render: { (d) in
88 | //    let y = d
89 | //    }, completion: nil)
90 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Ball.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  Ball.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 5/26/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | @IBDesignable
12 | public class Ball: UIView {
13 | 
14 |     @IBInspectable var cornerRadius: CGFloat = 15 {
15 |         didSet {
16 |             self.layer.cornerRadius = cornerRadius
17 |         }
18 |     }
19 |     
20 | }
21 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/AnimationContext.swift:
--------------------------------------------------------------------------------
  1 | //Copyright (c) 2016
  2 | //
  3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  4 | //
  5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  6 | //
  7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  8 | 
  9 | import UIKit
 10 | 
 11 | internal class AnimationContext: NSObject, UIDynamicAnimatorDelegate, AnimationSequenceDelegate {
 12 |     fileprivate weak var object: DriveAnimateBehaviors!
 13 |     fileprivate var mutipleSequences = [AnimationSequence]()
 14 |     
 15 |     //MARK: init method
 16 |     init(object: DriveAnimateBehaviors) {
 17 |         self.object = object
 18 |     }
 19 |     
 20 |     //MARK: public methods
 21 |     func addAnimationType(_ type: AnimationType) {
 22 |         let step = lastStep()
 23 |         step.types.append(type)
 24 |     }
 25 |     
 26 |     func changeDuration(_ d: CFTimeInterval) {
 27 |         let step = lastStep()
 28 |         step.duration = d
 29 |     }
 30 |     
 31 |     func changeDelay(_ d: CFTimeInterval) {
 32 |         let step = lastStep()
 33 |         step.delay = d
 34 |     }
 35 |     
 36 |     func changeAutoreverses(_ a: Bool) {
 37 |         let step = lastStep()
 38 |         step.autoreverses = a
 39 |     }
 40 |     
 41 |     func changeRepeatCount(_ count: Int) {
 42 |         let step = lastStep()
 43 |         step.repeatCount = count
 44 |     }
 45 |     
 46 |     func changeCompletion(_ c: @escaping () -> Void) {
 47 |         let step = lastStep()
 48 |         step.completion = c
 49 |     }
 50 |     
 51 |     func changeEasing(_ e: TimingFunctionType) {
 52 |         let step = lastStep()
 53 |         step.timing = e
 54 |     }
 55 |     
 56 |     func changeMainType(_ type: AnimationStyle) {
 57 |         let step = lastStep()
 58 |         let lastAnimationType = step.types.last
 59 |         guard let _ = lastAnimationType else {
 60 |             print("You should defined animaton first!")
 61 |             return
 62 |         }
 63 |         
 64 |         lastAnimationType!.mainType = type
 65 |     }
 66 |     
 67 |     func makeNextStep() {
 68 |         let step = AnimationStep()
 69 |         lastSequence().addStep(step)
 70 |     }
 71 |     
 72 |     @discardableResult
 73 |     func makeNextSequence() -> AnimationSequence {
 74 |         let sequence = AnimationSequence(object: self.object)
 75 |         sequence.delegate = self
 76 |         mutipleSequences.append(sequence)
 77 |         
 78 |         return sequence
 79 |     }
 80 |     
 81 |     func commit() {
 82 |         //start all sequence
 83 |         for sequence in mutipleSequences {
 84 |             sequence.start()
 85 |         }
 86 |         //make a temple sequence for next step
 87 |         makeNextSequence()
 88 |     }
 89 |     
 90 |     func removeAllRemaining() {
 91 |         for sequence in mutipleSequences {
 92 |             sequence.removeAllSteps()
 93 |         }
 94 |         mutipleSequences.removeAll()
 95 |     }
 96 |     
 97 |     
 98 |     //MARK: private methods
 99 |     
100 |     fileprivate func lastSequence() -> AnimationSequence {
101 |         var sequence = mutipleSequences.last
102 |         if sequence == nil {
103 |             sequence = makeNextSequence()
104 |         }
105 | 
106 |         return sequence!
107 |     }
108 |     
109 |     fileprivate func lastStep() -> AnimationStep {
110 |         let sequence = lastSequence()
111 |         var step = sequence.last()
112 |         if step == nil {
113 |             step = AnimationStep()
114 |             sequence.addStep(step!)
115 |         }
116 |         return step!
117 |     }
118 |     
119 |     //MARK: AnimationSequenceDelegate methods
120 |     
121 |     func animationSequenceDidComplete(_ sequence: AnimationSequence) {
122 |         let index = mutipleSequences.index(of: sequence)
123 |         if index != nil {
124 |             mutipleSequences.remove(at: index!)
125 |         }
126 |     }
127 | }
128 | 
129 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/AnimationSequence.swift:
--------------------------------------------------------------------------------
  1 | //Copyright (c) 2016
  2 | //
  3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  4 | //
  5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  6 | //
  7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  8 | 
  9 | import UIKit
 10 | 
 11 | protocol AnimationSequenceDelegate: class {
 12 |     func animationSequenceDidComplete(_ sequence: AnimationSequence);
 13 | }
 14 | 
 15 | internal class AnimationSequence: NSObject, UIDynamicAnimatorDelegate {
 16 |     var steps: [AnimationStep] = Array()
 17 |     weak var view: DriveAnimateBehaviors!
 18 |     weak var delegate: AnimationSequenceDelegate?
 19 |     var isRuning = false
 20 |     lazy var animator: UIDynamicAnimator = {
 21 |         let animator = UIDynamicAnimator()
 22 |         animator.delegate = self
 23 |         return animator
 24 |     }()
 25 |     
 26 |     //MARK: init method
 27 |     
 28 |     init(object: DriveAnimateBehaviors) {
 29 |         self.view = object
 30 |     }
 31 |     
 32 |     //MARK: internal method
 33 |     func addStep(_ step: AnimationStep) {
 34 |         steps.append(step)
 35 |     }
 36 |     
 37 |     func last() -> AnimationStep? {
 38 |         return steps.last
 39 |     }
 40 |     
 41 |     func start() {
 42 |         if !isRuning {
 43 |             isRuning = true
 44 |             excuteFirstStepIfExist()
 45 |         }
 46 |     }
 47 |     
 48 |     func removeAllSteps() {
 49 |         steps.removeAll()
 50 |     }
 51 |     
 52 |     fileprivate func excuteFirstStepIfExist() {
 53 |         
 54 |         if self.view == nil {
 55 |             return
 56 |         }
 57 |         
 58 |         let step = steps.first
 59 |         
 60 |         if let step = step {
 61 |             //if step has no animation types it must be the last temple step
 62 |             if step.types.count == 0 {
 63 |                 steps.removeFirst()
 64 |                 popFirstStepIfExsist()
 65 |                 return
 66 |             }
 67 |             
 68 |             for type in step.types {
 69 |                 let behavior = view.behavior(forType: type, step: step)
 70 |                 animator.addBehavior(behavior)
 71 |             }
 72 |             
 73 |         } else {
 74 |             popFirstStepIfExsist()
 75 |         }
 76 |     }
 77 |     
 78 |     fileprivate func popFirstStepIfExsist() {
 79 |         if !steps.isEmpty {
 80 |             let step = steps.first!
 81 |             //excute completion
 82 |             step.completion?()
 83 |             steps.removeFirst()
 84 |         } else {
 85 |             // all steps has completion
 86 |             self.delegate?.animationSequenceDidComplete(self)
 87 |         }
 88 |     }
 89 |     
 90 |     //MARK: UIDynamicAnimatorDelegate methods
 91 |     func dynamicAnimatorDidPause(_ animator: UIDynamicAnimator) {
 92 |         animator.removeAllBehaviors()
 93 |         popFirstStepIfExsist()
 94 |         excuteFirstStepIfExist()
 95 |     }
 96 |     
 97 |     func dynamicAnimatorWillResume(_ animator: UIDynamicAnimator) {
 98 |         
 99 |     }
100 | }
101 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/AnimationStep.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | internal class AnimationStep {
12 |     var types = [AnimationType]()
13 |     var duration: CFTimeInterval = 0.25
14 |     var timing: TimingFunctionType = .default
15 |     var delay: CFTimeInterval = 0.0
16 |     var autoreverses: Bool = false
17 |     var repeatCount: Int = 0
18 |     var completion: (() -> Void)?
19 | }
20 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/AnimationType.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | enum AnimationSubType {
12 |     case moveX(CGFloat)
13 |     case moveY(CGFloat)
14 |     case moveXY(CGFloat,CGFloat)//Layer
15 |     case moveTo(CGPoint)
16 |     case color(UIColor)
17 |     case alpha(CGFloat)
18 |     case opacity(Float)//Layer
19 |     case rotateX(CGFloat)
20 |     case rotateY(CGFloat)
21 |     case rotate(CGFloat)
22 |     case rotateXY(CGFloat)
23 |     case width(CGFloat)
24 |     case height(CGFloat)
25 |     case size(CGSize)
26 |     case frame(CGRect)
27 |     case bounds(CGRect)
28 |     case scaleX(CGFloat)
29 |     case scaleY(CGFloat)
30 |     case scaleXY(CGFloat,CGFloat)
31 |     case cornerRadius(CGFloat)
32 |     case borderWidth(CGFloat)
33 |     case shadowRadius(CGFloat)
34 |     case zPosition(CGFloat)
35 |     case anchorPoint(CGPoint)
36 |     case anchorPointZ(CGFloat)
37 |     case shadowOffset(CGSize)
38 |     case shadowColor(UIColor)
39 |     case shadowOpacity(Float)
40 |     case tintColor(UIColor)
41 | //    UILabel,UITextView...
42 | //    case TextColor(UIColor)
43 | }
44 | 
45 | //temp record for animation type
46 | internal class AnimationType {
47 |     var mainType: AnimationStyle
48 |     var subType: AnimationSubType
49 |     
50 |     init (type: AnimationStyle, subType: AnimationSubType) {
51 |         self.mainType = type
52 |         self.subType = subType
53 |     }
54 | }
55 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/AnimatorCoordinator.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | internal class AnimatorCoordinator: NSObject, UIDynamicAnimatorDelegate {
12 |     static let shared = AnimatorCoordinator()
13 |     fileprivate var activedAnimators: [UIDynamicAnimator] = Array()
14 |     fileprivate var basicAnimator = UIDynamicAnimator()
15 |     
16 |     //MARK: public methods    
17 |     func addBasicBehavior(_ b: UIDynamicBehavior) {
18 |         basicAnimator.addBehavior(b)
19 |     }
20 |     func addBehavior(_ b: UIDynamicBehavior) {
21 |         addBehaviors([b])
22 |     }
23 |     
24 |     func addBehaviors(_ behaviors: [UIDynamicBehavior]) {
25 |         
26 |         let animator = activedAnimators.last
27 |         for b in behaviors {
28 |             
29 |             if let exsist = animator {
30 |                 switch b {
31 |                 case b as UIGravityBehavior:
32 |                     fallthrough
33 |                 case b as UICollisionBehavior:
34 |                     createAnimator(b)
35 |                 default:
36 |                     exsist.addBehavior(b)
37 |                 }
38 |    
39 |             } else {
40 |                 createAnimator(b)
41 |             }
42 |         }
43 |     }
44 |     
45 |     fileprivate func createAnimator(_ behavior: UIDynamicBehavior) {
46 |         let animator = UIDynamicAnimator()
47 |         animator.delegate = self
48 |         animator.addBehavior(behavior)
49 |         activedAnimators.append(animator)
50 |     }
51 | 
52 |     
53 |     //MARK: UIDynamicAnimatorDelegate methods
54 |     
55 |     func dynamicAnimatorDidPause(_ animator: UIDynamicAnimator) {
56 |         let index = activedAnimators.index(of: animator)
57 |         activedAnimators.remove(at: index!)
58 |     }
59 |     
60 |     func dynamicAnimatorWillResume(_ animator: UIDynamicAnimator) {
61 |         //
62 |     }
63 | }
64 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/AttachmentConfigurable.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | public protocol AttachmentConfigurable: BasicChainable {
12 |     func attachment(_ damping: CGFloat, frequency: CGFloat) -> AttachmentConfigurable
13 | }
14 | 
15 | public protocol AttachmentConfigurable1: BasicChainable1 {
16 |     func attachment(_ damping: CGFloat, frequency: CGFloat) -> AttachmentConfigurable1
17 | }
18 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/BasicChainable.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | public protocol BasicChainable: Chainable {
12 |     func moveX(_ increment: CGFloat) -> UIView
13 |     func moveY(_ increment: CGFloat) -> UIView
14 |     func moveTo(_ point: CGPoint) -> UIView
15 |     func makeColor(_ color: UIColor) -> UIView
16 |     func makeAlpha(_ alpha: CGFloat) -> UIView
17 |     func rotate(_ z: CGFloat) -> UIView
18 |     func rotateX(_ x: CGFloat) -> UIView
19 |     func rotateY(_ y: CGFloat) -> UIView
20 |     func rotateXY(_ xy: CGFloat) -> UIView
21 |     func makeWidth(_ width: CGFloat) -> UIView
22 |     func makeHeight(_ height: CGFloat) -> UIView
23 |     func makeSize(_ size: CGSize) -> UIView
24 |     func makeFrame(_ frame: CGRect) -> UIView
25 |     func makeBounds(_ bounds: CGRect) -> UIView
26 |     func scaleX(_ x: CGFloat) -> UIView
27 |     func scaleY(_ y: CGFloat) -> UIView
28 |     func scaleXY(_ x: CGFloat, _ y: CGFloat) -> UIView
29 |     func cornerRadius(_ radius: CGFloat) -> UIView
30 |     func borderWidth(_ width: CGFloat) -> UIView
31 |     func shadowRadius(_ radius: CGFloat) -> UIView
32 |     func zPosition(_ position: CGFloat) -> UIView
33 |     func anchorPoint(_ point: CGPoint) -> UIView
34 |     func anchorPointZ(_ z: CGFloat) -> UIView
35 |     func shadowOffset(_ offset: CGSize) -> UIView
36 |     func shadowColor(_ color: UIColor) -> UIView
37 |     func shadowOpacity(_ opacity: Float) -> UIView
38 |     func makeTintColor(_ color: UIColor) -> UIView
39 |     func completion(_ c: @escaping () -> Void) -> UIView
40 | }
41 | 
42 | //CALayer
43 | public protocol BasicChainable1: Chainable1 {
44 |     func moveTo(_ point: CGPoint) -> CALayer
45 |     func makeColor(_ color: UIColor) -> CALayer
46 |     func makeOpacity(_ opacity: Float) -> CALayer
47 |     func rotate(_ z: CGFloat) -> CALayer
48 |     func rotateX(_ x: CGFloat) -> CALayer
49 |     func rotateY(_ y: CGFloat) -> CALayer
50 |     func rotateXY(_ xy: CGFloat) -> CALayer
51 |     func makeWidth(_ width: CGFloat) -> CALayer
52 |     func makeHeight(_ height: CGFloat) -> CALayer
53 |     func makeSize(_ size: CGSize) -> CALayer
54 |     func makeFrame(_ frame: CGRect) -> CALayer
55 |     func makeBounds(_ bounds: CGRect) -> CALayer
56 |     func scaleX(_ x: CGFloat) -> CALayer
57 |     func scaleY(_ y: CGFloat) -> CALayer
58 |     func scaleXY(_ x: CGFloat, _ y: CGFloat) -> CALayer
59 |     func cornerRadius(_ radius: CGFloat) -> CALayer
60 |     func borderWidth(_ width: CGFloat) -> CALayer
61 |     func shadowRadius(_ radius: CGFloat) -> CALayer
62 |     func zPosition(_ position: CGFloat) -> CALayer
63 |     func anchorPoint(_ point: CGPoint) -> CALayer
64 |     func anchorPointZ(_ z: CGFloat) -> CALayer
65 |     func shadowOffset(_ offset: CGSize) -> CALayer
66 |     func shadowColor(_ color: UIColor) -> CALayer
67 |     func shadowOpacity(_ opacity: Float) -> CALayer
68 |     func completion(_ c: @escaping () -> Void) -> CALayer
69 | }
70 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/BasicConfigurable.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | public protocol BasicConfigurable: BasicChainable {
12 |     func duration(_ d: CFTimeInterval) -> BasicConfigurable
13 |     func easing(_ type: TimingFunctionType) -> BasicConfigurable
14 |     func delay(_ d: CFTimeInterval) -> BasicConfigurable
15 |     func reverses() -> BasicConfigurable
16 |     func repeatCount(_ count: Int) -> BasicConfigurable
17 | }
18 | 
19 | //CALayer
20 | public protocol BasicConfigurable1: BasicChainable1 {
21 |     func duration(_ d: CFTimeInterval) -> BasicConfigurable1
22 |     func easing(_ type: TimingFunctionType) -> BasicConfigurable1
23 |     func delay(_ d: CFTimeInterval) -> BasicConfigurable1
24 |     func reverses() -> BasicConfigurable1
25 |     func repeatCount(_ count: Int) -> BasicConfigurable1
26 | }
27 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/CALayer+DriveAnimationBehaviors.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  CALayer+DriveAnimationBehaviors.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 6/21/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import Foundation
10 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/Chainable.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | public protocol Chainable {
12 |     //Chainable methods
13 |     func then() -> UIView
14 |     func animate() -> Void
15 | }
16 | 
17 | //CALayer
18 | public protocol Chainable1 {
19 |     //Chainable methods
20 |     func then() -> CALayer
21 |     func animate() -> Void
22 | }
23 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/DriveAnimateBehaviors.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  DriveAnimateBehaviors.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 6/21/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | protocol DriveAnimateBehaviors: class {
12 |     func behavior(forType type: AnimationType, step: AnimationStep) -> UIDynamicBehavior
13 | }
14 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/DynamicItem+Behavior.swift:
--------------------------------------------------------------------------------
  1 | //Copyright (c) 2016
  2 | //
  3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  4 | //
  5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  6 | //
  7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  8 | 
  9 | import UIKit
 10 | 
 11 | enum PhysicalDirection {
 12 |     case left
 13 |     case right
 14 |     case up
 15 |     case down
 16 |     case Angle(CGFloat)
 17 |     case vector(CGFloat,CGFloat)
 18 |     
 19 |     func angle() -> CGFloat {
 20 |         switch self {
 21 |         case .Angle(let a):
 22 |             return a
 23 |         case .vector(let x, let y):
 24 |             return atan2(y, x)
 25 |         case .left:
 26 |             return atan2(0, -1)
 27 |         case .right:
 28 |             return atan2(0, 1)
 29 |         case .up: 
 30 |             return atan2(-1, 0)
 31 |         case .down: 
 32 |             return atan2(1, 0)
 33 |         }
 34 |     }
 35 | }
 36 | 
 37 | extension UIDynamicItem {
 38 |     
 39 |     //gravity
 40 |     func gravityBehavior(_ magnitude: CGFloat = 1.0, direction: PhysicalDirection = .down) -> UIGravityBehavior {
 41 |         let gravity = UIGravityBehavior()
 42 |         switch direction {
 43 |         case .Angle(let a):
 44 |             gravity.setAngle(a, magnitude: magnitude)
 45 |         case .left:
 46 |             gravity.gravityDirection = CGVector(dx: -1, dy: 0)
 47 |         case .right:
 48 |             gravity.gravityDirection = CGVector(dx: 1, dy: 0)
 49 |         case .up:
 50 |             gravity.gravityDirection = CGVector(dx: 0, dy: -1)
 51 |         case .down:
 52 |             gravity.gravityDirection = CGVector(dx: 0, dy: 1)
 53 |         case .vector(let x, let y):
 54 |             gravity.gravityDirection = CGVector(dx: x, dy: y)
 55 |         }
 56 |         gravity.magnitude = magnitude
 57 |         gravity.addItem(self)
 58 |         return gravity
 59 |     }
 60 | 
 61 |     //snap
 62 |     func snapBehavior(_ toPoint: CGPoint, damping: CGFloat = 0.5) -> UISnapBehavior {
 63 |         let snap = UISnapBehavior(item: self,snapTo: toPoint)
 64 |         snap.damping = damping
 65 |         return snap
 66 |     }
 67 |     
 68 |     //attachment
 69 |     func attachmentBehavior(_ toAnchor: CGPoint, length: CGFloat = 0.0, damping: CGFloat = 0.5, frequency: CGFloat = 1.0) -> UIAttachmentBehavior {
 70 |         let attachment = UIAttachmentBehavior(item: self,attachedToAnchor: toAnchor)
 71 |         attachment.length = length
 72 |         attachment.damping = damping
 73 |         attachment.frequency = frequency
 74 |         return attachment
 75 |     }
 76 |     
 77 |     func attachmentBehavior(_ toItem: UIDynamicItem, damping: CGFloat = 0.5, frequency: CGFloat = 1.0) -> UIAttachmentBehavior {
 78 |         let attachment = UIAttachmentBehavior(item: self,attachedTo: toItem)
 79 |         attachment.damping = damping
 80 |         attachment.frequency = frequency
 81 |         return attachment
 82 |     }
 83 |     
 84 |     func attachmentBehavior(_ toItem: UIDynamicItem, damping: CGFloat = 0.5, frequency: CGFloat = 1.0, length: CGFloat = 0.0) -> UIAttachmentBehavior {
 85 |         let attachment = UIAttachmentBehavior(item: self,attachedTo: toItem)
 86 |         attachment.damping = damping
 87 |         attachment.length = length
 88 |         attachment.frequency = frequency
 89 |         return attachment
 90 |     }
 91 |     
 92 |     //push
 93 |     func pushBehavior(_ direction: CGVector, mode:UIPushBehaviorMode = .instantaneous, magnitude: CGFloat = 1.0) -> UIPushBehavior {
 94 |         let push = UIPushBehavior(items: [self], mode: mode)
 95 |         push.pushDirection = direction
 96 |         push.magnitude = magnitude
 97 |         return push
 98 |     }
 99 |     
100 |     func pushBehavior(_ direction: PhysicalDirection, mode:UIPushBehaviorMode = .instantaneous, magnitude: CGFloat = 1.0) -> UIPushBehavior {
101 |         let push = UIPushBehavior(items: [self], mode: mode)
102 |         switch direction {
103 |         case .Angle(let a):
104 |             push.setAngle(a, magnitude: magnitude)
105 |         case .left:
106 |             push.pushDirection = CGVector(dx: -1, dy: 0)
107 |         case .right:
108 |             push.pushDirection = CGVector(dx: 1, dy: 0)
109 |         case .up:
110 |             push.pushDirection = CGVector(dx: 0, dy: -1)
111 |         case .down:
112 |             push.pushDirection = CGVector(dx: 0, dy: 1)
113 |         case .vector(let x, let y):
114 |             push.pushDirection = CGVector(dx: x, dy: y)
115 |         }
116 |         
117 |         push.magnitude = magnitude
118 |         return push
119 |     }
120 | 
121 |     
122 |     func pushBehavior(_ angle: CGFloat, mode:UIPushBehaviorMode = .instantaneous, magnitude: CGFloat = 1.0) -> UIPushBehavior {
123 |         let push = UIPushBehavior(items: [self], mode: mode)
124 |         push.angle = angle
125 |         push.magnitude = magnitude
126 |         return push
127 |     }
128 |     
129 |     //collision
130 |     func collisionBehavior(_ mode: UICollisionBehaviorMode = .boundaries) -> UICollisionBehavior {
131 |         let collision = UICollisionBehavior()
132 |         collision.collisionMode = mode
133 |         collision.addItem(self)
134 |         return collision
135 |     }
136 |     
137 |     func collisionBehavior(_ mode: UICollisionBehaviorMode = .boundaries, path: UIBezierPath) -> UICollisionBehavior {
138 |         let collision = UICollisionBehavior()
139 |         collision.collisionMode = mode
140 |         let identifier = String(describing: Unmanaged.passUnretained(self).toOpaque())
141 |         collision.addBoundary(withIdentifier: identifier as NSCopying, for: path)
142 |         collision.addItem(self)
143 |         return collision
144 |     }
145 |     
146 |     func collisionBehavior(_ mode: UICollisionBehaviorMode = .boundaries, fromPoint: CGPoint, toPoint: CGPoint) -> UICollisionBehavior {
147 |         let collision = UICollisionBehavior()
148 |         collision.collisionMode = mode
149 |         let identifier = String(describing: Unmanaged.passUnretained(self).toOpaque())
150 |         collision.addBoundary(withIdentifier: identifier as NSCopying, from: fromPoint, to: toPoint)
151 |         collision.addItem(self)
152 |         return collision
153 |     }
154 |     
155 |     //itemBehavior
156 |     func itemBehavior(_ elasticity: CGFloat = 0.5, friction: CGFloat = 0.5, density: CGFloat = 1, resistance: CGFloat = 0, angularResistance: CGFloat = 0, allowsRotation: Bool = true) -> UIDynamicItemBehavior {
157 |         let behavior = UIDynamicItemBehavior()
158 |         behavior.addItem(self)
159 |         behavior.elasticity = elasticity
160 |         behavior.friction = friction
161 |         behavior.density = density
162 |         behavior.resistance = resistance
163 |         behavior.angularResistance = angularResistance
164 |         behavior.allowsRotation = allowsRotation
165 |         return behavior
166 |     }
167 | }
168 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/DynamicItem.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | //for 4 latitude
12 | final class DynamicItem<T: Vectorial>: NSObject, UIDynamicItem {
13 |     
14 |     var from: T
15 |     var to: T
16 |     var render: (T) -> Void
17 |     var complete = false
18 |     var boundaryLimit = false
19 |     var completion: (() -> Void)?
20 |     internal var fromR: Vector4
21 |     internal var toR: Vector4
22 |     weak var behavior: UIDynamicBehavior!
23 |     fileprivate var change: (x: Double,y: Double,z: Double,w: Double)
24 |     var referenceChangeLength: Double
25 |     
26 |     init(from: T, to: T, render: @escaping (T) -> Void) {
27 |         self.from = from
28 |         self.to = to
29 |         self.render = render
30 |         //
31 |         self.fromR = from.reverse()
32 |         self.toR = to.reverse()
33 |         //
34 |         let x = toR.one - fromR.one
35 |         let y = toR.two - fromR.two
36 |         let z = toR.three - fromR.three
37 |         let w = toR.four - fromR.four
38 |         self.change = (x,y,z,w)
39 |         //
40 |         let originChange = sqrt(x*x + y*y)
41 |         let sizeChange = sqrt(z*z + w*w)
42 |         self.referenceChangeLength = max(originChange, sizeChange)
43 |     }
44 |     
45 |     deinit {
46 |         self.render(to)
47 |         complete = true
48 |         completion?()
49 |     }
50 |     
51 |     //MARK: Update frame
52 |     
53 |     func updateFrame() {
54 |         let yChange = fabs(Double(center.y))
55 |         let progress = yChange / referenceChangeLength
56 |         let curX = fromR.one + change.x * progress;
57 |         let curY = fromR.two + change.y * progress;
58 |         let curZ = fromR.three + change.z * progress;
59 |         let curW = fromR.four + change.w * progress;
60 |         
61 |         let rect = Vector4.init((curX,curY,curZ,curW))
62 |         var curV = from.convert(rect)
63 |         if progress >= 1.0 {
64 |             if boundaryLimit {
65 |                 curV = to
66 |                 behavior.cancel()
67 |                 complete = true
68 |             }
69 |         }
70 |         self.render(curV)
71 |     }
72 |     
73 |     //MARK: UIDynamicItem protocol
74 |     var center: CGPoint = CGPoint.zero {
75 |         didSet {
76 |             updateFrame()
77 |         }
78 |     }
79 |     
80 |     var transform: CGAffineTransform = CGAffineTransform.identity
81 |     var bounds: CGRect {
82 |         get {
83 |             return CGRect(x: -50.0, y: -50.0, width: 100.0, height: 100.0)
84 |         }
85 |     }
86 | }
87 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/DynamicItemBasic.swift:
--------------------------------------------------------------------------------
  1 | //Copyright (c) 2016
  2 | //
  3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  4 | //
  5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  6 | //
  7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  8 | 
  9 | import UIKit
 10 | 
 11 | private let SolveForReverse = { (f: CFTimeInterval) in
 12 |     return 1 - f
 13 | }
 14 | 
 15 | private let SolveForUnReverse = { (f: CFTimeInterval) in
 16 |     return f
 17 | }
 18 | 
 19 | final class DynamicItemBasic<T: Interpolatable>: NSObject, UIDynamicItem, TimingType {
 20 |     
 21 |     var duration: CFTimeInterval = 0.25
 22 |     var delay: CFTimeInterval = 0.0
 23 |     var timingFunction: TimingSolvable = TimingFunctionType.default.easing()
 24 |     var from: T
 25 |     var to: T
 26 |     var render: (T) -> Void
 27 |     var autoreverses = false
 28 |     var repeatCount = 0
 29 |     var completion: ((Bool) -> Void)?
 30 |     var speed: Double = 1.0
 31 |     var timeOffset: CFTimeInterval = 0.0 {
 32 |         didSet {
 33 |             updateFrame()
 34 |         }
 35 |     }
 36 |     
 37 |     weak var behavior: UIDynamicBehavior?
 38 |     //External data to store (performance)
 39 |     fileprivate var externalData: Any?
 40 |     fileprivate var complete = false
 41 |     fileprivate var isReversing = false
 42 |     fileprivate var solveProgress = SolveForUnReverse
 43 |     fileprivate lazy var beginTime: CFTimeInterval = {
 44 |         return CACurrentMediaTime()
 45 |     }()
 46 |     fileprivate lazy var epsilon: Double = {
 47 |         return 1.0 / (self.duration * 1000.0)
 48 |     }()
 49 |     
 50 |     //MARK: Life cycle methods
 51 |     init(from: T, to: T, render: @escaping (T) -> Void) {
 52 |         self.from = from
 53 |         self.to = to
 54 |         self.render = render
 55 |         
 56 |         if let fromColor = from as? UIColor {
 57 |             let fromInfo = fromColor.colorInfo()
 58 |             let toColor = to as! UIColor
 59 |             let toInfo = toColor.colorInfo()
 60 |             self.externalData = (fromInfo,toInfo)
 61 |         }
 62 |     }
 63 |     
 64 |     deinit {
 65 |         //do some thing
 66 |     }
 67 |     
 68 |     //MARK: update frame
 69 |     fileprivate func updateFrame() {
 70 |         let startTime = beginTime
 71 |         var currentTime = CACurrentMediaTime() - startTime - delay
 72 |         currentTime = max(0, currentTime) * speed + timeOffset
 73 |         var progress = currentTime / duration
 74 |         if progress >= 1.0 {
 75 |             isReversing = autoreverses ? !isReversing : false
 76 |             if repeatCount == 0 {
 77 |                 if isReversing {
 78 |                     progress = 0.0
 79 |                     beginTime = CACurrentMediaTime()
 80 |                     solveProgress = SolveForReverse
 81 |                 } else {
 82 |                     progress = 1.0
 83 |                     behavior?.cancel()
 84 |                     complete = true
 85 |                     self.completion?(complete)
 86 |                 }
 87 |             }else {
 88 |                 if isReversing == false {
 89 |                     repeatCount -= 1
 90 |                     solveProgress = SolveForUnReverse
 91 |                 } else {
 92 |                     solveProgress = SolveForReverse
 93 |                 }
 94 |                 progress = 0.0
 95 |                 beginTime = CACurrentMediaTime()
 96 |             }
 97 |         }
 98 |         let solveP = solveProgress(progress)
 99 |         let adjustProgress = timingFunction.solveOn(solveP, epslion: epsilon)
100 |         let value = from.interpolate(adjustProgress, to: to, externalData: externalData)
101 |         self.render(value)
102 |     }
103 |     
104 |     //MARK: UIDynamicItem protocol
105 |     var center: CGPoint = CGPoint.zero {
106 |         didSet {
107 |             updateFrame()
108 |         }
109 |     }
110 |     
111 |     var transform: CGAffineTransform = CGAffineTransform.identity
112 |     var bounds: CGRect {
113 |         get {
114 |             return CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0)
115 |         }
116 |     }
117 | }
118 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/DynamicItemGravity.swift:
--------------------------------------------------------------------------------
  1 | //Copyright (c) 2016
  2 | //
  3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  4 | //
  5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  6 | //
  7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  8 | 
  9 | import UIKit
 10 | 
 11 | class DynamicItemGravity<T: Interpolatable>: NSObject, UIDynamicItem {
 12 |     
 13 |     var from: T!
 14 |     var to: T!
 15 |     var magnitude = 1.0
 16 |     var render: (T) -> Void
 17 |     var completion: (() -> Void)?
 18 |     var boundary = true
 19 |     weak var behavior: UIDynamicBehavior?
 20 |     //private vars
 21 |     fileprivate var referenceChangedLength: Double = 0.0
 22 |     //External data to store (performance)
 23 |     fileprivate var externalData: Any?
 24 |     fileprivate lazy var beginTime = {
 25 |         return CACurrentMediaTime()
 26 |     }()
 27 |     
 28 |     //MARK: init method
 29 |     init(from: T, to: T, render: @escaping (T) -> Void) {
 30 |         self.from = from
 31 |         self.to = to
 32 |         self.render = render
 33 |         super.init()
 34 |         caculateReferenceChangedLength()
 35 |     }
 36 |     
 37 |     deinit {
 38 |         self.completion?()
 39 |     }
 40 |     
 41 |     //MARK: private methods
 42 |     fileprivate func caculateReferenceChangedLength() {
 43 |         switch from {
 44 |         case let f as CGFloat:
 45 |             let t = to as! CGFloat
 46 |             referenceChangedLength = Double(fabs(t - f))
 47 |             
 48 |         case let f as Float:
 49 |             let t = to as! Float
 50 |             referenceChangedLength = Double(fabs(t - f))
 51 |             
 52 |         case let f as Double:
 53 |             let t = to as! Double
 54 |             referenceChangedLength = fabs(t - f)
 55 |             
 56 |         case let f as CGSize:
 57 |             let t = to as! CGSize
 58 |             let w = fabs(t.width - f.width)
 59 |             let h = fabs(t.height - f.height)
 60 |             referenceChangedLength = max(Double(w), Double(h))
 61 | 
 62 |         case let f as CGPoint:
 63 |             let t = to as! CGPoint
 64 |             let x = fabs(t.x - f.x)
 65 |             let y = fabs(t.y - f.y)
 66 |             referenceChangedLength = max(Double(x), Double(y))
 67 |             
 68 |         case let f as CGRect:
 69 |             let t = to as! CGRect
 70 |             let xChange = fabs(t.minX - f.minX)
 71 |             let yChange = fabs(t.minY - f.minY)
 72 |             let wChange = fabs(t.width - f.width)
 73 |             let hChange = fabs(t.height - f.height)
 74 |             let originC = hypot(xChange, yChange)
 75 |             let sizeC = hypot(wChange, hChange)
 76 |             referenceChangedLength = max(Double(originC), Double(sizeC))
 77 |             
 78 |         case let f as UIColor:
 79 |             let t = to as! UIColor
 80 |             let fromInfo = f.colorInfo()
 81 |             let toInfo = t.colorInfo()
 82 |             let hueChange = fabs(toInfo.hue - fromInfo.hue)
 83 |             let brightnessChange = fabs(toInfo.brightness - fromInfo.brightness)
 84 |             let saturationChange = fabs(toInfo.saturation - fromInfo.saturation)
 85 |             let alphaChange = fabs(toInfo.alpha - fromInfo.alpha)
 86 |             let oneC = hypot(hueChange, saturationChange) * 1000.0
 87 |             let twoC = hypot(brightnessChange, alphaChange) * 1000.0
 88 |             referenceChangedLength = max(Double(oneC), Double(twoC))
 89 |             externalData = (fromInfo,toInfo)
 90 |             
 91 |         default:
 92 |             referenceChangedLength = 1000.0
 93 |        
 94 |         }
 95 |     }
 96 |     
 97 |     fileprivate func updateFrame() {
 98 |         if referenceChangedLength <= 0.0 {
 99 |             behavior?.cancel()
100 |             return
101 |         }
102 |         var currentTime = CACurrentMediaTime() - beginTime
103 |         currentTime = max(0.0, currentTime)
104 |         let offset = gravityOffset(currentTime)
105 |         var progress = offset / referenceChangedLength
106 |         if progress >= 1.0 {
107 |             if boundary {
108 |                 progress = 1.0
109 |                 behavior?.cancel()
110 |             }
111 |         }
112 |         
113 |         let value = from.interpolate(progress, to: to, externalData: externalData)
114 |         render(value)
115 |     }
116 |     
117 |     fileprivate func gravityOffset(_ t: CFTimeInterval) -> Double {
118 |         return t * t * 1000.0 * magnitude;
119 |     }
120 |     
121 |     //MARK: UIDynamicItem protocol
122 |     var center: CGPoint = CGPoint.zero {
123 |         didSet {
124 |             updateFrame()
125 |         }
126 |     }
127 |     
128 |     var transform: CGAffineTransform = CGAffineTransform.identity
129 |     var bounds: CGRect {
130 |         get {
131 |             return CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0)
132 |         }
133 |     }
134 | }
135 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/GravityConfigurable.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | public protocol GravityConfigurable: BasicChainable {
12 |     func gravity(_ magnitude: Double) -> GravityConfigurable
13 | }
14 | 
15 | public protocol GravityConfigurable1: BasicChainable1 {
16 |     func gravity(_ magnitude: Double) -> GravityConfigurable1
17 | }
18 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/Interpolatable.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import Foundation
10 | 
11 | public protocol Interpolatable: Vectorial {
12 |     func interpolate(_ progress: Double, to: Self, externalData: Any?) -> Self
13 | }
14 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/Physical.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | public protocol Physical: Interpolatable {}
12 | 
13 | extension Physical {
14 |     public func fall(to: Self,magnitude: Double = 1.0, render: @escaping (Self) -> Void, completion: (() -> Void)? = nil) {
15 |         let item = DynamicItemGravity(from: self, to: to, render: render)
16 |         let push = item.pushBehavior(.down)
17 |         item.behavior = push
18 |         item.magnitude = magnitude
19 |         item.completion = completion
20 |         push.commitToBasic()
21 |     }
22 |     
23 |     public func snap(to: Self, damping: CGFloat = 0.5,render: @escaping (Self) -> Void, completion: (() -> Void)? = nil) {
24 |         let item = DynamicItem(from: self, to: to, render: render)
25 |         let toP = CGPoint.init(x: 0, y: CGFloat(item.referenceChangeLength))
26 |         let snap = item.snapBehavior(toP, damping: damping)
27 |         item.behavior = snap
28 |         item.completion = completion
29 |         snap.commit()
30 |     }
31 |     
32 |     public func attachment(to: Self,damping: CGFloat = 0.5, frequency: CGFloat = 0.5,render: @escaping (Self) -> Void, completion: (() -> Void)? = nil) {
33 |         let item = DynamicItem(from: self, to: to,render: render)
34 |         let toP = CGPoint.init(x: 0, y: CGFloat(item.referenceChangeLength))
35 |         let attachment = item.attachmentBehavior(toP, length: 0.0, damping: damping, frequency: frequency)
36 |         item.behavior = attachment
37 |         item.completion = completion
38 |         attachment.commit()
39 |     }
40 |     
41 |     public func pushed(to: Self,render: @escaping (Self) -> Void, completion: (() -> Void)? = nil) {
42 |         let item = DynamicItem(from: self,to: to,render: render)
43 |         let direction = CGVector(dx: item.toR.one - item.fromR.one, dy: item.toR.two - item.fromR.two)
44 |         let push = item.pushBehavior(direction, mode: .instantaneous, magnitude: 1.0)
45 |         item.behavior = push
46 |         item.boundaryLimit = true
47 |         item.completion = completion
48 |         push.commit()
49 |     }
50 |     
51 |     public func animate(to: Self, duration: CFTimeInterval = 0.25, delay: CFTimeInterval = 0.0, type: TimingFunctionType = .default, autoreverses: Bool = false, repeatCount: Int = 0, render: @escaping (Self) -> Void, completion: ((Bool) -> Void)? = nil) {
52 |         let basicItem = DynamicItemBasic(from: self, to: to, render: render)
53 |         let push = basicItem.pushBehavior(.down)
54 |         basicItem.behavior = push
55 |         basicItem.duration = duration
56 |         basicItem.timingFunction = type.easing()
57 |         basicItem.completion = completion
58 |         basicItem.delay = delay
59 |         basicItem.autoreverses = autoreverses
60 |         push.commitToBasic()
61 |     }
62 | }
63 | 
64 | 
65 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/SnapConfigurable.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | public protocol SnapConfigurable: BasicChainable {
12 |     func snap(_ damping: CGFloat) -> SnapConfigurable
13 | }
14 | 
15 | public protocol SnapConfigurable1: BasicChainable1 {
16 |     func snap(_ damping: CGFloat) -> SnapConfigurable1
17 | }
18 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/StepControllable.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import Foundation
10 | 
11 | public protocol StepControllable {
12 |     //remove all remaining from excute sequence
13 |     func cancelAllRemaining()
14 |     //will add more methods to control animation steps
15 | }


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/TimingFunction.swift:
--------------------------------------------------------------------------------
  1 | //Copyright (c) 2016
  2 | //
  3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  4 | //
  5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  6 | //
  7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  8 | import Foundation
  9 | 
 10 | /// A set of preset bezier curves.
 11 | public enum TimingFunctionType {
 12 |     /// Equivalent to `kCAMediaTimingFunctionDefault`.
 13 |     case `default`
 14 |     
 15 |     /// Equivalent to `kCAMediaTimingFunctionEaseIn`.
 16 |     case easeIn
 17 |     
 18 |     /// Equivalent to `kCAMediaTimingFunctionEaseOut`.
 19 |     case easeOut
 20 |     
 21 |     /// Equivalent to `kCAMediaTimingFunctionEaseInEaseOut`.
 22 |     case easeInEaseOut
 23 |     
 24 |     /// No easing.
 25 |     case linear
 26 |     
 27 |     /// Inspired by the default curve in Google Material Design.
 28 |     case swiftOut
 29 |     /// 
 30 |     case backEaseIn
 31 |     ///
 32 |     case backEaseOut
 33 |     ///
 34 |     case backEaseInOut
 35 |     ///
 36 |     case bounceOut
 37 |     ///
 38 |     case sine
 39 |     ///
 40 |     case circ
 41 |     ///
 42 |     case exponentialIn
 43 |     ///
 44 |     case exponentialOut
 45 |     ///
 46 |     case elasticIn
 47 |     ///
 48 |     case bounceReverse
 49 |     ///
 50 |     case elasticOut
 51 |     /// custom
 52 |     case custom(Double, Double, Double, Double)
 53 |     
 54 |     
 55 |     func easing() -> TimingSolvable {
 56 |         switch self {
 57 |         case .default:
 58 |             return UnitBezier(p1x: 0.25, p1y: 0.1, p2x: 0.25, p2y: 1.0)
 59 |         case .easeIn:
 60 |             return UnitBezier(p1x: 0.42, p1y: 0.0, p2x: 1.0, p2y: 1.0)
 61 |         case .easeOut:
 62 |             return UnitBezier(p1x: 0.0, p1y: 0.0, p2x: 0.58, p2y: 1.0)
 63 |         case .easeInEaseOut:
 64 |             return UnitBezier(p1x: 0.42, p1y: 0.0, p2x: 0.58, p2y: 1.0)
 65 |         case .linear: 
 66 |             return UnitBezier(p1x: 0.0, p1y: 0.0, p2x: 1.0, p2y: 1.0)
 67 |         case .swiftOut: 
 68 |             return UnitBezier(p1x: 0.4, p1y: 0.0, p2x: 0.2, p2y: 1.0)
 69 |         case .backEaseIn:
 70 |             return EasingContainer(easing: { (t: Double) in
 71 |                 return t * t * t - t * sin(t * M_PI)
 72 |             })
 73 |         case .backEaseOut:
 74 |             return EasingContainer(easing: { (t: Double) in
 75 |                 let f = (1 - t);
 76 |                 return 1 - (f * f * f - f * sin(f * M_PI));
 77 |             })
 78 |         case .backEaseInOut:
 79 |             return EasingContainer(easing: { (t: Double) in
 80 |                 if(t < 0.5) {
 81 |                     let f = 2 * t;
 82 |                     return 0.5 * (f * f * f - f * sin(f * M_PI));
 83 |                 } else {
 84 |                     let f = (1.0 - (2.0 * t - 1.0));
 85 |                     let cubic = f * f * f
 86 |                     return 0.5 * (1.0 - (cubic - f * sin(f * M_PI))) + 0.5;
 87 |                 }
 88 |             })
 89 |         case .bounceOut:
 90 |             return EasingContainer(easing: { (t: Double) in
 91 |                 if(t < 4/11.0){
 92 |                     return (121 * t * t)/16.0;
 93 |                 } else if(t < 8/11.0){
 94 |                     return (363/40.0 * t * t) - (99/10.0 * t) + 17/5.0;
 95 |                 }else if(t < 9/10.0){
 96 |                     return (4356/361.0 * t * t) - (35442/1805.0 * t) + 16061/1805.0;
 97 |                 }else{
 98 |                     return (54/5.0 * t * t) - (513/25.0 * t) + 268/25.0;
 99 |                 }
100 |             })
101 |         case .sine:
102 |             return EasingContainer(easing: { (t: Double) in
103 |                 return 1 - cos( t * M_PI / 2.0)
104 |             })
105 |         case .circ:
106 |             return EasingContainer(easing: { (t: Double) in
107 |                 return 1 - sqrt( 1.0 - t * t )
108 |             })
109 |         case .exponentialIn:
110 |             return EasingContainer(easing: { (t: Double) in
111 |                 return (t == 0.0) ? t : pow(2, 10 * (t - 1))
112 |             })
113 |         case .exponentialOut:
114 |             return EasingContainer(easing: { (t: Double) in
115 |                 return (t == 1.0) ? t : 1 - pow(2, -10 * t)
116 |             })
117 |         case .elasticIn:
118 |             return EasingContainer(easing: { (t: Double) in
119 |                 return sin(13.0 * M_PI_2 * t) * pow(2, 10 * (t - 1))
120 |             })
121 |         case .elasticOut:
122 |             return EasingContainer(easing: { (t: Double) in
123 |                 return sin(-13.0 * M_PI_2 * (t + 1)) * pow(2, -10 * t) + 1.0;
124 |             })
125 |         case .bounceReverse:
126 |             return EasingContainer(easing: { (t: Double) in
127 |                 var bounce: Double = 4.0
128 |                 var pow2 = 0.0
129 |                 
130 |                 repeat {
131 |                     bounce = bounce - 1.0
132 |                     pow2 = pow(2, bounce)
133 |                 } while (t < (pow2 - 1.0 ) / 11.0)
134 |                 
135 |                 return 1 / pow( 4, 3 - bounce ) - 7.5625 * pow( ( pow2 * 3 - 2 ) / 22 - t, 2 );
136 |             })
137 |         case .custom(let p1x,let p1y,let p2x,let p2y):
138 |             return UnitBezier(p1x: p1x, p1y: p1y, p2x: p2x, p2y: p2y)
139 |         }
140 |     }
141 | }
142 | 
143 | class EasingContainer: TimingSolvable {
144 |     let easing: (Double) -> Double
145 |     
146 |     init(easing: @escaping (Double) -> Double) {
147 |         self.easing = easing
148 |     }
149 |     
150 |     //
151 |     func solveOn(_ time: Double, epslion: Double) -> Double {
152 |         return self.easing(time)
153 |     }
154 | }
155 | 
156 | 
157 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/TimingSolvable.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  TimingSolvable.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 6/28/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import Foundation
10 | 
11 | protocol TimingSolvable {
12 |     func solveOn(_ time: Double, epslion: Double) -> Double
13 | }
14 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/TimingType.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import Foundation
10 | 
11 | protocol TimingType {
12 |     var duration: CFTimeInterval { get set }
13 |     var delay: CFTimeInterval { get set }
14 |     var timingFunction: TimingSolvable { get set }
15 |     var autoreverses: Bool { get set }
16 |     var repeatCount: Int { get set }
17 |     var speed: Double { get set }
18 |     var timeOffset: CFTimeInterval { get set }
19 | }


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/UIDynamicBehavior+Commit.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | internal extension UIDynamicBehavior {
12 |     
13 |     func commit() {
14 |         AnimatorCoordinator.shared.addBehavior(self)
15 |     }
16 |         
17 |     func cancel() {
18 |         self.dynamicAnimator?.removeBehavior(self)
19 |     }
20 |     
21 |     func commitToBasic() {
22 |         AnimatorCoordinator.shared.addBasicBehavior(self)
23 |     }
24 | }
25 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/UILabel+Stellar.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | extension UILabel {
12 | 
13 | //    public func makeTextColor(color: UIColor) -> UIView {
14 | //        let type = AnimationType(type: .Basic, subType: .TextColor(color))
15 | //        context.addAnimationType(type)
16 | //        return self
17 | //    }
18 | }
19 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/UITextView+Stellar.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | extension UITextView {
12 |     
13 | //    public func makeTextColor(color: UIColor) -> UIView {
14 | //        let type = AnimationType(type: .Basic, subType: .TextColor(color))
15 | //        context.addAnimationType(type)
16 | //        return self
17 | //    }
18 | }
19 | 
20 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/UIView+FileConfigurable.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  UIView+FileConfigurable.swift
 3 | //  StellarDemo
 4 | //
 5 | //  Created by AugustRush on 6/7/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import UIKit
10 | 
11 | enum ConfigurationError: Error {
12 |     case invalidString
13 |     case transformedError(Error)
14 |     case undefined
15 | }
16 | 
17 | extension UIView {
18 |     //configure animation with JSON string
19 |     public func configureWithJSON(_ str: String) throws -> Void {
20 |         let data = str.data(using: String.Encoding.utf8)
21 |         guard let _ = data else {
22 |             throw ConfigurationError.invalidString
23 |         }
24 |         do {
25 |                let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments)
26 |             switch json {
27 |             case let dict as Dictionary<String,String>:
28 |                 configureWithDictionary(dict)
29 |             default:
30 |                 throw ConfigurationError.undefined
31 |             }
32 |         } catch {
33 |             throw ConfigurationError.transformedError(error)
34 |         }
35 |     }
36 |     
37 |     fileprivate func configureWithDictionary(_ dict: Dictionary<String, String>) -> Void {
38 |         
39 |     }
40 | }
41 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/UnitBezier.swift:
--------------------------------------------------------------------------------
  1 | //Copyright (c) 2016
  2 | //
  3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  4 | //
  5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  6 | //
  7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  8 | 
  9 | import Foundation
 10 | import CoreGraphics
 11 | 
 12 | public typealias Scalar = Double
 13 | /// A bezier curve, often used to calculate timing functions.
 14 | public struct UnitBezier {
 15 |     
 16 |     /// The horizontal component of the first control point.
 17 |     public var p1x: Scalar
 18 |     
 19 |     /// The vertical component of the first control point.
 20 |     public var p1y: Scalar
 21 |     
 22 |     /// The horizontal component of the second control point.
 23 |     public var p2x: Scalar
 24 |     
 25 |     /// The vertical component of the second control point.
 26 |     public var p2y: Scalar
 27 |     
 28 |     /// Creates a new `UnitBezier` instance.
 29 |     public init(p1x: Scalar, p1y: Scalar, p2x: Scalar, p2y: Scalar) {
 30 |         self.p1x = p1x
 31 |         self.p1y = p1y
 32 |         self.p2x = p2x
 33 |         self.p2y = p2y
 34 |     }
 35 |     
 36 |     /// Calculates the resulting `y` for given `x`.
 37 |     ///
 38 |     /// - parameter x: The value to solve for.
 39 |     /// - parameter epsilon: The required precision of the result (where `x * epsilon` is the maximum time segment to be evaluated).
 40 |     /// - returns: The solved `y` value.
 41 |     public func solve(_ x: Scalar, epsilon: Scalar) -> Scalar {
 42 |         return UnitBezierSolver(bezier: self).solve(x, eps: epsilon)
 43 |     }
 44 | }
 45 | 
 46 | extension UnitBezier: Equatable { }
 47 | 
 48 | extension UnitBezier: TimingSolvable {
 49 |     func solveOn(_ time: Double, epslion: Double) -> Double {
 50 |         return self.solve(time, epsilon: epslion)
 51 |     }
 52 | }
 53 | 
 54 | /// Equatable.
 55 | public func ==(lhs: UnitBezier, rhs: UnitBezier) -> Bool {
 56 |     return lhs.p1x == rhs.p1x
 57 |         && lhs.p1y == rhs.p1y
 58 |         && lhs.p2x == rhs.p2x
 59 |         && lhs.p2y == rhs.p2y
 60 | }
 61 | 
 62 | 
 63 | // Ported to Swift from WebCore:
 64 | // http://opensource.apple.com/source/WebCore/WebCore-955.66/platform/graphics/UnitBezier.h
 65 | 
 66 | /*
 67 |  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
 68 |  *
 69 |  * Redistribution and use in source and binary forms, with or without
 70 |  * modification, are permitted provided that the following conditions
 71 |  * are met:
 72 |  * 1. Redistributions of source code must retain the above copyright
 73 |  *    notice, this list of conditions and the following disclaimer.
 74 |  * 2. Redistributions in binary form must reproduce the above copyright
 75 |  *    notice, this list of conditions and the following disclaimer in the
 76 |  *    documentation and/or other materials provided with the distribution.
 77 |  *
 78 |  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 79 |  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 80 |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 81 |  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 82 |  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 83 |  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 84 |  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 85 |  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 86 |  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 87 |  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 88 |  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 89 |  */
 90 | 
 91 | 
 92 | private struct UnitBezierSolver {
 93 |     
 94 |     fileprivate let ax: Scalar
 95 |     fileprivate let bx: Scalar
 96 |     fileprivate let cx: Scalar
 97 |     
 98 |     fileprivate let ay: Scalar
 99 |     fileprivate let by: Scalar
100 |     fileprivate let cy: Scalar
101 |     
102 |     init(bezier: UnitBezier) {
103 |         self.init(p1x: bezier.p1x, p1y: bezier.p1y, p2x: bezier.p2x, p2y: bezier.p2y)
104 |     }
105 |     
106 |     init(p1x: Scalar, p1y: Scalar, p2x: Scalar, p2y: Scalar) {
107 |         
108 |         // Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1).
109 |         cx = 3.0 * p1x
110 |         bx = 3.0 * (p2x - p1x) - cx
111 |         ax = 1.0 - cx - bx
112 |         
113 |         cy = 3.0 * p1y
114 |         by = 3.0 * (p2y - p1y) - cy
115 |         ay = 1.0 - cy - by
116 |     }
117 |     
118 |     func sampleCurveX(_ t: Scalar) -> Scalar {
119 |         return ((ax * t + bx) * t + cx) * t
120 |     }
121 |     
122 |     func sampleCurveY(_ t: Scalar) -> Scalar {
123 |         return ((ay * t + by) * t + cy) * t
124 |     }
125 |     
126 |     func sampleCurveDerivativeX(_ t: Scalar) -> Scalar {
127 |         return (3.0 * ax * t + 2.0 * bx) * t + cx
128 |     }
129 |     
130 |     func solveCurveX(_ x: Scalar, eps: Scalar) -> Scalar {
131 |         var t0: Scalar = 0.0
132 |         var t1: Scalar = 0.0
133 |         var t2: Scalar = 0.0
134 |         var x2: Scalar = 0.0
135 |         var d2: Scalar = 0.0
136 |         
137 |         // First try a few iterations of Newton's method -- normally very fast.
138 |         t2 = x
139 |         for _ in 0..<8 {
140 |             x2 = sampleCurveX(t2) - x
141 |             if abs(x2) < eps {
142 |                 return t2
143 |             }
144 |             d2 = sampleCurveDerivativeX(t2)
145 |             if abs(d2) < 1e-6 {
146 |                 break
147 |             }
148 |             t2 = t2 - x2 / d2
149 |         }
150 |         
151 |         // Fall back to the bisection method for reliability.
152 |         t0 = 0.0
153 |         t1 = 1.0
154 |         t2 = x
155 |         
156 |         if t2 < t0 {
157 |             return t0
158 |         }
159 |         if t2 > t1 {
160 |             return t1
161 |         }
162 |         
163 |         while t0 < t1 {
164 |             x2 = sampleCurveX(t2)
165 |             if abs(x2-x) < eps {
166 |                 return t2
167 |             }
168 |             if x > x2 {
169 |                 t0 = t2
170 |             } else {
171 |                 t1 = t2
172 |             }
173 |             t2 = (t1-t0) * 0.5 + t0
174 |         }
175 |         
176 |         return t2
177 |     }
178 |     
179 |     func solve(_ x: Scalar, eps: Scalar) -> Scalar {
180 |         return sampleCurveY(solveCurveX(x, eps: eps))
181 |     }
182 | }
183 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/Sources/Sources/Vectorial.swift:
--------------------------------------------------------------------------------
 1 | //Copyright (c) 2016
 2 | //
 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 4 | //
 5 | //The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 6 | //
 7 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 8 | 
 9 | import UIKit
10 | 
11 | public class Vector4 {
12 |     var one: Double = 0
13 |     var two: Double = 0
14 |     var three: Double = 0
15 |     var four: Double = 0
16 |     
17 |     convenience init(_ fourLatitude: (Double,Double,Double,Double)) {
18 |         self.init()
19 |         self.one = fourLatitude.0
20 |         self.two = fourLatitude.1
21 |         self.three = fourLatitude.2
22 |         self.four = fourLatitude.3
23 |     }
24 | }
25 | 
26 | public protocol Vectorial {
27 |     func convert(_ p: Vector4) -> Self
28 |     func reverse() -> Vector4
29 | }
30 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemo/MyPlayground.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 | <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2 | <playground version='5.0' target-platform='ios' auto-termination-delay='50' display-mode='rendered' timelineScrubberEnabled='true' last-migration='0820'>
3 |     <timeline fileName='timeline.xctimeline'/>
4 | </playground>


--------------------------------------------------------------------------------
/StellarDemo/StellarDemoTests/Info.plist:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 3 | <plist version="1.0">
 4 | <dict>
 5 | 	<key>CFBundleDevelopmentRegion</key>
 6 | 	<string>en</string>
 7 | 	<key>CFBundleExecutable</key>
 8 | 	<string>$(EXECUTABLE_NAME)</string>
 9 | 	<key>CFBundleIdentifier</key>
10 | 	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11 | 	<key>CFBundleInfoDictionaryVersion</key>
12 | 	<string>6.0</string>
13 | 	<key>CFBundleName</key>
14 | 	<string>$(PRODUCT_NAME)</string>
15 | 	<key>CFBundlePackageType</key>
16 | 	<string>BNDL</string>
17 | 	<key>CFBundleShortVersionString</key>
18 | 	<string>1.0</string>
19 | 	<key>CFBundleSignature</key>
20 | 	<string>????</string>
21 | 	<key>CFBundleVersion</key>
22 | 	<string>1</string>
23 | </dict>
24 | </plist>
25 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemoTests/StellarDemoTests.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  StellarDemoTests.swift
 3 | //  StellarDemoTests
 4 | //
 5 | //  Created by AugustRush on 5/7/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import XCTest
10 | @testable import StellarDemo
11 | 
12 | class StellarDemoTests: XCTestCase {
13 |     
14 |     override func setUp() {
15 |         super.setUp()
16 |         // Put setup code here. This method is called before the invocation of each test method in the class.
17 |     }
18 |     
19 |     override func tearDown() {
20 |         // Put teardown code here. This method is called after the invocation of each test method in the class.
21 |         super.tearDown()
22 |     }
23 |     
24 |     func testExample() {
25 |         // This is an example of a functional test case.
26 |         // Use XCTAssert and related functions to verify your tests produce the correct results.
27 |     }
28 |     
29 |     func testPerformanceExample() {
30 |         // This is an example of a performance test case.
31 |         self.measure {
32 |             // Put the code you want to measure the time of here.
33 |         }
34 |     }
35 |     
36 | }
37 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemoUITests/Info.plist:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 3 | <plist version="1.0">
 4 | <dict>
 5 | 	<key>CFBundleDevelopmentRegion</key>
 6 | 	<string>en</string>
 7 | 	<key>CFBundleExecutable</key>
 8 | 	<string>$(EXECUTABLE_NAME)</string>
 9 | 	<key>CFBundleIdentifier</key>
10 | 	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11 | 	<key>CFBundleInfoDictionaryVersion</key>
12 | 	<string>6.0</string>
13 | 	<key>CFBundleName</key>
14 | 	<string>$(PRODUCT_NAME)</string>
15 | 	<key>CFBundlePackageType</key>
16 | 	<string>BNDL</string>
17 | 	<key>CFBundleShortVersionString</key>
18 | 	<string>1.0</string>
19 | 	<key>CFBundleSignature</key>
20 | 	<string>????</string>
21 | 	<key>CFBundleVersion</key>
22 | 	<string>1</string>
23 | </dict>
24 | </plist>
25 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarDemoUITests/StellarDemoUITests.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  StellarDemoUITests.swift
 3 | //  StellarDemoUITests
 4 | //
 5 | //  Created by AugustRush on 5/7/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import XCTest
10 | 
11 | class StellarDemoUITests: XCTestCase {
12 |         
13 |     override func setUp() {
14 |         super.setUp()
15 |         
16 |         // Put setup code here. This method is called before the invocation of each test method in the class.
17 |         
18 |         // In UI tests it is usually best to stop immediately when a failure occurs.
19 |         continueAfterFailure = false
20 |         // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
21 |         XCUIApplication().launch()
22 | 
23 |         // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
24 |     }
25 |     
26 |     override func tearDown() {
27 |         // Put teardown code here. This method is called after the invocation of each test method in the class.
28 |         super.tearDown()
29 |     }
30 |     
31 |     func testExample() {
32 |         // Use recording to get started writing UI tests.
33 |         // Use XCTAssert and related functions to verify your tests produce the correct results.
34 |     }
35 |     
36 | }
37 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarTests/Info.plist:
--------------------------------------------------------------------------------
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 3 | <plist version="1.0">
 4 | <dict>
 5 | 	<key>CFBundleDevelopmentRegion</key>
 6 | 	<string>en</string>
 7 | 	<key>CFBundleExecutable</key>
 8 | 	<string>$(EXECUTABLE_NAME)</string>
 9 | 	<key>CFBundleIdentifier</key>
10 | 	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11 | 	<key>CFBundleInfoDictionaryVersion</key>
12 | 	<string>6.0</string>
13 | 	<key>CFBundleName</key>
14 | 	<string>$(PRODUCT_NAME)</string>
15 | 	<key>CFBundlePackageType</key>
16 | 	<string>BNDL</string>
17 | 	<key>CFBundleShortVersionString</key>
18 | 	<string>1.0</string>
19 | 	<key>CFBundleSignature</key>
20 | 	<string>????</string>
21 | 	<key>CFBundleVersion</key>
22 | 	<string>1</string>
23 | </dict>
24 | </plist>
25 | 


--------------------------------------------------------------------------------
/StellarDemo/StellarTests/StellarTests.swift:
--------------------------------------------------------------------------------
 1 | //
 2 | //  StellarTests.swift
 3 | //  StellarTests
 4 | //
 5 | //  Created by AugustRush on 6/6/16.
 6 | //  Copyright © 2016 August. All rights reserved.
 7 | //
 8 | 
 9 | import XCTest
10 | @testable import Stellar
11 | 
12 | class StellarTests: XCTestCase {
13 |     
14 |     override func setUp() {
15 |         super.setUp()
16 |         // Put setup code here. This method is called before the invocation of each test method in the class.
17 |     }
18 |     
19 |     override func tearDown() {
20 |         // Put teardown code here. This method is called after the invocation of each test method in the class.
21 |         super.tearDown()
22 |     }
23 |     
24 |     func testExample() {
25 |         // This is an example of a functional test case.
26 |         // Use XCTAssert and related functions to verify your tests produce the correct results.
27 |     }
28 |     
29 |     func testPerformanceExample() {
30 |         // This is an example of a performance test case.
31 |         self.measureBlock {
32 |             // Put the code you want to measure the time of here.
33 |         }
34 |     }
35 |     
36 | }
37 | 


--------------------------------------------------------------------------------
/attachmentCurve.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/attachmentCurve.gif


--------------------------------------------------------------------------------
/balls.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/balls.gif


--------------------------------------------------------------------------------
/basicCurve.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/basicCurve.gif


--------------------------------------------------------------------------------
/example4.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/example4.gif


--------------------------------------------------------------------------------
/example5.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/example5.gif


--------------------------------------------------------------------------------
/example6.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/example6.gif


--------------------------------------------------------------------------------
/gravityCurve.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/gravityCurve.gif


--------------------------------------------------------------------------------
/layers.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/layers.gif


--------------------------------------------------------------------------------
/lines.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/lines.gif


--------------------------------------------------------------------------------
/pushCurve.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/pushCurve.gif


--------------------------------------------------------------------------------
/snapCurve.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/snapCurve.gif


--------------------------------------------------------------------------------
/title.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AugustRush/Stellar/6c192427621f8b52f3b155d0088e1eabd156abe0/title.png


--------------------------------------------------------------------------------