mirror of
https://github.com/exyte/Macaw.git
synced 2024-09-11 13:15:35 +03:00
Raw automated swift 3.0 conversion (not buildable)
This commit is contained in:
parent
be9f26903f
commit
bed4386799
1
Example/.swift-version
Normal file
1
Example/.swift-version
Normal file
@ -0,0 +1 @@
|
|||||||
|
3.0
|
@ -301,7 +301,7 @@
|
|||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastSwiftUpdateCheck = 0710;
|
LastSwiftUpdateCheck = 0710;
|
||||||
LastUpgradeCheck = 0710;
|
LastUpgradeCheck = 0800;
|
||||||
ORGANIZATIONNAME = Exyte;
|
ORGANIZATIONNAME = Exyte;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
B02E75EC1C16104900D1971D = {
|
B02E75EC1C16104900D1971D = {
|
||||||
@ -474,8 +474,10 @@
|
|||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
CLANG_WARN_INT_CONVERSION = YES;
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
@ -518,8 +520,10 @@
|
|||||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
CLANG_WARN_EMPTY_BODY = YES;
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
CLANG_WARN_INT_CONVERSION = YES;
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
@ -538,6 +542,7 @@
|
|||||||
IPHONEOS_DEPLOYMENT_TARGET = 9.1;
|
IPHONEOS_DEPLOYMENT_TARGET = 9.1;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||||
VALIDATE_PRODUCT = YES;
|
VALIDATE_PRODUCT = YES;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
@ -546,6 +551,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = B1435E8977BA0B9A49C4E399 /* Pods-Example.debug.xcconfig */;
|
baseConfigurationReference = B1435E8977BA0B9A49C4E399 /* Pods-Example.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
@ -555,7 +561,7 @@
|
|||||||
PRODUCT_BUNDLE_IDENTIFIER = com.exyte.Example.Example;
|
PRODUCT_BUNDLE_IDENTIFIER = com.exyte.Example.Example;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE = "";
|
PROVISIONING_PROFILE = "";
|
||||||
SWIFT_VERSION = 2.3;
|
SWIFT_VERSION = 3.0;
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
@ -563,6 +569,7 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 131DDFA4A9D164CC4B64C3E8 /* Pods-Example.release.xcconfig */;
|
baseConfigurationReference = 131DDFA4A9D164CC4B64C3E8 /* Pods-Example.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||||
@ -572,7 +579,7 @@
|
|||||||
PRODUCT_BUNDLE_IDENTIFIER = com.exyte.Example.Example;
|
PRODUCT_BUNDLE_IDENTIFIER = com.exyte.Example.Example;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE = "";
|
PROVISIONING_PROFILE = "";
|
||||||
SWIFT_VERSION = 2.3;
|
SWIFT_VERSION = 3.0;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
@ -14,31 +14,31 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
|
|
||||||
var window: UIWindow?
|
var window: UIWindow?
|
||||||
|
|
||||||
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
|
||||||
// Override point for customization after application launch.
|
// Override point for customization after application launch.
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func applicationWillResignActive(application: UIApplication) {
|
func applicationWillResignActive(_ application: UIApplication) {
|
||||||
// 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.
|
// 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.
|
||||||
// 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.
|
// 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.
|
||||||
}
|
}
|
||||||
|
|
||||||
func applicationDidEnterBackground(application: UIApplication) {
|
func applicationDidEnterBackground(_ application: UIApplication) {
|
||||||
// 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.
|
// 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.
|
||||||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||||
}
|
}
|
||||||
|
|
||||||
func applicationWillEnterForeground(application: UIApplication) {
|
func applicationWillEnterForeground(_ application: UIApplication) {
|
||||||
// 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.
|
// 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.
|
||||||
}
|
}
|
||||||
|
|
||||||
func applicationDidBecomeActive(application: UIApplication) {
|
func applicationDidBecomeActive(_ application: UIApplication) {
|
||||||
// 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.
|
// 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.
|
||||||
AnimationRestorer.restore()
|
AnimationRestorer.restore()
|
||||||
}
|
}
|
||||||
|
|
||||||
func applicationWillTerminate(application: UIApplication) {
|
func applicationWillTerminate(_ application: UIApplication) {
|
||||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import Foundation
|
|||||||
|
|
||||||
class BasePageViewController: UIPageViewController {
|
class BasePageViewController: UIPageViewController {
|
||||||
|
|
||||||
private lazy var orderedViewControllers: [UIViewController] = {
|
fileprivate lazy var orderedViewControllers: [UIViewController] = {
|
||||||
return [
|
return [
|
||||||
self.newMacawViewController("MenuViewController"),
|
self.newMacawViewController("MenuViewController"),
|
||||||
self.newMacawViewController("FirstPageViewController"),
|
self.newMacawViewController("FirstPageViewController"),
|
||||||
@ -19,9 +19,9 @@ class BasePageViewController: UIPageViewController {
|
|||||||
]
|
]
|
||||||
}()
|
}()
|
||||||
|
|
||||||
private func newMacawViewController(controllerName: String) -> UIViewController {
|
fileprivate func newMacawViewController(_ controllerName: String) -> UIViewController {
|
||||||
return UIStoryboard(name: "Main", bundle: nil)
|
return UIStoryboard(name: "Main", bundle: nil)
|
||||||
.instantiateViewControllerWithIdentifier(controllerName)
|
.instantiateViewController(withIdentifier: controllerName)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
@ -30,7 +30,7 @@ class BasePageViewController: UIPageViewController {
|
|||||||
|
|
||||||
if let firstViewController = orderedViewControllers.first {
|
if let firstViewController = orderedViewControllers.first {
|
||||||
setViewControllers([firstViewController],
|
setViewControllers([firstViewController],
|
||||||
direction: .Forward,
|
direction: .forward,
|
||||||
animated: true,
|
animated: true,
|
||||||
completion: nil)
|
completion: nil)
|
||||||
}
|
}
|
||||||
@ -44,9 +44,9 @@ class BasePageViewController: UIPageViewController {
|
|||||||
|
|
||||||
extension BasePageViewController: UIPageViewControllerDataSource {
|
extension BasePageViewController: UIPageViewControllerDataSource {
|
||||||
|
|
||||||
func pageViewController(pageViewController: UIPageViewController,
|
func pageViewController(_ pageViewController: UIPageViewController,
|
||||||
viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
|
viewControllerBefore viewController: UIViewController) -> UIViewController? {
|
||||||
guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
|
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,9 +65,9 @@ extension BasePageViewController: UIPageViewControllerDataSource {
|
|||||||
return orderedViewControllers[previousIndex]
|
return orderedViewControllers[previousIndex]
|
||||||
}
|
}
|
||||||
|
|
||||||
func pageViewController(pageViewController: UIPageViewController,
|
func pageViewController(_ pageViewController: UIPageViewController,
|
||||||
viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
|
viewControllerAfter viewController: UIViewController) -> UIViewController? {
|
||||||
guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
|
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,16 +87,16 @@ extension BasePageViewController: UIPageViewControllerDataSource {
|
|||||||
return orderedViewControllers[nextIndex]
|
return orderedViewControllers[nextIndex]
|
||||||
}
|
}
|
||||||
|
|
||||||
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
|
func presentationCount(for pageViewController: UIPageViewController) -> Int {
|
||||||
return orderedViewControllers.count
|
return orderedViewControllers.count
|
||||||
}
|
}
|
||||||
|
|
||||||
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
|
func presentationIndex(for pageViewController: UIPageViewController) -> Int {
|
||||||
guard let firstViewController = viewControllers?.first,
|
guard let firstViewController = viewControllers?.first,
|
||||||
firstViewControllerIndex = orderedViewControllers.indexOf(firstViewController) else {
|
let firstViewControllerIndex = orderedViewControllers.index(of: firstViewController) else {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return firstViewControllerIndex
|
return firstViewControllerIndex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ class AnimationsExampleController: UIViewController {
|
|||||||
|
|
||||||
var animView: AnimationsView?
|
var animView: AnimationsView?
|
||||||
|
|
||||||
override func viewDidAppear(animated: Bool) {
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
super.viewDidAppear(animated)
|
super.viewDidAppear(animated)
|
||||||
|
|
||||||
animView?.prepareAnimation()
|
animView?.prepareAnimation()
|
||||||
|
@ -30,7 +30,7 @@ class AnimationsView: MacawView {
|
|||||||
var velocities = [Point]()
|
var velocities = [Point]()
|
||||||
var positions = [Point]()
|
var positions = [Point]()
|
||||||
|
|
||||||
func posForTime(t: Double, index: Int) -> Point {
|
func posForTime(_ t: Double, index: Int) -> Point {
|
||||||
|
|
||||||
let prevPos = positions[index]
|
let prevPos = positions[index]
|
||||||
var velocity = velocities[index]
|
var velocity = velocities[index]
|
||||||
|
@ -9,20 +9,20 @@ class ModelListenersExampleController: UIViewController {
|
|||||||
@IBOutlet weak var widthSteppter: UIStepper!
|
@IBOutlet weak var widthSteppter: UIStepper!
|
||||||
@IBOutlet weak var radiusStepper: UIStepper!
|
@IBOutlet weak var radiusStepper: UIStepper!
|
||||||
|
|
||||||
@IBAction func onHeightChange(sender: AnyObject) {
|
@IBAction func onHeightChange(_ sender: AnyObject) {
|
||||||
updateForm()
|
updateForm()
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func onWidthChange(sender: AnyObject) {
|
@IBAction func onWidthChange(_ sender: AnyObject) {
|
||||||
updateForm()
|
updateForm()
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func onRadiusChange(sender: AnyObject) {
|
@IBAction func onRadiusChange(_ sender: AnyObject) {
|
||||||
updateForm()
|
updateForm()
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateForm() {
|
func updateForm() {
|
||||||
let screenSize: CGRect = UIScreen.mainScreen().bounds
|
let screenSize: CGRect = UIScreen.main.bounds
|
||||||
let height = heightStepper.value
|
let height = heightStepper.value
|
||||||
let width = widthSteppter.value
|
let width = widthSteppter.value
|
||||||
let radius = radiusStepper.value
|
let radius = radiusStepper.value
|
||||||
|
@ -7,7 +7,7 @@ class RectShapeView: MacawView {
|
|||||||
var rectShape: Shape!
|
var rectShape: Shape!
|
||||||
|
|
||||||
required init?(coder aDecoder: NSCoder) {
|
required init?(coder aDecoder: NSCoder) {
|
||||||
let screenSize: CGRect = UIScreen.mainScreen().bounds
|
let screenSize: CGRect = UIScreen.main.bounds
|
||||||
|
|
||||||
let rect = RoundRect(
|
let rect = RoundRect(
|
||||||
rect: Rect(x: Double(screenSize.width / 2) - 50, y: Double(screenSize.height / 2) - 50, w: 100, h: 100),
|
rect: Rect(x: Double(screenSize.width / 2) - 50, y: Double(screenSize.height / 2) - 50, w: 100, h: 100),
|
||||||
@ -24,4 +24,4 @@ class RectShapeView: MacawView {
|
|||||||
super.init(node: rectShape, coder: aDecoder)
|
super.init(node: rectShape, coder: aDecoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ class PathExampleController: UIViewController {
|
|||||||
var sceneView: PathExampleView?
|
var sceneView: PathExampleView?
|
||||||
@IBOutlet var slider: UISlider?
|
@IBOutlet var slider: UISlider?
|
||||||
|
|
||||||
override func viewDidAppear(animated: Bool) {
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
super.viewDidAppear(animated)
|
super.viewDidAppear(animated)
|
||||||
|
|
||||||
sceneView?.testAnimation()
|
sceneView?.testAnimation()
|
||||||
@ -14,7 +14,7 @@ class PathExampleController: UIViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func onScaleUpdate(slider: UISlider) {
|
@IBAction func onScaleUpdate(_ slider: UISlider) {
|
||||||
sceneView?.updateScale(slider.value)
|
sceneView?.updateScale(slider.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,17 +135,17 @@ class PathExampleView: MacawView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testAnimation() {
|
func testAnimation() {
|
||||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(1 * NSEC_PER_SEC)), dispatch_get_main_queue()) {
|
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(1 * NSEC_PER_SEC)) / Double(NSEC_PER_SEC)) {
|
||||||
self.animation?.play()
|
self.animation?.play()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateScale(scale: Float) {
|
func updateScale(_ scale: Float) {
|
||||||
let rotation = GeomUtils.centerRotation(node: sceneGroup, place: initialTransform, angle: M_PI_4 * Double(scale))
|
let rotation = GeomUtils.centerRotation(node: sceneGroup, place: initialTransform, angle: M_PI_4 * Double(scale))
|
||||||
sceneGroup.place = rotation// GeomUtils.concat(t1: rotation, t2: initialTransform)
|
sceneGroup.place = rotation// GeomUtils.concat(t1: rotation, t2: initialTransform)
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func newScene() -> Node {
|
fileprivate static func newScene() -> Node {
|
||||||
let shape = Shape(form: Rect(x: -50, y: -50, w: 100, h: 100), fill: Color.blue)
|
let shape = Shape(form: Rect(x: -50, y: -50, w: 100, h: 100), fill: Color.blue)
|
||||||
let t1 = Transform.identity
|
let t1 = Transform.identity
|
||||||
let t2 = GeomUtils.centerRotation(node: shape, place: Transform.identity, angle: M_PI_4) // Transform.rotate(angle: M_PI_4)
|
let t2 = GeomUtils.centerRotation(node: shape, place: Transform.identity, angle: M_PI_4) // Transform.rotate(angle: M_PI_4)
|
||||||
|
@ -73,7 +73,7 @@ class ShapesExampleView: MacawView {
|
|||||||
super.init(node: group, coder: aDecoder)
|
super.init(node: group, coder: aDecoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func newText(text: String, _ place: Transform, baseline: Baseline = .bottom) -> Text {
|
fileprivate static func newText(_ text: String, _ place: Transform, baseline: Baseline = .bottom) -> Text {
|
||||||
return Text(text: text, fill: Color.black, baseline: baseline, align: .mid, place: place)
|
return Text(text: text, fill: Color.black, baseline: baseline, align: .mid, place: place)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,12 +13,12 @@ import Macaw
|
|||||||
|
|
||||||
class TransformExampleView: MacawView {
|
class TransformExampleView: MacawView {
|
||||||
|
|
||||||
private static let transforms = [Transform.scale(sx: 2, sy: 2),
|
fileprivate static let transforms = [Transform.scale(sx: 2, sy: 2),
|
||||||
Transform.move(dx: 100, dy: 30),
|
Transform.move(dx: 100, dy: 30),
|
||||||
Transform.rotate(angle: M_PI_4, x: 150, y: 80),
|
Transform.rotate(angle: M_PI_4, x: 150, y: 80),
|
||||||
Transform.rotate(angle: M_PI_4)]
|
Transform.rotate(angle: M_PI_4)]
|
||||||
|
|
||||||
private static let titles = ["Transform.scale(sx: 2, sy: 2)",
|
fileprivate static let titles = ["Transform.scale(sx: 2, sy: 2)",
|
||||||
"Transform.move(dx: 100, dy: 30)",
|
"Transform.move(dx: 100, dy: 30)",
|
||||||
"Transform.rotate(angle: M_PI_4, x: 150, y: 80)",
|
"Transform.rotate(angle: M_PI_4, x: 150, y: 80)",
|
||||||
"Transform.rotate(angle: M_PI_4)"]
|
"Transform.rotate(angle: M_PI_4)"]
|
||||||
@ -27,10 +27,10 @@ class TransformExampleView: MacawView {
|
|||||||
super.init(node: TransformExampleView.newScene(), coder: aDecoder)
|
super.init(node: TransformExampleView.newScene(), coder: aDecoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func newScene() -> Node {
|
fileprivate static func newScene() -> Node {
|
||||||
let shape = Shape(form: Rect(x: 0, y: 0, w: 50, h: 50), fill: Color.blue)
|
let shape = Shape(form: Rect(x: 0, y: 0, w: 50, h: 50), fill: Color.blue)
|
||||||
let textes = Group(place: .move(dx: 50, dy: 275))
|
let textes = Group(place: .move(dx: 50, dy: 275))
|
||||||
for (i, item) in titles.enumerate() {
|
for (i, item) in titles.enumerated() {
|
||||||
let place = Transform.move(dx: 0, dy: Double(i * 25))
|
let place = Transform.move(dx: 0, dy: Double(i * 25))
|
||||||
textes.contents.append(Text(text: item, baseline: .bottom, place: place, opacity: 0))
|
textes.contents.append(Text(text: item, baseline: .bottom, place: place, opacity: 0))
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ class TransformExampleView: MacawView {
|
|||||||
return Group(contents: [newAxes(), shape, textes], place: .move(dx: 10, dy: 30))
|
return Group(contents: [newAxes(), shape, textes], place: .move(dx: 10, dy: 30))
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func newAxes() -> Node {
|
fileprivate static func newAxes() -> Node {
|
||||||
var items: [Node] = []
|
var items: [Node] = []
|
||||||
let gray = Color(val: 0xF0F0F0)
|
let gray = Color(val: 0xF0F0F0)
|
||||||
for i in 1...20 {
|
for i in 1...20 {
|
||||||
|
@ -10,11 +10,11 @@ class MenuViewController: UIViewController, UITableViewDataSource, UITableViewDe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
|
func numberOfSections(in tableView: UITableView) -> Int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
guard let count = viewControllers?.count else {
|
guard let count = viewControllers?.count else {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@ -22,22 +22,22 @@ class MenuViewController: UIViewController, UITableViewDataSource, UITableViewDe
|
|||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
|
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
let cell = tableView.dequeueReusableCellWithIdentifier("menu_cell")!
|
let cell = tableView.dequeueReusableCell(withIdentifier: "menu_cell")!
|
||||||
|
|
||||||
if let viewController = viewControllers?[indexPath.row] {
|
if let viewController = viewControllers?[(indexPath as NSIndexPath).row] {
|
||||||
cell.textLabel?.text = viewController.title
|
cell.textLabel?.text = viewController.title
|
||||||
}
|
}
|
||||||
|
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
|
||||||
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
|
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
guard let selectedCtrl = viewControllers?[indexPath.row] else {
|
guard let selectedCtrl = viewControllers?[(indexPath as NSIndexPath).row] else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pageViewController?.setViewControllers([selectedCtrl],
|
pageViewController?.setViewControllers([selectedCtrl],
|
||||||
direction: .Forward, animated: true, completion: nil)
|
direction: .forward, animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
PODS:
|
PODS:
|
||||||
- Macaw (0.1.0):
|
- Macaw (0.1.0):
|
||||||
- RxSwift (~> 2.0s)
|
- RxSwift (= 3.0.0-beta.1)
|
||||||
- SWXMLHash (~> 2.3.0)
|
- SWXMLHash (~> 3.0.0)
|
||||||
- RxSwift (2.6.0)
|
- RxSwift (3.0.0-beta.1)
|
||||||
- SWXMLHash (2.3.2)
|
- SWXMLHash (3.0.2)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- Macaw (from `../`)
|
- Macaw (from `../`)
|
||||||
@ -13,9 +13,9 @@ EXTERNAL SOURCES:
|
|||||||
:path: ../
|
:path: ../
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
Macaw: 6d8c002627caf979148fd395770caf12112ecc2b
|
Macaw: 34daf17a1bacaea417aef1eeb1647123d43d6af5
|
||||||
RxSwift: 77f3a0b15324baa7a1c9bfa9f199648a82424e26
|
RxSwift: 0823e8d7969c23bfa9ddfb2afa4881e424a1a710
|
||||||
SWXMLHash: 2f8c49af765718ad56020c4f875ec3ff22612f06
|
SWXMLHash: e0f6935971f01b06fb228cf435510d998ecde647
|
||||||
|
|
||||||
PODFILE CHECKSUM: 151f0be871736eddfeeec5cda1747f8a81e679ef
|
PODFILE CHECKSUM: 151f0be871736eddfeeec5cda1747f8a81e679ef
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ Pod::Spec.new do |s|
|
|||||||
|
|
||||||
s.platform = :ios, '8.0'
|
s.platform = :ios, '8.0'
|
||||||
s.requires_arc = true
|
s.requires_arc = true
|
||||||
s.pod_target_xcconfig = { 'SWIFT_VERSION' => '2.3' }
|
s.pod_target_xcconfig = { 'SWIFT_VERSION' => '3.0' }
|
||||||
|
|
||||||
s.source_files = [
|
s.source_files = [
|
||||||
'Source/*.swift',
|
'Source/*.swift',
|
||||||
@ -57,6 +57,6 @@ Pod::Spec.new do |s|
|
|||||||
|
|
||||||
# s.public_header_files = 'Pod/Classes/**/*.h'
|
# s.public_header_files = 'Pod/Classes/**/*.h'
|
||||||
# s.frameworks = 'UIKit', 'MapKit'
|
# s.frameworks = 'UIKit', 'MapKit'
|
||||||
s.dependency 'SWXMLHash', '~> 2.3.0'
|
s.dependency 'SWXMLHash', '~> 3.0.0'
|
||||||
s.dependency 'RxSwift', '~> 2.0s '
|
s.dependency 'RxSwift', '3.0.0-beta.1'
|
||||||
end
|
end
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class AnimatableVariable<T: Interpolable> : Variable<T> {
|
open class AnimatableVariable<T: Interpolable> : Variable<T> {
|
||||||
|
|
||||||
internal var node: Node?
|
internal var node: Node?
|
||||||
|
|
||||||
|
@ -1,35 +1,35 @@
|
|||||||
public class Animation {
|
open class Animation {
|
||||||
|
|
||||||
internal init() {
|
internal init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func play() {
|
open func play() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func stop() {
|
open func stop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func easing(easing: Easing) -> Animation {
|
open func easing(_ easing: Easing) -> Animation {
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
public func delay(delay: Double) -> Animation {
|
open func delay(_ delay: Double) -> Animation {
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
public func cycle(count: Double) -> Animation {
|
open func cycle(_ count: Double) -> Animation {
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
public func reverse() -> Animation {
|
open func reverse() -> Animation {
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
public func autoreversed() -> Animation {
|
open func autoreversed() -> Animation {
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
public func onComplete(_: (() -> ())) -> Animation {
|
open func onComplete(_: (() -> ())) -> Animation {
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,18 +10,18 @@ import Foundation
|
|||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
enum AnimationType {
|
enum AnimationType {
|
||||||
case Unknown
|
case unknown
|
||||||
case AffineTransformation
|
case affineTransformation
|
||||||
case Opacity
|
case opacity
|
||||||
case Sequence
|
case sequence
|
||||||
case Combine
|
case combine
|
||||||
case Empty
|
case empty
|
||||||
}
|
}
|
||||||
|
|
||||||
class BasicAnimation: Animation {
|
class BasicAnimation: Animation {
|
||||||
|
|
||||||
var node: Node?
|
var node: Node?
|
||||||
var type = AnimationType.Unknown
|
var type = AnimationType.unknown
|
||||||
let ID: String
|
let ID: String
|
||||||
var next: BasicAnimation?
|
var next: BasicAnimation?
|
||||||
var removeFunc: (() -> ())?
|
var removeFunc: (() -> ())?
|
||||||
@ -31,49 +31,49 @@ class BasicAnimation: Animation {
|
|||||||
var delay = 0.0
|
var delay = 0.0
|
||||||
var autoreverses = false
|
var autoreverses = false
|
||||||
var onProgressUpdate: ((Double) -> ())?
|
var onProgressUpdate: ((Double) -> ())?
|
||||||
var easing = Easing.Ease
|
var easing = Easing.ease
|
||||||
var completion: (() -> ())?
|
var completion: (() -> ())?
|
||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
ID = NSUUID().UUIDString
|
ID = UUID().uuidString
|
||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func delay(delay: Double) -> Animation {
|
override open func delay(_ delay: Double) -> Animation {
|
||||||
self.delay += delay
|
self.delay += delay
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func cycle(count: Double) -> Animation {
|
override open func cycle(_ count: Double) -> Animation {
|
||||||
self.repeatCount = count
|
self.repeatCount = count
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func easing(easing: Easing) -> Animation {
|
override open func easing(_ easing: Easing) -> Animation {
|
||||||
self.easing = easing
|
self.easing = easing
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func autoreversed() -> Animation {
|
override open func autoreversed() -> Animation {
|
||||||
self.autoreverses = true
|
self.autoreverses = true
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func onComplete(f: (() -> ())) -> Animation {
|
override open func onComplete(_ f: @escaping (() -> ())) -> Animation {
|
||||||
self.completion = f
|
self.completion = f
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func play() {
|
override open func play() {
|
||||||
animationProducer.addAnimation(self)
|
animationProducer.addAnimation(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func stop() {
|
override open func stop() {
|
||||||
manualStop = true
|
manualStop = true
|
||||||
removeFunc?()
|
removeFunc?()
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func reverse() -> Animation {
|
override open func reverse() -> Animation {
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,9 +89,9 @@ internal class AnimationImpl<T: Interpolable>: BasicAnimation {
|
|||||||
let duration: Double
|
let duration: Double
|
||||||
let logicalFps: UInt
|
let logicalFps: UInt
|
||||||
|
|
||||||
private var vFunc: ((Double) -> T)?
|
fileprivate var vFunc: ((Double) -> T)?
|
||||||
|
|
||||||
init(observableValue: Variable<T>, valueFunc: (Double) -> T, animationDuration: Double, delay: Double = 0.0, fps: UInt = 30) {
|
init(observableValue: Variable<T>, valueFunc: @escaping (Double) -> T, animationDuration: Double, delay: Double = 0.0, fps: UInt = 30) {
|
||||||
self.value = observableValue
|
self.value = observableValue
|
||||||
self.duration = animationDuration
|
self.duration = animationDuration
|
||||||
self.timeFactory = { (node) in return valueFunc }
|
self.timeFactory = { (node) in return valueFunc }
|
||||||
@ -103,7 +103,7 @@ internal class AnimationImpl<T: Interpolable>: BasicAnimation {
|
|||||||
self.delay = delay
|
self.delay = delay
|
||||||
}
|
}
|
||||||
|
|
||||||
init(observableValue: Variable<T>, factory: ((Node) -> ((Double) -> T)), animationDuration: Double, delay: Double = 0.0, fps: UInt = 30) {
|
init(observableValue: Variable<T>, factory: @escaping ((Node) -> ((Double) -> T)), animationDuration: Double, delay: Double = 0.0, fps: UInt = 30) {
|
||||||
self.value = observableValue
|
self.value = observableValue
|
||||||
self.duration = animationDuration
|
self.duration = animationDuration
|
||||||
self.timeFactory = factory
|
self.timeFactory = factory
|
||||||
@ -126,11 +126,11 @@ internal class AnimationImpl<T: Interpolable>: BasicAnimation {
|
|||||||
self.init(observableValue: observableValue, startValue: observableValue.value, finalValue: finalValue, animationDuration: animationDuration)
|
self.init(observableValue: observableValue, startValue: observableValue.value, finalValue: finalValue, animationDuration: animationDuration)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func getDuration() -> Double {
|
open override func getDuration() -> Double {
|
||||||
return duration
|
return duration
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getVFunc() -> ((Double) -> T) {
|
open func getVFunc() -> ((Double) -> T) {
|
||||||
if (vFunc == nil) {
|
if (vFunc == nil) {
|
||||||
vFunc = timeFactory(self.node!)
|
vFunc = timeFactory(self.node!)
|
||||||
}
|
}
|
||||||
@ -141,27 +141,27 @@ internal class AnimationImpl<T: Interpolable>: BasicAnimation {
|
|||||||
|
|
||||||
// For sequence completion
|
// For sequence completion
|
||||||
class EmptyAnimation: BasicAnimation {
|
class EmptyAnimation: BasicAnimation {
|
||||||
required init(completion: (() -> ())) {
|
required init(completion: @escaping (() -> ())) {
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.completion = completion
|
self.completion = completion
|
||||||
self.type = .Empty
|
self.type = .empty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Animation Description
|
// MARK: - Animation Description
|
||||||
|
|
||||||
public class AnimationDescription <T> {
|
open class AnimationDescription <T> {
|
||||||
public let valueFunc: (Double) -> T
|
open let valueFunc: (Double) -> T
|
||||||
public var duration = 0.0
|
open var duration = 0.0
|
||||||
public var delay = 0.0
|
open var delay = 0.0
|
||||||
public init(valueFunc: (Double) -> T, duration: Double = 1.0, delay: Double = 0.0) {
|
public init(valueFunc: @escaping (Double) -> T, duration: Double = 1.0, delay: Double = 0.0) {
|
||||||
self.valueFunc = valueFunc
|
self.valueFunc = valueFunc
|
||||||
self.duration = duration
|
self.duration = duration
|
||||||
self.delay = delay
|
self.delay = delay
|
||||||
}
|
}
|
||||||
|
|
||||||
public func t(duration: Double, delay: Double = 0.0) -> AnimationDescription<T> {
|
open func t(_ duration: Double, delay: Double = 0.0) -> AnimationDescription<T> {
|
||||||
return AnimationDescription(valueFunc: valueFunc, duration: duration, delay: delay)
|
return AnimationDescription(valueFunc: valueFunc, duration: duration, delay: delay)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,18 +6,18 @@ class AnimationProducer {
|
|||||||
|
|
||||||
var storedAnimations = [Node: BasicAnimation]()
|
var storedAnimations = [Node: BasicAnimation]()
|
||||||
|
|
||||||
func addAnimation(animation: BasicAnimation, withoutDelay: Bool = false) {
|
func addAnimation(_ animation: BasicAnimation, withoutDelay: Bool = false) {
|
||||||
|
|
||||||
if animation.delay > 0.0 && !withoutDelay {
|
if animation.delay > 0.0 && !withoutDelay {
|
||||||
|
|
||||||
NSTimer.schedule(delay: animation.delay, handler: { _ in
|
Timer.schedule(delay: animation.delay, handler: { _ in
|
||||||
self.addAnimation(animation, withoutDelay: true)
|
self.addAnimation(animation, withoutDelay: true)
|
||||||
})
|
})
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if animation.type == .Empty {
|
if animation.type == .empty {
|
||||||
executeCompletion(animation)
|
executeCompletion(animation)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -36,30 +36,30 @@ class AnimationProducer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch animation.type {
|
switch animation.type {
|
||||||
case .Unknown:
|
case .unknown:
|
||||||
return
|
return
|
||||||
case .AffineTransformation:
|
case .affineTransformation:
|
||||||
addTransformAnimation(animation, sceneLayer: macawView.layer, animationCache: cache, completion: {
|
addTransformAnimation(animation, sceneLayer: macawView.layer, animationCache: cache, completion: {
|
||||||
if let next = animation.next {
|
if let next = animation.next {
|
||||||
self.addAnimation(next)
|
self.addAnimation(next)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
case .Opacity:
|
case .opacity:
|
||||||
addOpacityAnimation(animation, sceneLayer: macawView.layer, animationCache: cache, completion: {
|
addOpacityAnimation(animation, sceneLayer: macawView.layer, animationCache: cache, completion: {
|
||||||
if let next = animation.next {
|
if let next = animation.next {
|
||||||
self.addAnimation(next)
|
self.addAnimation(next)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
case .Sequence:
|
case .sequence:
|
||||||
addAnimationSequence(animation)
|
addAnimationSequence(animation)
|
||||||
case .Combine:
|
case .combine:
|
||||||
addCombineAnimation(animation)
|
addCombineAnimation(animation)
|
||||||
case .Empty:
|
case .empty:
|
||||||
executeCompletion(animation)
|
executeCompletion(animation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private func addAnimationSequence(animationSequnce: Animation) {
|
fileprivate func addAnimationSequence(_ animationSequnce: Animation) {
|
||||||
guard let sequence = animationSequnce as? AnimationSequence else {
|
guard let sequence = animationSequnce as? AnimationSequence else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -74,14 +74,14 @@ class AnimationProducer {
|
|||||||
var sequenceAnimations = [BasicAnimation]()
|
var sequenceAnimations = [BasicAnimation]()
|
||||||
if sequence.repeatCount > 0.0001 {
|
if sequence.repeatCount > 0.0001 {
|
||||||
for i in 0..<Int(sequence.repeatCount) {
|
for i in 0..<Int(sequence.repeatCount) {
|
||||||
sequenceAnimations.appendContentsOf(sequence.animations)
|
sequenceAnimations.append(contentsOf: sequence.animations)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sequenceAnimations.appendContentsOf(sequence.animations)
|
sequenceAnimations.append(contentsOf: sequence.animations)
|
||||||
}
|
}
|
||||||
|
|
||||||
if sequence.autoreverses {
|
if sequence.autoreverses {
|
||||||
sequenceAnimations = sequenceAnimations.reverse()
|
sequenceAnimations = sequenceAnimations.reversed()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connecting animations
|
// Connecting animations
|
||||||
@ -111,7 +111,7 @@ class AnimationProducer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func addCombineAnimation(combineAnimation: Animation) {
|
fileprivate func addCombineAnimation(_ combineAnimation: Animation) {
|
||||||
guard let combine = combineAnimation as? CombineAnimation else {
|
guard let combine = combineAnimation as? CombineAnimation else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -177,14 +177,14 @@ class AnimationProducer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func executeCompletion(emptyAnimation: BasicAnimation) {
|
fileprivate func executeCompletion(_ emptyAnimation: BasicAnimation) {
|
||||||
emptyAnimation.completion?()
|
emptyAnimation.completion?()
|
||||||
}
|
}
|
||||||
|
|
||||||
func addStoredAnimations(node: Node) {
|
func addStoredAnimations(_ node: Node) {
|
||||||
if let animation = storedAnimations[node] {
|
if let animation = storedAnimations[node] {
|
||||||
addAnimation(animation)
|
addAnimation(animation)
|
||||||
storedAnimations.removeValueForKey(node)
|
storedAnimations.removeValue(forKey: node)
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let group = node as? Group else {
|
guard let group = node as? Group else {
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
class AnimationUtils {
|
class AnimationUtils {
|
||||||
class func absolutePosition(node: Node) -> Transform {
|
class func absolutePosition(_ node: Node) -> Transform {
|
||||||
return AnimationUtils.absoluteTransform(node, pos: node.place)
|
return AnimationUtils.absoluteTransform(node, pos: node.place)
|
||||||
}
|
}
|
||||||
|
|
||||||
class func absoluteTransform(node: Node, pos: Transform) -> Transform {
|
class func absoluteTransform(_ node: Node, pos: Transform) -> Transform {
|
||||||
var transform = pos
|
var transform = pos
|
||||||
var parent = nodesMap.parents(node).first
|
var parent = nodesMap.parents(node).first
|
||||||
while parent != .None {
|
while parent != .none {
|
||||||
transform = GeomUtils.concat(t1: parent!.place, t2: transform)
|
transform = GeomUtils.concat(t1: parent!.place, t2: transform)
|
||||||
parent = nodesMap.parents(parent!).first
|
parent = nodesMap.parents(parent!).first
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
public enum Easing {
|
public enum Easing {
|
||||||
case Ease
|
case ease
|
||||||
case Linear
|
case linear
|
||||||
case EaseIn
|
case easeIn
|
||||||
case EaseOut
|
case easeOut
|
||||||
case EaseInOut
|
case easeInOut
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,12 @@ public extension Rect {
|
|||||||
return CGRect(x: self.x, y: self.y, width: self.w, height: self.h)
|
return CGRect(x: self.x, y: self.y, width: self.w, height: self.h)
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyTransform(transform: Transform) -> Rect {
|
func applyTransform(_ transform: Transform) -> Rect {
|
||||||
|
|
||||||
// TODO: Rewrite using math
|
// TODO: Rewrite using math
|
||||||
|
|
||||||
let cgTransform = RenderUtils.mapTransform(transform)
|
let cgTransform = RenderUtils.mapTransform(transform)
|
||||||
return Rect(cgRect: CGRectApplyAffineTransform(self.cgRect(), cgTransform))
|
return Rect(cgRect: self.cgRect().applying(cgTransform))
|
||||||
}
|
}
|
||||||
|
|
||||||
public func description() -> String {
|
public func description() -> String {
|
||||||
|
@ -5,7 +5,7 @@ public protocol DoubleInterpolation: Interpolable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension Double: DoubleInterpolation {
|
extension Double: DoubleInterpolation {
|
||||||
public func interpolate(endValue: Double, progress: Double) -> Double {
|
public func interpolate(_ endValue: Double, progress: Double) -> Double {
|
||||||
return self + (endValue - self) * progress
|
return self + (endValue - self) * progress
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public protocol Interpolable {
|
public protocol Interpolable {
|
||||||
func interpolate(endValue: Self, progress: Double) -> Self
|
func interpolate(_ endValue: Self, progress: Double) -> Self
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ public protocol TransformInterpolation: Interpolable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension Transform: TransformInterpolation {
|
extension Transform: TransformInterpolation {
|
||||||
public func interpolate(endValue: Transform, progress: Double) -> Transform {
|
public func interpolate(_ endValue: Transform, progress: Double) -> Transform {
|
||||||
return Transform(m11: self.m11.interpolate(endValue.m11, progress: progress),
|
return Transform(m11: self.m11.interpolate(endValue.m11, progress: progress),
|
||||||
m12: self.m12.interpolate(endValue.m12, progress: progress),
|
m12: self.m12.interpolate(endValue.m12, progress: progress),
|
||||||
m21: self.m21.interpolate(endValue.m21, progress: progress),
|
m21: self.m21.interpolate(endValue.m21, progress: progress),
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
|
|
||||||
|
|
||||||
func boundsForFunc(func2d: func2D) -> Rect {
|
func boundsForFunc(_ func2d: func2D) -> Rect {
|
||||||
|
|
||||||
var p = func2d(t: 0.0)
|
var p = func2d(0.0)
|
||||||
var minX = p.x
|
var minX = p.x
|
||||||
var minY = p.y
|
var minY = p.y
|
||||||
var maxX = minX
|
var maxX = minX
|
||||||
var maxY = minY
|
var maxY = minY
|
||||||
|
|
||||||
for t in 0.0.stride(to: 1.0, by: 0.01) {
|
for t in stride(from: 0.0, to: 1.0, by: 0.01) {
|
||||||
p = func2d(t: t)
|
p = func2d(t)
|
||||||
|
|
||||||
if minX > p.x {
|
if minX > p.x {
|
||||||
minX = p.x
|
minX = p.x
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
|
|
||||||
func pathBounds(path: Path) -> Rect? {
|
func pathBounds(_ path: Path) -> Rect? {
|
||||||
|
|
||||||
guard let firstSegment = path.segments.first else {
|
guard let firstSegment = path.segments.first else {
|
||||||
return .None
|
return .none
|
||||||
}
|
}
|
||||||
|
|
||||||
let firstSegmentInfo = pathSegmenInfo(firstSegment, currentPoint: .None, currentBezierPoint: .None)
|
let firstSegmentInfo = pathSegmenInfo(firstSegment, currentPoint: .none, currentBezierPoint: .none)
|
||||||
var bounds = firstSegmentInfo.0
|
var bounds = firstSegmentInfo.0
|
||||||
var currentPoint = firstSegmentInfo.1 ?? Point.origin
|
var currentPoint = firstSegmentInfo.1 ?? Point.origin
|
||||||
var cubicBezierPoint: Point?
|
var cubicBezierPoint: Point?
|
||||||
@ -40,19 +40,19 @@ func pathBounds(path: Path) -> Rect? {
|
|||||||
return bounds
|
return bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
func pathSegmenInfo(segment: PathSegment, currentPoint: Point?, currentBezierPoint: Point?)
|
func pathSegmenInfo(_ segment: PathSegment, currentPoint: Point?, currentBezierPoint: Point?)
|
||||||
-> (Rect?, Point?, Point?) { // Bounds, last point, last bezier point TODO: Replace as struct
|
-> (Rect?, Point?, Point?) { // Bounds, last point, last bezier point TODO: Replace as struct
|
||||||
|
|
||||||
let data = segment.data
|
let data = segment.data
|
||||||
switch segment.type {
|
switch segment.type {
|
||||||
case .m, .M:
|
case .m, .M:
|
||||||
let point = Point(x: data[0], y: data[1])
|
let point = Point(x: data[0], y: data[1])
|
||||||
return (Rect(x: point.x, y: point.y, w: 0.0, h: 0.0), point, .None)
|
return (Rect(x: point.x, y: point.y, w: 0.0, h: 0.0), point, .none)
|
||||||
case .c, .C:
|
case .c, .C:
|
||||||
return (cubicBounds(data), Point(x: data[4], y: data[5]), Point(x: data[2], y: data[3]))
|
return (cubicBounds(data), Point(x: data[4], y: data[5]), Point(x: data[2], y: data[3]))
|
||||||
case .s, .S:
|
case .s, .S:
|
||||||
guard let currentPoint = currentPoint else {
|
guard let currentPoint = currentPoint else {
|
||||||
return (.None, .None, .None)
|
return (.none, .none, .none)
|
||||||
}
|
}
|
||||||
|
|
||||||
var p2 = currentPoint
|
var p2 = currentPoint
|
||||||
@ -66,17 +66,17 @@ func pathSegmenInfo(segment: PathSegment, currentPoint: Point?, currentBezierPoi
|
|||||||
Point(x: data[2], y: data[3]),
|
Point(x: data[2], y: data[3]),
|
||||||
Point(x: p2.x, y: p2.y))
|
Point(x: p2.x, y: p2.y))
|
||||||
case .h, .H:
|
case .h, .H:
|
||||||
return (Rect(x: 0.0, y: 0.0, w: data[0], h: 0.0), Point(x: data[0], y: 0.0), .None)
|
return (Rect(x: 0.0, y: 0.0, w: data[0], h: 0.0), Point(x: data[0], y: 0.0), .none)
|
||||||
case .v, .V:
|
case .v, .V:
|
||||||
return (Rect(x: 0.0, y: 0.0, w: 0.0, h: data[0]), Point(x: 0.0, y: data[0]), .None)
|
return (Rect(x: 0.0, y: 0.0, w: 0.0, h: data[0]), Point(x: 0.0, y: data[0]), .none)
|
||||||
case .l, .L:
|
case .l, .L:
|
||||||
return (Rect(x: data[0], y: data[1], w: 0.0, h: 0.0), Point(x: data[0], y: data[1]), .None)
|
return (Rect(x: data[0], y: data[1], w: 0.0, h: 0.0), Point(x: data[0], y: data[1]), .none)
|
||||||
default:
|
default:
|
||||||
return (.None, .None, .None)
|
return (.none, .none, .none)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func cubicBounds(data: [Double]) -> Rect {
|
private func cubicBounds(_ data: [Double]) -> Rect {
|
||||||
let p0 = Point(x: 0, y: 0)
|
let p0 = Point(x: 0, y: 0)
|
||||||
let p1 = Point(x: data[0], y: data[1])
|
let p1 = Point(x: data[0], y: data[1])
|
||||||
let p2 = Point(x: data[2], y: data[3])
|
let p2 = Point(x: data[2], y: data[3])
|
||||||
@ -88,7 +88,7 @@ private func cubicBounds(data: [Double]) -> Rect {
|
|||||||
return boundsForFunc(bezier3)
|
return boundsForFunc(bezier3)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func sCubicBounds(data: [Double], currentPoint: Point, currentBezierPoint: Point?) -> Rect {
|
private func sCubicBounds(_ data: [Double], currentPoint: Point, currentBezierPoint: Point?) -> Rect {
|
||||||
|
|
||||||
let p0 = Point(x: 0, y: 0)
|
let p0 = Point(x: 0, y: 0)
|
||||||
let p1 = Point(x: data[0], y: data[1])
|
let p1 = Point(x: data[0], y: data[1])
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
typealias func2D = ((t: Double) -> (Point))
|
typealias func2D = ((_ t: Double) -> (Point))
|
||||||
|
|
||||||
func BezierFunc2D(t: Double, p0: Point, p1: Point, p2: Point, p3: Point) -> Point {
|
func BezierFunc2D(_ t: Double, p0: Point, p1: Point, p2: Point, p3: Point) -> Point {
|
||||||
return Point(
|
return Point(
|
||||||
x: polynom3(t, p0: p0.x, p1: p1.x, p2: p2.x, p3: p3.x),
|
x: polynom3(t, p0: p0.x, p1: p1.x, p2: p2.x, p3: p3.x),
|
||||||
y: polynom3(t, p0: p0.y, p1: p1.y, p2: p2.y, p3: p3.y))
|
y: polynom3(t, p0: p0.y, p1: p1.y, p2: p2.y, p3: p3.y))
|
||||||
}
|
}
|
||||||
|
|
||||||
func polynom3(t: Double, p0: Double, p1: Double, p2: Double, p3: Double) -> Double {
|
func polynom3(_ t: Double, p0: Double, p1: Double, p2: Double, p3: Double) -> Double {
|
||||||
let t1 = 1.0 - t
|
let t1 = 1.0 - t
|
||||||
return pow(t1, 3.0) * p0 + 3.0 * t * pow(t1, 2.0) * p1 + 3.0 * t * t * t1 * p2 + pow(t, 3.0) * p3
|
return pow(t1, 3.0) * p0 + 3.0 * t * pow(t1, 2.0) * p1 + 3.0 * t * t * t1 * p2 + pow(t, 3.0) * p3
|
||||||
}
|
}
|
||||||
|
@ -10,28 +10,28 @@ internal class AnimationSequence: BasicAnimation {
|
|||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.type = .Sequence
|
self.type = .sequence
|
||||||
self.node = animations.first?.node
|
self.node = animations.first?.node
|
||||||
self.delay = delay
|
self.delay = delay
|
||||||
}
|
}
|
||||||
|
|
||||||
override func getDuration() -> Double {
|
override func getDuration() -> Double {
|
||||||
return animations.map({ $0.getDuration() }).reduce(0, combine: { $0 + $1 })
|
return animations.map({ $0.getDuration() }).reduce(0, { $0 + $1 })
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func stop() {
|
open override func stop() {
|
||||||
animations.forEach { animation in
|
animations.forEach { animation in
|
||||||
animation.stop()
|
animation.stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func reverse() -> Animation {
|
open override func reverse() -> Animation {
|
||||||
var reversedAnimations = [BasicAnimation]()
|
var reversedAnimations = [BasicAnimation]()
|
||||||
animations.forEach { animation in
|
animations.forEach { animation in
|
||||||
reversedAnimations.append(animation.reverse() as! BasicAnimation)
|
reversedAnimations.append(animation.reverse() as! BasicAnimation)
|
||||||
}
|
}
|
||||||
|
|
||||||
let reversedSequence = reversedAnimations.reverse().sequence(delay: self.delay) as! BasicAnimation
|
let reversedSequence = reversedAnimations.reversed().sequence(delay: self.delay) as! BasicAnimation
|
||||||
reversedSequence.completion = completion
|
reversedSequence.completion = completion
|
||||||
reversedSequence.progress = progress
|
reversedSequence.progress = progress
|
||||||
|
|
||||||
@ -39,8 +39,8 @@ internal class AnimationSequence: BasicAnimation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension SequenceType where Generator.Element: Animation {
|
public extension Sequence where Iterator.Element: Animation {
|
||||||
public func sequence(delay delay: Double = 0.0) -> Animation {
|
public func sequence(delay: Double = 0.0) -> Animation {
|
||||||
|
|
||||||
var sequence = [BasicAnimation]()
|
var sequence = [BasicAnimation]()
|
||||||
self.forEach { animation in
|
self.forEach { animation in
|
||||||
|
@ -10,21 +10,21 @@ internal class CombineAnimation: BasicAnimation {
|
|||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.type = .Combine
|
self.type = .combine
|
||||||
self.node = animations.first?.node
|
self.node = animations.first?.node
|
||||||
self.delay = delay
|
self.delay = delay
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override func getDuration() -> Double {
|
override func getDuration() -> Double {
|
||||||
if let maxElement = animations.map({ $0.getDuration() }).maxElement() {
|
if let maxElement = animations.map({ $0.getDuration() }).max() {
|
||||||
return maxElement
|
return maxElement
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0.0
|
return 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func reverse() -> Animation {
|
open override func reverse() -> Animation {
|
||||||
var reversedAnimations = [BasicAnimation]()
|
var reversedAnimations = [BasicAnimation]()
|
||||||
animations.forEach { animation in
|
animations.forEach { animation in
|
||||||
reversedAnimations.append(animation.reverse() as! BasicAnimation)
|
reversedAnimations.append(animation.reverse() as! BasicAnimation)
|
||||||
@ -37,15 +37,15 @@ internal class CombineAnimation: BasicAnimation {
|
|||||||
return combineReversed
|
return combineReversed
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func stop() {
|
open override func stop() {
|
||||||
animations.forEach { animation in
|
animations.forEach { animation in
|
||||||
animation.stop()
|
animation.stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension SequenceType where Generator.Element: Animation {
|
public extension Sequence where Iterator.Element: Animation {
|
||||||
public func combine(delay delay: Double = 0.0) -> Animation {
|
public func combine(delay: Double = 0.0) -> Animation {
|
||||||
|
|
||||||
var toCombine = [BasicAnimation]()
|
var toCombine = [BasicAnimation]()
|
||||||
self.forEach { animation in
|
self.forEach { animation in
|
||||||
@ -53,4 +53,4 @@ public extension SequenceType where Generator.Element: Animation {
|
|||||||
}
|
}
|
||||||
return CombineAnimation(animations: toCombine, delay: delay)
|
return CombineAnimation(animations: toCombine, delay: delay)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ internal class OpacityAnimation: AnimationImpl<Double> {
|
|||||||
|
|
||||||
init(animatedNode: Node, valueFunc: (Double) -> Double, animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
|
init(animatedNode: Node, valueFunc: (Double) -> Double, animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
|
||||||
super.init(observableValue: animatedNode.opacityVar, valueFunc: valueFunc, animationDuration: animationDuration, delay: delay, fps: fps)
|
super.init(observableValue: animatedNode.opacityVar, valueFunc: valueFunc, animationDuration: animationDuration, delay: delay, fps: fps)
|
||||||
type = .Opacity
|
type = .opacity
|
||||||
node = animatedNode
|
node = animatedNode
|
||||||
|
|
||||||
if autostart {
|
if autostart {
|
||||||
@ -24,7 +24,7 @@ internal class OpacityAnimation: AnimationImpl<Double> {
|
|||||||
|
|
||||||
init(animatedNode: Node, factory: ((Node) -> ((Double) -> Double)), animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
|
init(animatedNode: Node, factory: ((Node) -> ((Double) -> Double)), animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
|
||||||
super.init(observableValue: animatedNode.opacityVar, factory: factory, animationDuration: animationDuration, delay: delay, fps: fps)
|
super.init(observableValue: animatedNode.opacityVar, factory: factory, animationDuration: animationDuration, delay: delay, fps: fps)
|
||||||
type = .Opacity
|
type = .opacity
|
||||||
node = animatedNode
|
node = animatedNode
|
||||||
|
|
||||||
if autostart {
|
if autostart {
|
||||||
@ -32,7 +32,7 @@ internal class OpacityAnimation: AnimationImpl<Double> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func reverse() -> Animation {
|
open override func reverse() -> Animation {
|
||||||
let factory = { (node: Node) -> (Double) -> Double in
|
let factory = { (node: Node) -> (Double) -> Double in
|
||||||
let original = self.timeFactory(node)
|
let original = self.timeFactory(node)
|
||||||
return { (t: Double) -> Double in
|
return { (t: Double) -> Double in
|
||||||
@ -52,19 +52,19 @@ internal class OpacityAnimation: AnimationImpl<Double> {
|
|||||||
public typealias OpacityAnimationDescription = AnimationDescription<Double>
|
public typealias OpacityAnimationDescription = AnimationDescription<Double>
|
||||||
|
|
||||||
public extension AnimatableVariable where T: DoubleInterpolation {
|
public extension AnimatableVariable where T: DoubleInterpolation {
|
||||||
public func animate(desc: OpacityAnimationDescription) {
|
public func animate(_ desc: OpacityAnimationDescription) {
|
||||||
let _ = OpacityAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: true)
|
let _ = OpacityAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func animation(desc: OpacityAnimationDescription) -> Animation {
|
public func animation(_ desc: OpacityAnimationDescription) -> Animation {
|
||||||
return OpacityAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: false)
|
return OpacityAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func animate(from from: Double? = nil, to: Double, during: Double = 1.0, delay: Double = 0.0) {
|
public func animate(from: Double? = nil, to: Double, during: Double = 1.0, delay: Double = 0.0) {
|
||||||
self.animate(((from ?? node!.opacity) >> to).t(during, delay: delay))
|
self.animate(((from ?? node!.opacity) >> to).t(during, delay: delay))
|
||||||
}
|
}
|
||||||
|
|
||||||
public func animation(from from: Double? = nil, to: Double, during: Double = 1.0, delay: Double = 0.0) -> Animation {
|
public func animation(from: Double? = nil, to: Double, during: Double = 1.0, delay: Double = 0.0) -> Animation {
|
||||||
if let safeFrom = from {
|
if let safeFrom = from {
|
||||||
return self.animation((safeFrom >> to).t(during, delay: delay))
|
return self.animation((safeFrom >> to).t(during, delay: delay))
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ public extension AnimatableVariable where T: DoubleInterpolation {
|
|||||||
return OpacityAnimation(animatedNode: self.node!, factory: factory, animationDuration: during, delay: delay)
|
return OpacityAnimation(animatedNode: self.node!, factory: factory, animationDuration: during, delay: delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func animation(f: (Double) -> Double, during: Double = 1.0, delay: Double = 0.0) -> Animation {
|
public func animation(_ f: (Double) -> Double, during: Double = 1.0, delay: Double = 0.0) -> Animation {
|
||||||
return OpacityAnimation(animatedNode: node!, valueFunc: f, animationDuration: during, delay: delay)
|
return OpacityAnimation(animatedNode: node!, valueFunc: f, animationDuration: during, delay: delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ internal class TransformAnimation: AnimationImpl<Transform> {
|
|||||||
|
|
||||||
init(animatedNode: Node, valueFunc: (Double) -> Transform, animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
|
init(animatedNode: Node, valueFunc: (Double) -> Transform, animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
|
||||||
super.init(observableValue: animatedNode.placeVar, valueFunc: valueFunc, animationDuration: animationDuration, delay: delay, fps: fps)
|
super.init(observableValue: animatedNode.placeVar, valueFunc: valueFunc, animationDuration: animationDuration, delay: delay, fps: fps)
|
||||||
type = .AffineTransformation
|
type = .affineTransformation
|
||||||
node = animatedNode
|
node = animatedNode
|
||||||
|
|
||||||
if autostart {
|
if autostart {
|
||||||
@ -23,7 +23,7 @@ internal class TransformAnimation: AnimationImpl<Transform> {
|
|||||||
|
|
||||||
init(animatedNode: Node, factory: ((Node) -> ((Double) -> Transform)), animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
|
init(animatedNode: Node, factory: ((Node) -> ((Double) -> Transform)), animationDuration: Double, delay: Double = 0.0, autostart: Bool = false, fps: UInt = 30) {
|
||||||
super.init(observableValue: animatedNode.placeVar, factory: factory, animationDuration: animationDuration, delay: delay, fps: fps)
|
super.init(observableValue: animatedNode.placeVar, factory: factory, animationDuration: animationDuration, delay: delay, fps: fps)
|
||||||
type = .AffineTransformation
|
type = .affineTransformation
|
||||||
node = animatedNode
|
node = animatedNode
|
||||||
|
|
||||||
if autostart {
|
if autostart {
|
||||||
@ -31,7 +31,7 @@ internal class TransformAnimation: AnimationImpl<Transform> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func reverse() -> Animation {
|
open override func reverse() -> Animation {
|
||||||
|
|
||||||
let factory = { (node: Node) -> (Double) -> Transform in
|
let factory = { (node: Node) -> (Double) -> Transform in
|
||||||
let original = self.timeFactory(node)
|
let original = self.timeFactory(node)
|
||||||
@ -52,19 +52,19 @@ internal class TransformAnimation: AnimationImpl<Transform> {
|
|||||||
public typealias TransformAnimationDescription = AnimationDescription<Transform>
|
public typealias TransformAnimationDescription = AnimationDescription<Transform>
|
||||||
|
|
||||||
public extension AnimatableVariable where T: TransformInterpolation {
|
public extension AnimatableVariable where T: TransformInterpolation {
|
||||||
public func animate(desc: TransformAnimationDescription) {
|
public func animate(_ desc: TransformAnimationDescription) {
|
||||||
let _ = TransformAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: true)
|
let _ = TransformAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func animation(desc: TransformAnimationDescription) -> Animation {
|
public func animation(_ desc: TransformAnimationDescription) -> Animation {
|
||||||
return TransformAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: false)
|
return TransformAnimation(animatedNode: node!, valueFunc: desc.valueFunc, animationDuration: desc.duration, delay: desc.delay, autostart: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func animate(from from: Transform? = nil, to: Transform, during: Double = 1.0, delay: Double = 0.0) {
|
public func animate(from: Transform? = nil, to: Transform, during: Double = 1.0, delay: Double = 0.0) {
|
||||||
self.animate(((from ?? node!.place) >> to).t(during, delay: delay))
|
self.animate(((from ?? node!.place) >> to).t(during, delay: delay))
|
||||||
}
|
}
|
||||||
|
|
||||||
public func animation(from from: Transform? = nil, to: Transform, during: Double = 1.0, delay: Double = 0.0) -> Animation {
|
public func animation(from: Transform? = nil, to: Transform, during: Double = 1.0, delay: Double = 0.0) -> Animation {
|
||||||
if let safeFrom = from {
|
if let safeFrom = from {
|
||||||
return self.animation((safeFrom >> to).t(during, delay: delay))
|
return self.animation((safeFrom >> to).t(during, delay: delay))
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ public extension AnimatableVariable where T: TransformInterpolation {
|
|||||||
return TransformAnimation(animatedNode: self.node!, factory: factory, animationDuration: during, delay: delay)
|
return TransformAnimation(animatedNode: self.node!, factory: factory, animationDuration: during, delay: delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func animation(f: (Double) -> Transform, during: Double, delay: Double = 0.0) -> Animation {
|
public func animation(_ f: (Double) -> Transform, during: Double, delay: Double = 0.0) -> Animation {
|
||||||
return TransformAnimation(animatedNode: node!, valueFunc: f, animationDuration: during, delay: delay)
|
return TransformAnimation(animatedNode: node!, valueFunc: f, animationDuration: during, delay: delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ class AnimationCache {
|
|||||||
self.sceneLayer = sceneLayer
|
self.sceneLayer = sceneLayer
|
||||||
}
|
}
|
||||||
|
|
||||||
func layerForNode(node: Node, animation: Animation) -> ShapeLayer {
|
func layerForNode(_ node: Node, animation: Animation) -> ShapeLayer {
|
||||||
guard let cachedLayer = layerCache[node] else {
|
guard let cachedLayer = layerCache[node] else {
|
||||||
let layer = ShapeLayer()
|
let layer = ShapeLayer()
|
||||||
layer.animationCache = self
|
layer.animationCache = self
|
||||||
@ -35,17 +35,17 @@ class AnimationCache {
|
|||||||
if let shapeBounds = node.bounds() {
|
if let shapeBounds = node.bounds() {
|
||||||
let cgRect = shapeBounds.cgRect()
|
let cgRect = shapeBounds.cgRect()
|
||||||
|
|
||||||
let origFrame = CGRectMake(0.0, 0.0,
|
let origFrame = CGRect(x: 0.0, y: 0.0,
|
||||||
round(cgRect.width),
|
width: round(cgRect.width),
|
||||||
round(cgRect.height))
|
height: round(cgRect.height))
|
||||||
|
|
||||||
layer.bounds = origFrame
|
layer.bounds = origFrame
|
||||||
layer.anchorPoint = CGPointMake(
|
layer.anchorPoint = CGPoint(
|
||||||
-1.0 * cgRect.origin.x / cgRect.width,
|
x: -1.0 * cgRect.origin.x / cgRect.width,
|
||||||
-1.0 * cgRect.origin.y / cgRect.height
|
y: -1.0 * cgRect.origin.y / cgRect.height
|
||||||
)
|
)
|
||||||
|
|
||||||
layer.renderTransform = CGAffineTransformMakeTranslation(-1.0 * cgRect.origin.x, -1.0 * cgRect.origin.y)
|
layer.renderTransform = CGAffineTransform(translationX: -1.0 * cgRect.origin.x, y: -1.0 * cgRect.origin.y)
|
||||||
|
|
||||||
let nodeTransform = RenderUtils.mapTransform(AnimationUtils.absolutePosition(node))
|
let nodeTransform = RenderUtils.mapTransform(AnimationUtils.absolutePosition(node))
|
||||||
layer.transform = CATransform3DMakeAffineTransform(nodeTransform)
|
layer.transform = CATransform3DMakeAffineTransform(nodeTransform)
|
||||||
@ -67,7 +67,7 @@ class AnimationCache {
|
|||||||
return cachedLayer.layer
|
return cachedLayer.layer
|
||||||
}
|
}
|
||||||
|
|
||||||
func freeLayer(node: Node) {
|
func freeLayer(_ node: Node) {
|
||||||
guard let cachedLayer = layerCache[node] else {
|
guard let cachedLayer = layerCache[node] else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -79,12 +79,12 @@ class AnimationCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let layer = cachedLayer.layer
|
let layer = cachedLayer.layer
|
||||||
layerCache.removeValueForKey(node)
|
layerCache.removeValue(forKey: node)
|
||||||
sceneLayer.setNeedsDisplay()
|
sceneLayer.setNeedsDisplay()
|
||||||
layer.removeFromSuperlayer()
|
layer.removeFromSuperlayer()
|
||||||
}
|
}
|
||||||
|
|
||||||
func isAnimating(node: Node) -> Bool {
|
func isAnimating(_ node: Node) -> Bool {
|
||||||
|
|
||||||
if let _ = layerCache[node] {
|
if let _ = layerCache[node] {
|
||||||
return true
|
return true
|
||||||
@ -93,7 +93,7 @@ class AnimationCache {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func isChildrenAnimating(group: Group) -> Bool {
|
func isChildrenAnimating(_ group: Group) -> Bool {
|
||||||
|
|
||||||
for child in group.contents {
|
for child in group.contents {
|
||||||
if isAnimating(child) {
|
if isAnimating(child) {
|
||||||
@ -108,7 +108,7 @@ class AnimationCache {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func containsAnimation(node: Node) -> Bool {
|
func containsAnimation(_ node: Node) -> Bool {
|
||||||
if isAnimating(node) {
|
if isAnimating(node) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
let animationRestorer = AnimationRestorer()
|
let animationRestorer = AnimationRestorer()
|
||||||
public class AnimationRestorer {
|
open class AnimationRestorer {
|
||||||
typealias RestoreClosure = () -> ()
|
typealias RestoreClosure = () -> ()
|
||||||
var restoreClosures = [RestoreClosure]()
|
var restoreClosures = [RestoreClosure]()
|
||||||
|
|
||||||
func addRestoreClosure(closure: RestoreClosure) {
|
func addRestoreClosure(_ closure: @escaping RestoreClosure) {
|
||||||
restoreClosures.append(closure)
|
restoreClosures.append(closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
public class func restore() {
|
open class func restore() {
|
||||||
dispatch_async(dispatch_get_main_queue()) {
|
DispatchQueue.main.async {
|
||||||
animationRestorer.restoreClosures.forEach { restoreClosure in
|
animationRestorer.restoreClosures.forEach { restoreClosure in
|
||||||
restoreClosure()
|
restoreClosure()
|
||||||
}
|
}
|
||||||
@ -18,4 +18,4 @@ public class AnimationRestorer {
|
|||||||
animationRestorer.restoreClosures.removeAll()
|
animationRestorer.restoreClosures.removeAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,10 @@ import Macaw
|
|||||||
extension Node: Hashable {
|
extension Node: Hashable {
|
||||||
public var hashValue: Int {
|
public var hashValue: Int {
|
||||||
|
|
||||||
return unsafeAddressOf(self).hashValue
|
return Unmanaged.passUnretained(self).toOpaque().hashValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func == (lhs: Node, rhs: Node) -> Bool {
|
public func == (lhs: Node, rhs: Node) -> Bool {
|
||||||
return unsafeAddressOf(lhs) == unsafeAddressOf(rhs)
|
return Unmanaged.passUnretained(lhs).toOpaque() == Unmanaged.passUnretained(rhs).toOpaque()
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
func addOpacityAnimation(animation: BasicAnimation, sceneLayer: CALayer, animationCache: AnimationCache, completion: (() -> ())) {
|
func addOpacityAnimation(_ animation: BasicAnimation, sceneLayer: CALayer, animationCache: AnimationCache, completion: @escaping (() -> ())) {
|
||||||
guard let opacityAnimation = animation as? OpacityAnimation else {
|
guard let opacityAnimation = animation as? OpacityAnimation else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -47,13 +47,13 @@ func addOpacityAnimation(animation: BasicAnimation, sceneLayer: CALayer, animati
|
|||||||
}
|
}
|
||||||
|
|
||||||
let layer = animationCache.layerForNode(node, animation: animation)
|
let layer = animationCache.layerForNode(node, animation: animation)
|
||||||
layer.addAnimation(generatedAnimation, forKey: animation.ID)
|
layer.add(generatedAnimation, forKey: animation.ID)
|
||||||
animation.removeFunc = {
|
animation.removeFunc = {
|
||||||
layer.removeAnimationForKey(animation.ID)
|
layer.removeAnimation(forKey: animation.ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func opacityAnimationByFunc(valueFunc: (Double) -> Double, duration: Double, fps: UInt) -> CAAnimation {
|
func opacityAnimationByFunc(_ valueFunc: (Double) -> Double, duration: Double, fps: UInt) -> CAAnimation {
|
||||||
|
|
||||||
var opacityValues = [Double]()
|
var opacityValues = [Double]()
|
||||||
var timeValues = [Double]()
|
var timeValues = [Double]()
|
||||||
@ -61,7 +61,7 @@ func opacityAnimationByFunc(valueFunc: (Double) -> Double, duration: Double, fps
|
|||||||
let step = 1.0 / (duration * Double(fps))
|
let step = 1.0 / (duration * Double(fps))
|
||||||
|
|
||||||
var dt = 0.0
|
var dt = 0.0
|
||||||
for t in 0.0.stride(to: 1.0, by: step) {
|
for t in stride(from: 0.0, to: 1.0, by: step) {
|
||||||
|
|
||||||
dt = t
|
dt = t
|
||||||
if 1.0 - dt < step {
|
if 1.0 - dt < step {
|
||||||
@ -75,11 +75,11 @@ func opacityAnimationByFunc(valueFunc: (Double) -> Double, duration: Double, fps
|
|||||||
|
|
||||||
let opacityAnimation = CAKeyframeAnimation(keyPath: "opacity")
|
let opacityAnimation = CAKeyframeAnimation(keyPath: "opacity")
|
||||||
opacityAnimation.fillMode = kCAFillModeForwards
|
opacityAnimation.fillMode = kCAFillModeForwards
|
||||||
opacityAnimation.removedOnCompletion = false
|
opacityAnimation.isRemovedOnCompletion = false
|
||||||
|
|
||||||
opacityAnimation.duration = duration
|
opacityAnimation.duration = duration
|
||||||
opacityAnimation.values = opacityValues
|
opacityAnimation.values = opacityValues
|
||||||
opacityAnimation.keyTimes = timeValues
|
opacityAnimation.keyTimes = timeValues as [NSNumber]?
|
||||||
|
|
||||||
return opacityAnimation
|
return opacityAnimation
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
func caTimingFunction(easing: Easing) -> CAMediaTimingFunction {
|
func caTimingFunction(_ easing: Easing) -> CAMediaTimingFunction {
|
||||||
switch easing {
|
switch easing {
|
||||||
case .Ease:
|
case .ease:
|
||||||
return CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)
|
return CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)
|
||||||
case .Linear:
|
case .linear:
|
||||||
return CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
|
return CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
|
||||||
case .EaseIn:
|
case .easeIn:
|
||||||
return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
|
return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
|
||||||
case .EaseOut:
|
case .easeOut:
|
||||||
return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
|
return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
|
||||||
case .EaseInOut:
|
case .easeInOut:
|
||||||
return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
|
return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
func addTransformAnimation(animation: BasicAnimation, sceneLayer: CALayer, animationCache: AnimationCache, completion: (() -> ())) {
|
func addTransformAnimation(_ animation: BasicAnimation, sceneLayer: CALayer, animationCache: AnimationCache, completion: @escaping (() -> ())) {
|
||||||
guard let transformAnimation = animation as? TransformAnimation else {
|
guard let transformAnimation = animation as? TransformAnimation else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -53,23 +53,23 @@ func addTransformAnimation(animation: BasicAnimation, sceneLayer: CALayer, anima
|
|||||||
|
|
||||||
let layer = animationCache.layerForNode(node, animation: animation)
|
let layer = animationCache.layerForNode(node, animation: animation)
|
||||||
|
|
||||||
layer.addAnimation(generatedAnim, forKey: animation.ID)
|
layer.add(generatedAnim, forKey: animation.ID)
|
||||||
animation.removeFunc = {
|
animation.removeFunc = {
|
||||||
layer.removeAnimationForKey(animation.ID)
|
layer.removeAnimation(forKey: animation.ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func transfomToCG(transform: Transform) -> CGAffineTransform {
|
func transfomToCG(_ transform: Transform) -> CGAffineTransform {
|
||||||
return CGAffineTransformMake(
|
return CGAffineTransform(
|
||||||
CGFloat(transform.m11),
|
a: CGFloat(transform.m11),
|
||||||
CGFloat(transform.m12),
|
b: CGFloat(transform.m12),
|
||||||
CGFloat(transform.m21),
|
c: CGFloat(transform.m21),
|
||||||
CGFloat(transform.m22),
|
d: CGFloat(transform.m22),
|
||||||
CGFloat(transform.dx),
|
tx: CGFloat(transform.dx),
|
||||||
CGFloat(transform.dy))
|
ty: CGFloat(transform.dy))
|
||||||
}
|
}
|
||||||
|
|
||||||
func transformAnimationByFunc(node: Node, valueFunc: (Double) -> Transform, duration: Double, fps: UInt) -> CAAnimation {
|
func transformAnimationByFunc(_ node: Node, valueFunc: (Double) -> Transform, duration: Double, fps: UInt) -> CAAnimation {
|
||||||
|
|
||||||
var scaleXValues = [CGFloat]()
|
var scaleXValues = [CGFloat]()
|
||||||
var scaleYValues = [CGFloat]()
|
var scaleYValues = [CGFloat]()
|
||||||
@ -80,7 +80,7 @@ func transformAnimationByFunc(node: Node, valueFunc: (Double) -> Transform, dura
|
|||||||
|
|
||||||
let step = 1.0 / (duration * Double(fps))
|
let step = 1.0 / (duration * Double(fps))
|
||||||
var dt = 0.0
|
var dt = 0.0
|
||||||
for t in 0.0.stride(to: 1.0, by: step) {
|
for t in stride(from: 0.0, to: 1.0, by: step) {
|
||||||
|
|
||||||
dt = t
|
dt = t
|
||||||
if 1.0 - dt < step {
|
if 1.0 - dt < step {
|
||||||
@ -112,31 +112,31 @@ func transformAnimationByFunc(node: Node, valueFunc: (Double) -> Transform, dura
|
|||||||
let xAnimation = CAKeyframeAnimation(keyPath: "transform.translation.x")
|
let xAnimation = CAKeyframeAnimation(keyPath: "transform.translation.x")
|
||||||
xAnimation.duration = duration
|
xAnimation.duration = duration
|
||||||
xAnimation.values = xValues
|
xAnimation.values = xValues
|
||||||
xAnimation.keyTimes = timeValues
|
xAnimation.keyTimes = timeValues as [NSNumber]?
|
||||||
|
|
||||||
let yAnimation = CAKeyframeAnimation(keyPath: "transform.translation.y")
|
let yAnimation = CAKeyframeAnimation(keyPath: "transform.translation.y")
|
||||||
yAnimation.duration = duration
|
yAnimation.duration = duration
|
||||||
yAnimation.values = yValues
|
yAnimation.values = yValues
|
||||||
yAnimation.keyTimes = timeValues
|
yAnimation.keyTimes = timeValues as [NSNumber]?
|
||||||
|
|
||||||
let scaleXAnimation = CAKeyframeAnimation(keyPath: "transform.scale.x")
|
let scaleXAnimation = CAKeyframeAnimation(keyPath: "transform.scale.x")
|
||||||
scaleXAnimation.duration = duration
|
scaleXAnimation.duration = duration
|
||||||
scaleXAnimation.values = scaleXValues
|
scaleXAnimation.values = scaleXValues
|
||||||
scaleXAnimation.keyTimes = timeValues
|
scaleXAnimation.keyTimes = timeValues as [NSNumber]?
|
||||||
|
|
||||||
let scaleYAnimation = CAKeyframeAnimation(keyPath: "transform.scale.y")
|
let scaleYAnimation = CAKeyframeAnimation(keyPath: "transform.scale.y")
|
||||||
scaleYAnimation.duration = duration
|
scaleYAnimation.duration = duration
|
||||||
scaleYAnimation.values = scaleYValues
|
scaleYAnimation.values = scaleYValues
|
||||||
scaleYAnimation.keyTimes = timeValues
|
scaleYAnimation.keyTimes = timeValues as [NSNumber]?
|
||||||
|
|
||||||
let rotationAnimation = CAKeyframeAnimation(keyPath: "transform.rotation.z")
|
let rotationAnimation = CAKeyframeAnimation(keyPath: "transform.rotation.z")
|
||||||
rotationAnimation.duration = duration
|
rotationAnimation.duration = duration
|
||||||
rotationAnimation.values = rotationValues
|
rotationAnimation.values = rotationValues
|
||||||
rotationAnimation.keyTimes = timeValues
|
rotationAnimation.keyTimes = timeValues as [NSNumber]?
|
||||||
|
|
||||||
let group = CAAnimationGroup()
|
let group = CAAnimationGroup()
|
||||||
group.fillMode = kCAFillModeForwards
|
group.fillMode = kCAFillModeForwards
|
||||||
group.removedOnCompletion = false
|
group.isRemovedOnCompletion = false
|
||||||
|
|
||||||
group.animations = [scaleXAnimation, scaleYAnimation, rotationAnimation, xAnimation, yAnimation]
|
group.animations = [scaleXAnimation, scaleYAnimation, rotationAnimation, xAnimation, yAnimation]
|
||||||
group.duration = duration
|
group.duration = duration
|
||||||
@ -144,6 +144,6 @@ func transformAnimationByFunc(node: Node, valueFunc: (Double) -> Transform, dura
|
|||||||
return group
|
return group
|
||||||
}
|
}
|
||||||
|
|
||||||
func fixedAngle(angle: CGFloat) -> CGFloat {
|
func fixedAngle(_ angle: CGFloat) -> CGFloat {
|
||||||
return angle > -0.0000000000000000000000001 ? angle : CGFloat(2.0 * M_PI) + angle
|
return angle > -0.0000000000000000000000001 ? angle : CGFloat(2.0 * M_PI) + angle
|
||||||
}
|
}
|
||||||
|
@ -8,25 +8,25 @@
|
|||||||
|
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class GroupDisposable: Disposable {
|
open class GroupDisposable: Disposable {
|
||||||
|
|
||||||
private var items: [Disposable] = []
|
fileprivate var items: [Disposable] = []
|
||||||
|
|
||||||
public func dispose() {
|
open func dispose() {
|
||||||
for disposable in items {
|
for disposable in items {
|
||||||
disposable.dispose()
|
disposable.dispose()
|
||||||
}
|
}
|
||||||
items = []
|
items = []
|
||||||
}
|
}
|
||||||
|
|
||||||
public func add(item: Disposable) {
|
open func add(_ item: Disposable) {
|
||||||
items.append(item)
|
items.append(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Disposable {
|
extension Disposable {
|
||||||
public func addTo(group: GroupDisposable) {
|
public func addTo(_ group: GroupDisposable) {
|
||||||
group.add(self)
|
group.add(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ public struct ArrayChangeEvent {
|
|||||||
public let deletedIndices: [Int]
|
public let deletedIndices: [Int]
|
||||||
public let updatedIndices: [Int]
|
public let updatedIndices: [Int]
|
||||||
|
|
||||||
private init(inserted: [Int] = [], deleted: [Int] = [], updated: [Int] = []) {
|
fileprivate init(inserted: [Int] = [], deleted: [Int] = [], updated: [Int] = []) {
|
||||||
assert(inserted.count + deleted.count + updated.count > 0)
|
assert(inserted.count + deleted.count + updated.count > 0)
|
||||||
self.insertedIndices = inserted
|
self.insertedIndices = inserted
|
||||||
self.deletedIndices = deleted
|
self.deletedIndices = deleted
|
||||||
@ -23,7 +23,7 @@ public struct ArrayChangeEvent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct ObservableArray<Element>: ArrayLiteralConvertible {
|
public struct ObservableArray<Element>: ExpressibleByArrayLiteral {
|
||||||
public typealias EventType = ArrayChangeEvent
|
public typealias EventType = ArrayChangeEvent
|
||||||
|
|
||||||
internal var eventSubject: PublishSubject<EventType>!
|
internal var eventSubject: PublishSubject<EventType>!
|
||||||
@ -35,10 +35,10 @@ public struct ObservableArray<Element>: ArrayLiteralConvertible {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public init(count:Int, repeatedValue: Element) {
|
public init(count:Int, repeatedValue: Element) {
|
||||||
self.elements = Array(count: count, repeatedValue: repeatedValue)
|
self.elements = Array(repeating: repeatedValue, count: count)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init<S : SequenceType where S.Generator.Element == Element>(_ s: S) {
|
public init<S : Sequence>(_ s: S) where S.Iterator.Element == Element {
|
||||||
self.elements = Array(s)
|
self.elements = Array(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ extension ObservableArray {
|
|||||||
return eventSubject
|
return eventSubject
|
||||||
}
|
}
|
||||||
|
|
||||||
private func arrayDidChange(event: EventType) {
|
fileprivate func arrayDidChange(_ event: EventType) {
|
||||||
elementsSubject?.onNext(elements)
|
elementsSubject?.onNext(elements)
|
||||||
eventSubject?.onNext(event)
|
eventSubject?.onNext(event)
|
||||||
}
|
}
|
||||||
@ -82,35 +82,35 @@ extension ObservableArray: Indexable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ObservableArray: RangeReplaceableCollectionType {
|
extension ObservableArray: RangeReplaceableCollection {
|
||||||
public var capacity: Int {
|
public var capacity: Int {
|
||||||
return elements.capacity
|
return elements.capacity
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func reserveCapacity(minimumCapacity: Int) {
|
public mutating func reserveCapacity(_ minimumCapacity: Int) {
|
||||||
elements.reserveCapacity(minimumCapacity)
|
elements.reserveCapacity(minimumCapacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func append(newElement: Element) {
|
public mutating func append(_ newElement: Element) {
|
||||||
elements.append(newElement)
|
elements.append(newElement)
|
||||||
arrayDidChange(ArrayChangeEvent(inserted: [elements.count - 1]))
|
arrayDidChange(ArrayChangeEvent(inserted: [elements.count - 1]))
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func appendContentsOf<S : SequenceType where S.Generator.Element == Element>(newElements: S) {
|
public mutating func append<S : Sequence>(contentsOf newElements: S) where S.Iterator.Element == Element {
|
||||||
let end = elements.count
|
let end = elements.count
|
||||||
elements.appendContentsOf(newElements)
|
elements.append(contentsOf: newElements)
|
||||||
guard end != elements.count else {
|
guard end != elements.count else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
arrayDidChange(ArrayChangeEvent(inserted: Array(end..<elements.count)))
|
arrayDidChange(ArrayChangeEvent(inserted: Array(end..<elements.count)))
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func appendContentsOf<C : CollectionType where C.Generator.Element == Element>(newElements: C) {
|
public mutating func appendContentsOf<C : Collection>(_ newElements: C) where C.Iterator.Element == Element {
|
||||||
guard !newElements.isEmpty else {
|
guard !newElements.isEmpty else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let end = elements.count
|
let end = elements.count
|
||||||
elements.appendContentsOf(newElements)
|
elements.append(contentsOf: newElements)
|
||||||
arrayDidChange(ArrayChangeEvent(inserted: Array(end..<elements.count)))
|
arrayDidChange(ArrayChangeEvent(inserted: Array(end..<elements.count)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,37 +120,37 @@ extension ObservableArray: RangeReplaceableCollectionType {
|
|||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func insert(newElement: Element, atIndex i: Int) {
|
public mutating func insert(_ newElement: Element, at i: Int) {
|
||||||
elements.insert(newElement, atIndex: i)
|
elements.insert(newElement, at: i)
|
||||||
arrayDidChange(ArrayChangeEvent(inserted: [i]))
|
arrayDidChange(ArrayChangeEvent(inserted: [i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func removeAtIndex(index: Int) -> Element {
|
public mutating func remove(at index: Int) -> Element {
|
||||||
let e = elements.removeAtIndex(index)
|
let e = elements.remove(at: index)
|
||||||
arrayDidChange(ArrayChangeEvent(deleted: [index]))
|
arrayDidChange(ArrayChangeEvent(deleted: [index]))
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func removeAll(keepCapacity: Bool = false) {
|
public mutating func removeAll(_ keepCapacity: Bool = false) {
|
||||||
guard !elements.isEmpty else {
|
guard !elements.isEmpty else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let es = elements
|
let es = elements
|
||||||
elements.removeAll(keepCapacity: keepCapacity)
|
elements.removeAll(keepingCapacity: keepCapacity)
|
||||||
arrayDidChange(ArrayChangeEvent(deleted: Array(0..<es.count)))
|
arrayDidChange(ArrayChangeEvent(deleted: Array(0..<es.count)))
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func insertContentsOf(newElements: [Element], atIndex i: Int) {
|
public mutating func insertContentsOf(_ newElements: [Element], atIndex i: Int) {
|
||||||
guard !newElements.isEmpty else {
|
guard !newElements.isEmpty else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
elements.insertContentsOf(newElements, at: i)
|
elements.insert(contentsOf: newElements, at: i)
|
||||||
arrayDidChange(ArrayChangeEvent(inserted: Array(i..<i + newElements.count)))
|
arrayDidChange(ArrayChangeEvent(inserted: Array(i..<i + newElements.count)))
|
||||||
}
|
}
|
||||||
|
|
||||||
public mutating func replaceRange<C : CollectionType where C.Generator.Element == Element>(subRange: Range<Int>, with newCollection: C) {
|
public mutating func replaceSubrange<C : Collection>(_ subRange: Range<Int>, with newCollection: C) where C.Iterator.Element == Element {
|
||||||
let oldCount = elements.count
|
let oldCount = elements.count
|
||||||
elements.replaceRange(subRange, with: newCollection)
|
elements.replaceSubrange(subRange, with: newCollection)
|
||||||
guard let first = subRange.first else {
|
guard let first = subRange.first else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -181,7 +181,7 @@ extension ObservableArray: CustomStringConvertible {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ObservableArray: CollectionType {
|
extension ObservableArray: Collection {
|
||||||
public subscript(index: Int) -> Element {
|
public subscript(index: Int) -> Element {
|
||||||
get {
|
get {
|
||||||
return elements[index]
|
return elements[index]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
public class PanEvent {
|
open class PanEvent {
|
||||||
|
|
||||||
public let dx: Double
|
open let dx: Double
|
||||||
public let dy: Double
|
open let dy: Double
|
||||||
|
|
||||||
init(dx: Double, dy: Double) {
|
init(dx: Double, dy: Double) {
|
||||||
self.dx = dx
|
self.dx = dx
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
public class PinchEvent {
|
open class PinchEvent {
|
||||||
|
|
||||||
public let scale: Double
|
open let scale: Double
|
||||||
|
|
||||||
init(scale: Double) {
|
init(scale: Double) {
|
||||||
self.scale = scale
|
self.scale = scale
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
public class RotateEvent {
|
open class RotateEvent {
|
||||||
|
|
||||||
public let angle: Double
|
open let angle: Double
|
||||||
|
|
||||||
init(angle: Double) {
|
init(angle: Double) {
|
||||||
self.angle = angle
|
self.angle = angle
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
public class TapEvent {
|
open class TapEvent {
|
||||||
|
|
||||||
public let location: Point
|
open let location: Point
|
||||||
|
|
||||||
init(location: Point) {
|
init(location: Point) {
|
||||||
self.location = location
|
self.location = location
|
||||||
|
@ -1,63 +1,63 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Color: Fill {
|
open class Color: Fill {
|
||||||
|
|
||||||
public let val: Int
|
open let val: Int
|
||||||
|
|
||||||
public static let white: Color = Color( val: 0xFFFFFF )
|
open static let white: Color = Color( val: 0xFFFFFF )
|
||||||
public static let silver: Color = Color( val: 0xC0C0C0 )
|
open static let silver: Color = Color( val: 0xC0C0C0 )
|
||||||
public static let gray: Color = Color( val: 0x808080 )
|
open static let gray: Color = Color( val: 0x808080 )
|
||||||
public static let black: Color = Color( val: 0 )
|
open static let black: Color = Color( val: 0 )
|
||||||
public static let red: Color = Color( val: 0xFF0000 )
|
open static let red: Color = Color( val: 0xFF0000 )
|
||||||
public static let maroon: Color = Color( val: 0x800000 )
|
open static let maroon: Color = Color( val: 0x800000 )
|
||||||
public static let yellow: Color = Color( val: 0xFFFF00 )
|
open static let yellow: Color = Color( val: 0xFFFF00 )
|
||||||
public static let olive: Color = Color( val: 0x808000 )
|
open static let olive: Color = Color( val: 0x808000 )
|
||||||
public static let lime: Color = Color( val: 0x00FF00 )
|
open static let lime: Color = Color( val: 0x00FF00 )
|
||||||
public static let green: Color = Color( val: 0x008000 )
|
open static let green: Color = Color( val: 0x008000 )
|
||||||
public static let aqua: Color = Color( val: 0x00FFFF )
|
open static let aqua: Color = Color( val: 0x00FFFF )
|
||||||
public static let teal: Color = Color( val: 0x008080 )
|
open static let teal: Color = Color( val: 0x008080 )
|
||||||
public static let blue: Color = Color( val: 0x0000FF )
|
open static let blue: Color = Color( val: 0x0000FF )
|
||||||
public static let navy: Color = Color( val: 0x000080 )
|
open static let navy: Color = Color( val: 0x000080 )
|
||||||
public static let fuchsia: Color = Color( val: 0xFF00FF )
|
open static let fuchsia: Color = Color( val: 0xFF00FF )
|
||||||
public static let purple: Color = Color( val: 0x800080 )
|
open static let purple: Color = Color( val: 0x800080 )
|
||||||
|
|
||||||
public init(val: Int = 0) {
|
public init(val: Int = 0) {
|
||||||
self.val = val
|
self.val = val
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED
|
// GENERATED
|
||||||
public func r() -> Int {
|
open func r() -> Int {
|
||||||
return ( ( val >> 16 ) & 0xff )
|
return ( ( val >> 16 ) & 0xff )
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED
|
// GENERATED
|
||||||
public func g() -> Int {
|
open func g() -> Int {
|
||||||
return ( ( val >> 8 ) & 0xff )
|
return ( ( val >> 8 ) & 0xff )
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED
|
// GENERATED
|
||||||
public func b() -> Int {
|
open func b() -> Int {
|
||||||
return ( val & 0xff )
|
return ( val & 0xff )
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED
|
// GENERATED
|
||||||
public func a() -> Int {
|
open func a() -> Int {
|
||||||
return ( 255 - ( ( val >> 24 ) & 0xff ) )
|
return ( 255 - ( ( val >> 24 ) & 0xff ) )
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED
|
// GENERATED
|
||||||
public class func rgbt(r r: Int, g: Int, b: Int, t: Int) -> Color {
|
open class func rgbt(r: Int, g: Int, b: Int, t: Int) -> Color {
|
||||||
return Color( val: ( ( ( ( ( t & 0xff ) << 24 ) | ( ( r & 0xff ) << 16 ) ) | ( ( g & 0xff ) << 8 ) ) | ( b & 0xff ) ) )
|
return Color( val: ( ( ( ( ( t & 0xff ) << 24 ) | ( ( r & 0xff ) << 16 ) ) | ( ( g & 0xff ) << 8 ) ) | ( b & 0xff ) ) )
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED
|
// GENERATED
|
||||||
public class func rgba(r r: Int, g: Int, b: Int, a: Double) -> Color {
|
open class func rgba(r: Int, g: Int, b: Int, a: Double) -> Color {
|
||||||
return rgbt( r: r, g: g, b: b, t: Int( ( ( 1 - a ) * 255 ) ) )
|
return rgbt( r: r, g: g, b: b, t: Int( ( ( 1 - a ) * 255 ) ) )
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED
|
// GENERATED
|
||||||
public class func rgb(r r: Int, g: Int, b: Int) -> Color {
|
open class func rgb(r: Int, g: Int, b: Int) -> Color {
|
||||||
return rgbt( r: r, g: g, b: b, t: 0 )
|
return rgbt( r: r, g: g, b: b, t: 0 )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Drawable {
|
open class Drawable {
|
||||||
|
|
||||||
public let visible: Bool
|
open let visible: Bool
|
||||||
public let tag: [String]
|
open let tag: [String]
|
||||||
|
|
||||||
public init(visible: Bool = true, tag: [String] = []) {
|
public init(visible: Bool = true, tag: [String] = []) {
|
||||||
self.visible = visible
|
self.visible = visible
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class DropShadow: Effect {
|
open class DropShadow: Effect {
|
||||||
|
|
||||||
public let radius: Double
|
open let radius: Double
|
||||||
public let offset: Point
|
open let offset: Point
|
||||||
public let color: Color
|
open let color: Color
|
||||||
public let input: Effect?
|
open let input: Effect?
|
||||||
|
|
||||||
public init(radius: Double = 0, offset: Point = Point.origin, color: Color = Color.black, input: Effect? = nil) {
|
public init(radius: Double = 0, offset: Point = Point.origin, color: Color = Color.black, input: Effect? = nil) {
|
||||||
self.radius = radius
|
self.radius = radius
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Effect {
|
open class Effect {
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Fill {
|
open class Fill {
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Font {
|
open class Font {
|
||||||
|
|
||||||
public let name: String
|
open let name: String
|
||||||
public let size: Int
|
open let size: Int
|
||||||
|
|
||||||
public init(name: String = "Serif", size: Int = 12) {
|
public init(name: String = "Serif", size: Int = 12) {
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class GaussianBlur: Effect {
|
open class GaussianBlur: Effect {
|
||||||
|
|
||||||
public let radius: Double
|
open let radius: Double
|
||||||
public let input: Effect?
|
open let input: Effect?
|
||||||
|
|
||||||
public init(radius: Double = 0, input: Effect? = nil) {
|
public init(radius: Double = 0, input: Effect? = nil) {
|
||||||
self.radius = radius
|
self.radius = radius
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Gradient: Fill {
|
open class Gradient: Fill {
|
||||||
|
|
||||||
public let userSpace: Bool
|
open let userSpace: Bool
|
||||||
public let stops: [Stop]
|
open let stops: [Stop]
|
||||||
|
|
||||||
public init(userSpace: Bool = false, stops: [Stop] = []) {
|
public init(userSpace: Bool = false, stops: [Stop] = []) {
|
||||||
self.userSpace = userSpace
|
self.userSpace = userSpace
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class LinearGradient: Gradient {
|
open class LinearGradient: Gradient {
|
||||||
|
|
||||||
public let x1: Double
|
open let x1: Double
|
||||||
public let y1: Double
|
open let y1: Double
|
||||||
public let x2: Double
|
open let x2: Double
|
||||||
public let y2: Double
|
open let y2: Double
|
||||||
|
|
||||||
public init(x1: Double = 0, y1: Double = 0, x2: Double = 0, y2: Double = 0, userSpace: Bool = false, stops: [Stop] = []) {
|
public init(x1: Double = 0, y1: Double = 0, x2: Double = 0, y2: Double = 0, userSpace: Bool = false, stops: [Stop] = []) {
|
||||||
self.x1 = x1
|
self.x1 = x1
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class RadialGradient: Gradient {
|
open class RadialGradient: Gradient {
|
||||||
|
|
||||||
public let cx: Double
|
open let cx: Double
|
||||||
public let cy: Double
|
open let cy: Double
|
||||||
public let fx: Double
|
open let fx: Double
|
||||||
public let fy: Double
|
open let fy: Double
|
||||||
public let r: Double
|
open let r: Double
|
||||||
|
|
||||||
public init(cx: Double = 0.5, cy: Double = 0.5, fx: Double = 0.5, fy: Double = 0.5, r: Double = 0.5, userSpace: Bool = false, stops: [Stop] = []) {
|
public init(cx: Double = 0.5, cy: Double = 0.5, fx: Double = 0.5, fy: Double = 0.5, r: Double = 0.5, userSpace: Bool = false, stops: [Stop] = []) {
|
||||||
self.cx = cx
|
self.cx = cx
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Stop {
|
open class Stop {
|
||||||
|
|
||||||
public let offset: Double
|
open let offset: Double
|
||||||
public let color: Color
|
open let color: Color
|
||||||
|
|
||||||
public init(offset: Double = 0, color: Color) {
|
public init(offset: Double = 0, color: Color) {
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Stroke {
|
open class Stroke {
|
||||||
|
|
||||||
public let fill: Fill
|
open let fill: Fill
|
||||||
public let width: Double
|
open let width: Double
|
||||||
public let cap: LineCap
|
open let cap: LineCap
|
||||||
public let join: LineJoin
|
open let join: LineJoin
|
||||||
public let dashes: [Double]
|
open let dashes: [Double]
|
||||||
|
|
||||||
public init(fill: Fill = Color.black, width: Double = 1, cap: LineCap = .butt, join: LineJoin = .miter, dashes: [Double] = []) {
|
public init(fill: Fill = Color.black, width: Double = 1, cap: LineCap = .butt, join: LineJoin = .miter, dashes: [Double] = []) {
|
||||||
self.fill = fill
|
self.fill = fill
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Arc: Locus {
|
open class Arc: Locus {
|
||||||
|
|
||||||
public let ellipse: Ellipse
|
open let ellipse: Ellipse
|
||||||
public let shift: Double
|
open let shift: Double
|
||||||
public let extent: Double
|
open let extent: Double
|
||||||
|
|
||||||
public init(ellipse: Ellipse, shift: Double = 0, extent: Double = 0) {
|
public init(ellipse: Ellipse, shift: Double = 0, extent: Double = 0) {
|
||||||
self.ellipse = ellipse
|
self.ellipse = ellipse
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Circle: Locus {
|
open class Circle: Locus {
|
||||||
|
|
||||||
public let cx: Double
|
open let cx: Double
|
||||||
public let cy: Double
|
open let cy: Double
|
||||||
public let r: Double
|
open let r: Double
|
||||||
|
|
||||||
public init(cx: Double = 0, cy: Double = 0, r: Double = 0) {
|
public init(cx: Double = 0, cy: Double = 0, r: Double = 0) {
|
||||||
self.cx = cx
|
self.cx = cx
|
||||||
@ -14,7 +14,7 @@ public class Circle: Locus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func arc(shift shift: Double, extent: Double) -> Arc {
|
open func arc(shift: Double, extent: Double) -> Arc {
|
||||||
return Arc(ellipse: Ellipse(cx: cx, cy: cy, rx: r, ry: r), shift: shift, extent: extent)
|
return Arc(ellipse: Ellipse(cx: cx, cy: cy, rx: r, ry: r), shift: shift, extent: extent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Ellipse: Locus {
|
open class Ellipse: Locus {
|
||||||
|
|
||||||
public let cx: Double
|
open let cx: Double
|
||||||
public let cy: Double
|
open let cy: Double
|
||||||
public let rx: Double
|
open let rx: Double
|
||||||
public let ry: Double
|
open let ry: Double
|
||||||
|
|
||||||
public init(cx: Double = 0, cy: Double = 0, rx: Double = 0, ry: Double = 0) {
|
public init(cx: Double = 0, cy: Double = 0, rx: Double = 0, ry: Double = 0) {
|
||||||
self.cx = cx
|
self.cx = cx
|
||||||
@ -16,7 +16,7 @@ public class Ellipse: Locus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func arc(shift shift: Double, extent: Double) -> Arc {
|
open func arc(shift: Double, extent: Double) -> Arc {
|
||||||
return Arc(ellipse: self, shift: shift, extent: extent)
|
return Arc(ellipse: self, shift: shift, extent: extent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
public class GeomUtils {
|
open class GeomUtils {
|
||||||
|
|
||||||
public class func concat(t1 t1: Transform, t2: Transform) -> Transform {
|
open class func concat(t1: Transform, t2: Transform) -> Transform {
|
||||||
let nm11 = t2.m11 * t1.m11 + t2.m12 * t1.m21
|
let nm11 = t2.m11 * t1.m11 + t2.m12 * t1.m21
|
||||||
let nm21 = t2.m21 * t1.m11 + t2.m22 * t1.m21
|
let nm21 = t2.m21 * t1.m11 + t2.m22 * t1.m21
|
||||||
let ndx = t2.dx * t1.m11 + t2.dy * t1.m21 + t1.dx
|
let ndx = t2.dx * t1.m11 + t2.dy * t1.m21 + t1.dx
|
||||||
@ -10,7 +10,7 @@ public class GeomUtils {
|
|||||||
return Transform(m11: nm11, m12: nm12, m21: nm21, m22: nm22, dx: ndx, dy: ndy)
|
return Transform(m11: nm11, m12: nm12, m21: nm21, m22: nm22, dx: ndx, dy: ndy)
|
||||||
}
|
}
|
||||||
|
|
||||||
public class func centerRotation(node node: Node, place: Transform, angle: Double) -> Transform {
|
open class func centerRotation(node: Node, place: Transform, angle: Double) -> Transform {
|
||||||
guard let bounds = node.bounds() else {
|
guard let bounds = node.bounds() else {
|
||||||
return Transform()
|
return Transform()
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Insets {
|
open class Insets {
|
||||||
|
|
||||||
public let top: Double
|
open let top: Double
|
||||||
public let right: Double
|
open let right: Double
|
||||||
public let bottom: Double
|
open let bottom: Double
|
||||||
public let left: Double
|
open let left: Double
|
||||||
|
|
||||||
public init(top: Double = 0, right: Double = 0, bottom: Double = 0, left: Double = 0) {
|
public init(top: Double = 0, right: Double = 0, bottom: Double = 0, left: Double = 0) {
|
||||||
self.top = top
|
self.top = top
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Line: Locus {
|
open class Line: Locus {
|
||||||
|
|
||||||
public let x1: Double
|
open let x1: Double
|
||||||
public let y1: Double
|
open let y1: Double
|
||||||
public let x2: Double
|
open let x2: Double
|
||||||
public let y2: Double
|
open let y2: Double
|
||||||
|
|
||||||
public init(x1: Double = 0, y1: Double = 0, x2: Double = 0, y2: Double = 0) {
|
public init(x1: Double = 0, y1: Double = 0, x2: Double = 0, y2: Double = 0) {
|
||||||
self.x1 = x1
|
self.x1 = x1
|
||||||
|
@ -1,28 +1,28 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Locus {
|
open class Locus {
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func bounds() -> Rect {
|
open func bounds() -> Rect {
|
||||||
return Rect()
|
return Rect()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func stroke(with with: Stroke) -> Shape {
|
open func stroke(with: Stroke) -> Shape {
|
||||||
return Shape(form: self, stroke: with)
|
return Shape(form: self, stroke: with)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func fill(with with: Fill) -> Shape {
|
open func fill(with: Fill) -> Shape {
|
||||||
return Shape(form: self, fill: with)
|
return Shape(form: self, fill: with)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func stroke(fill fill: Fill = Color.black, width: Double = 1, cap: LineCap = .butt, join: LineJoin = .miter, dashes: [Double] = []) -> Shape {
|
open func stroke(fill: Fill = Color.black, width: Double = 1, cap: LineCap = .butt, join: LineJoin = .miter, dashes: [Double] = []) -> Shape {
|
||||||
return Shape(form: self, stroke: Stroke(fill: fill, width: width, cap: cap, join: join, dashes: dashes))
|
return Shape(form: self, stroke: Stroke(fill: fill, width: width, cap: cap, join: join, dashes: dashes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class MoveTo: PathBuilder {
|
open class MoveTo: PathBuilder {
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public init(x: Double, y: Double) {
|
public init(x: Double, y: Double) {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Path: Locus {
|
open class Path: Locus {
|
||||||
|
|
||||||
public let segments: [PathSegment]
|
open let segments: [PathSegment]
|
||||||
|
|
||||||
public init(segments: [PathSegment] = []) {
|
public init(segments: [PathSegment] = []) {
|
||||||
self.segments = segments
|
self.segments = segments
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class PathBuilder {
|
open class PathBuilder {
|
||||||
|
|
||||||
public let segment: PathSegment
|
open let segment: PathSegment
|
||||||
public let rest: PathBuilder?
|
open let rest: PathBuilder?
|
||||||
|
|
||||||
public init(segment: PathSegment, rest: PathBuilder? = nil) {
|
public init(segment: PathSegment, rest: PathBuilder? = nil) {
|
||||||
self.segment = segment
|
self.segment = segment
|
||||||
@ -12,143 +12,143 @@ public class PathBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func moveTo(x x: Double, y: Double) -> PathBuilder {
|
open func moveTo(x: Double, y: Double) -> PathBuilder {
|
||||||
return M(x, y)
|
return M(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func lineTo(x x: Double, y: Double) -> PathBuilder {
|
open func lineTo(x: Double, y: Double) -> PathBuilder {
|
||||||
return L(x, y)
|
return L(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func cubicTo(x1 x1: Double, y1: Double, x2: Double, y2: Double, x: Double, y: Double) -> PathBuilder {
|
open func cubicTo(x1: Double, y1: Double, x2: Double, y2: Double, x: Double, y: Double) -> PathBuilder {
|
||||||
return C(x1, y1, x2, y2, x, y)
|
return C(x1, y1, x2, y2, x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func quadraticTo(x1 x1: Double, y1: Double, x: Double, y: Double) -> PathBuilder {
|
open func quadraticTo(x1: Double, y1: Double, x: Double, y: Double) -> PathBuilder {
|
||||||
return Q(x1, y1, x, y)
|
return Q(x1, y1, x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func arcTo(rx rx: Double, ry: Double, angle: Double, largeArc: Bool, sweep: Bool, x: Double, y: Double) -> PathBuilder {
|
open func arcTo(rx: Double, ry: Double, angle: Double, largeArc: Bool, sweep: Bool, x: Double, y: Double) -> PathBuilder {
|
||||||
return A(rx, ry, angle, largeArc, sweep, x, y)
|
return A(rx, ry, angle, largeArc, sweep, x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func close() -> PathBuilder {
|
open func close() -> PathBuilder {
|
||||||
return Z()
|
return Z()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func m(x: Double, _ y: Double) -> PathBuilder {
|
open func m(_ x: Double, _ y: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .m, data: [x, y]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .m, data: [x, y]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func M(x: Double, _ y: Double) -> PathBuilder {
|
open func M(_ x: Double, _ y: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .M, data: [x, y]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .M, data: [x, y]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func l(x: Double, _ y: Double) -> PathBuilder {
|
open func l(_ x: Double, _ y: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .l, data: [x, y]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .l, data: [x, y]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func L(x: Double, _ y: Double) -> PathBuilder {
|
open func L(_ x: Double, _ y: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .L, data: [x, y]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .L, data: [x, y]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func h(x: Double) -> PathBuilder {
|
open func h(_ x: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .h, data: [x]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .h, data: [x]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func H(x: Double) -> PathBuilder {
|
open func H(_ x: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .H, data: [x]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .H, data: [x]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func v(y: Double) -> PathBuilder {
|
open func v(_ y: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .v, data: [y]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .v, data: [y]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func V(y: Double) -> PathBuilder {
|
open func V(_ y: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .V, data: [y]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .V, data: [y]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func c(x1: Double, _ y1: Double, _ x2: Double, _ y2: Double, _ x: Double, _ y: Double) -> PathBuilder {
|
open func c(_ x1: Double, _ y1: Double, _ x2: Double, _ y2: Double, _ x: Double, _ y: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .c, data: [x1, y1, x2, y2, x, y]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .c, data: [x1, y1, x2, y2, x, y]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func C(x1: Double, _ y1: Double, _ x2: Double, _ y2: Double, _ x: Double, _ y: Double) -> PathBuilder {
|
open func C(_ x1: Double, _ y1: Double, _ x2: Double, _ y2: Double, _ x: Double, _ y: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .C, data: [x1, y1, x2, y2, x, y]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .C, data: [x1, y1, x2, y2, x, y]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func s(_ x2: Double, _ y2: Double, _ x: Double, _ y: Double) -> PathBuilder {
|
open func s(_ x2: Double, _ y2: Double, _ x: Double, _ y: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .s, data: [x2, y2, x, y]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .s, data: [x2, y2, x, y]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func S(_ x2: Double, _ y2: Double, _ x: Double, _ y: Double) -> PathBuilder {
|
open func S(_ x2: Double, _ y2: Double, _ x: Double, _ y: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .S, data: [x2, y2, x, y]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .S, data: [x2, y2, x, y]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func q(x1: Double, _ y1: Double, _ x: Double, _ y: Double) -> PathBuilder {
|
open func q(_ x1: Double, _ y1: Double, _ x: Double, _ y: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .q, data: [x1, y1, x, y]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .q, data: [x1, y1, x, y]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func Q(x1: Double, _ y1: Double, _ x: Double, _ y: Double) -> PathBuilder {
|
open func Q(_ x1: Double, _ y1: Double, _ x: Double, _ y: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .Q, data: [x1, y1, x, y]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .Q, data: [x1, y1, x, y]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func t(x: Double, _ y: Double) -> PathBuilder {
|
open func t(_ x: Double, _ y: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .t, data: [x, y]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .t, data: [x, y]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func T(x: Double, _ y: Double) -> PathBuilder {
|
open func T(_ x: Double, _ y: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .T, data: [x, y]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .T, data: [x, y]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func a(rx: Double, _ ry: Double, _ angle: Double, _ largeArc: Bool, _ sweep: Bool, _ x: Double, _ y: Double) -> PathBuilder {
|
open func a(_ rx: Double, _ ry: Double, _ angle: Double, _ largeArc: Bool, _ sweep: Bool, _ x: Double, _ y: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .a, data: [rx, ry, angle, boolsToNum(largeArc, sweep: sweep), x, y]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .a, data: [rx, ry, angle, boolsToNum(largeArc, sweep: sweep), x, y]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func A(rx: Double, _ ry: Double, _ angle: Double, _ largeArc: Bool, _ sweep: Bool, _ x: Double, _ y: Double) -> PathBuilder {
|
open func A(_ rx: Double, _ ry: Double, _ angle: Double, _ largeArc: Bool, _ sweep: Bool, _ x: Double, _ y: Double) -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .A, data: [rx, ry, angle, boolsToNum(largeArc, sweep: sweep), x, y]), rest: self)
|
return PathBuilder(segment: PathSegment(type: .A, data: [rx, ry, angle, boolsToNum(largeArc, sweep: sweep), x, y]), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func Z() -> PathBuilder {
|
open func Z() -> PathBuilder {
|
||||||
return PathBuilder(segment: PathSegment(type: .Z), rest: self)
|
return PathBuilder(segment: PathSegment(type: .z), rest: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func build() -> Path {
|
open func build() -> Path {
|
||||||
var segments : [PathSegment] = []
|
var segments : [PathSegment] = []
|
||||||
var builder : PathBuilder? = self
|
var builder : PathBuilder? = self
|
||||||
while(builder != nil) {
|
while(builder != nil) {
|
||||||
segments.append(builder!.segment)
|
segments.append(builder!.segment)
|
||||||
builder = builder!.rest
|
builder = builder!.rest
|
||||||
}
|
}
|
||||||
return Path(segments: segments.reverse())
|
return Path(segments: segments.reversed())
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
private func boolsToNum(largeArc: Bool, sweep: Bool) -> Double {
|
fileprivate func boolsToNum(_ largeArc: Bool, sweep: Bool) -> Double {
|
||||||
return (largeArc ? 1 : 0) + (sweep ? 1 : 0) * 2;
|
return (largeArc ? 1 : 0) + (sweep ? 1 : 0) * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class PathSegment {
|
open class PathSegment {
|
||||||
|
|
||||||
public let type: PathSegmentType
|
open let type: PathSegmentType
|
||||||
public let data: [Double]
|
open let data: [Double]
|
||||||
|
|
||||||
public init(type: PathSegmentType = .M, data: [Double] = []) {
|
public init(type: PathSegmentType = .M, data: [Double] = []) {
|
||||||
self.type = type
|
self.type = type
|
||||||
@ -12,7 +12,7 @@ public class PathSegment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func isAbsolute() -> Bool {
|
open func isAbsolute() -> Bool {
|
||||||
switch type {
|
switch type {
|
||||||
case .M, .L, .H, .V, .C, .S, .Q, .T, .A:
|
case .M, .L, .H, .V, .C, .S, .Q, .T, .A:
|
||||||
return true
|
return true
|
||||||
|
@ -4,7 +4,7 @@ public enum PathSegmentType {
|
|||||||
case C
|
case C
|
||||||
case Q
|
case Q
|
||||||
case A
|
case A
|
||||||
case Z
|
case z
|
||||||
case H
|
case H
|
||||||
case V
|
case V
|
||||||
case S
|
case S
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Point: Locus {
|
open class Point: Locus {
|
||||||
|
|
||||||
public let x: Double
|
open let x: Double
|
||||||
public let y: Double
|
open let y: Double
|
||||||
|
|
||||||
public static let origin: Point = Point( x: 0, y: 0 )
|
open static let origin: Point = Point( x: 0, y: 0 )
|
||||||
|
|
||||||
public init(x: Double = 0, y: Double = 0) {
|
public init(x: Double = 0, y: Double = 0) {
|
||||||
self.x = x
|
self.x = x
|
||||||
@ -14,7 +14,7 @@ public class Point: Locus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func add(point: Point) -> Point {
|
open func add(_ point: Point) -> Point {
|
||||||
return Point(
|
return Point(
|
||||||
x: self.x + point.x,
|
x: self.x + point.x,
|
||||||
y: self.y + point.y)
|
y: self.y + point.y)
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Polygon: Locus {
|
open class Polygon: Locus {
|
||||||
|
|
||||||
public let points: [Double]
|
open let points: [Double]
|
||||||
|
|
||||||
public init(points: [Double] = []) {
|
public init(points: [Double] = []) {
|
||||||
self.points = points
|
self.points = points
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Polyline: Locus {
|
open class Polyline: Locus {
|
||||||
|
|
||||||
public let points: [Double]
|
open let points: [Double]
|
||||||
|
|
||||||
public init(points: [Double] = []) {
|
public init(points: [Double] = []) {
|
||||||
self.points = points
|
self.points = points
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Rect: Locus {
|
open class Rect: Locus {
|
||||||
|
|
||||||
public let x: Double
|
open let x: Double
|
||||||
public let y: Double
|
open let y: Double
|
||||||
public let w: Double
|
open let w: Double
|
||||||
public let h: Double
|
open let h: Double
|
||||||
|
|
||||||
public init(x: Double = 0, y: Double = 0, w: Double = 0, h: Double = 0) {
|
public init(x: Double = 0, y: Double = 0, w: Double = 0, h: Double = 0) {
|
||||||
self.x = x
|
self.x = x
|
||||||
@ -16,12 +16,12 @@ public class Rect: Locus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func round(rx rx: Double, ry: Double) -> RoundRect {
|
open func round(rx: Double, ry: Double) -> RoundRect {
|
||||||
return RoundRect(rect: self, rx: rx, ry: ry)
|
return RoundRect(rect: self, rx: rx, ry: ry)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func contains(locus locus: Locus) -> Bool {
|
open func contains(locus: Locus) -> Bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ public class Rect: Locus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func move(offset offset: Point) -> Rect {
|
open func move(offset: Point) -> Rect {
|
||||||
return Rect(
|
return Rect(
|
||||||
x: self.x + offset.x,
|
x: self.x + offset.x,
|
||||||
y: self.y + offset.y,
|
y: self.y + offset.y,
|
||||||
@ -40,7 +40,7 @@ public class Rect: Locus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func union(rect rect: Rect) -> Rect {
|
open func union(rect: Rect) -> Rect {
|
||||||
return Rect(
|
return Rect(
|
||||||
x: min(self.x, rect.x),
|
x: min(self.x, rect.x),
|
||||||
y: min(self.y, rect.y),
|
y: min(self.y, rect.y),
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class RoundRect: Locus {
|
open class RoundRect: Locus {
|
||||||
|
|
||||||
public let rect: Rect
|
open let rect: Rect
|
||||||
public let rx: Double
|
open let rx: Double
|
||||||
public let ry: Double
|
open let ry: Double
|
||||||
|
|
||||||
public init(rect: Rect, rx: Double = 0, ry: Double = 0) {
|
public init(rect: Rect, rx: Double = 0, ry: Double = 0) {
|
||||||
self.rect = rect
|
self.rect = rect
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Size {
|
open class Size {
|
||||||
|
|
||||||
public let w: Double
|
open let w: Double
|
||||||
public let h: Double
|
open let h: Double
|
||||||
|
|
||||||
public init(w: Double = 0, h: Double = 0) {
|
public init(w: Double = 0, h: Double = 0) {
|
||||||
self.w = w
|
self.w = w
|
||||||
|
@ -22,57 +22,57 @@ public final class Transform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func move(dx dx: Double, dy: Double) -> Transform {
|
public func move(dx: Double, dy: Double) -> Transform {
|
||||||
return Transform(m11: m11, m12: m12, m21: m21, m22: m22,
|
return Transform(m11: m11, m12: m12, m21: m21, m22: m22,
|
||||||
dx: dx * m11 + dy * m21 + self.dx, dy: dx * m12 + dy * m22 + self.dy)
|
dx: dx * m11 + dy * m21 + self.dx, dy: dx * m12 + dy * m22 + self.dy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func scale(sx sx: Double, sy: Double) -> Transform {
|
public func scale(sx: Double, sy: Double) -> Transform {
|
||||||
return Transform(m11: m11 * sx, m12: m12 * sx, m21: m21 * sy, m22: m22 * sy, dx: dx, dy: dy)
|
return Transform(m11: m11 * sx, m12: m12 * sx, m21: m21 * sy, m22: m22 * sy, dx: dx, dy: dy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func shear(shx shx: Double, shy: Double) -> Transform {
|
public func shear(shx: Double, shy: Double) -> Transform {
|
||||||
return Transform(m11: m11 + m21 * shy, m12: m12 + m22 * shy,
|
return Transform(m11: m11 + m21 * shy, m12: m12 + m22 * shy,
|
||||||
m21: m11 * shx + m21, m22: m12 * shx + m22, dx: dx, dy: dy)
|
m21: m11 * shx + m21, m22: m12 * shx + m22, dx: dx, dy: dy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func rotate(angle angle: Double) -> Transform {
|
public func rotate(angle: Double) -> Transform {
|
||||||
let asin = sin(angle); let acos = cos(angle)
|
let asin = sin(angle); let acos = cos(angle)
|
||||||
return Transform(m11: acos * m11 + asin * m21, m12: acos * m12 + asin * m22,
|
return Transform(m11: acos * m11 + asin * m21, m12: acos * m12 + asin * m22,
|
||||||
m21: -asin * m11 + acos * m21, m22: -asin * m12 + acos * m22, dx: dx, dy: dy)
|
m21: -asin * m11 + acos * m21, m22: -asin * m12 + acos * m22, dx: dx, dy: dy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public func rotate(angle angle: Double, x: Double, y: Double) -> Transform {
|
public func rotate(angle: Double, x: Double, y: Double) -> Transform {
|
||||||
return move(dx: x, dy: y).rotate(angle: angle).move(dx: -x, dy: -y)
|
return move(dx: x, dy: y).rotate(angle: angle).move(dx: -x, dy: -y)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED
|
// GENERATED
|
||||||
public class func move(dx dx: Double, dy: Double) -> Transform {
|
public class func move(dx: Double, dy: Double) -> Transform {
|
||||||
return Transform(dx: dx, dy: dy)
|
return Transform(dx: dx, dy: dy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED
|
// GENERATED
|
||||||
public class func scale(sx sx: Double, sy: Double) -> Transform {
|
public class func scale(sx: Double, sy: Double) -> Transform {
|
||||||
return Transform(m11: sx, m22: sy)
|
return Transform(m11: sx, m22: sy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED
|
// GENERATED
|
||||||
public class func shear(shx shx: Double, shy: Double) -> Transform {
|
public class func shear(shx: Double, shy: Double) -> Transform {
|
||||||
return Transform(m12: shy, m21: shx)
|
return Transform(m12: shy, m21: shx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public class func rotate(angle angle: Double) -> Transform {
|
public class func rotate(angle: Double) -> Transform {
|
||||||
let asin = sin(angle); let acos = cos(angle)
|
let asin = sin(angle); let acos = cos(angle)
|
||||||
return Transform(m11: acos, m12: asin, m21: -asin, m22: acos)
|
return Transform(m11: acos, m12: asin, m21: -asin, m22: acos)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GENERATED NOT
|
// GENERATED NOT
|
||||||
public class func rotate(angle angle: Double, x: Double, y: Double) -> Transform {
|
public class func rotate(angle: Double, x: Double, y: Double) -> Transform {
|
||||||
return Transform.move(dx: x, dy: y).rotate(angle: angle).move(dx: -x, dy: -y)
|
return Transform.move(dx: x, dy: y).rotate(angle: angle).move(dx: -x, dy: -y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Group: Node {
|
open class Group: Node {
|
||||||
|
|
||||||
public var contents: ObservableArray<Node>
|
open var contents: ObservableArray<Node>
|
||||||
|
|
||||||
public init(contents: [Node] = [], place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) {
|
public init(contents: [Node] = [], place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) {
|
||||||
self.contents = ObservableArray<Node>(array: contents)
|
self.contents = ObservableArray<Node>(array: contents)
|
||||||
@ -22,12 +22,12 @@ public class Group: Node {
|
|||||||
override internal func bounds() -> Rect? {
|
override internal func bounds() -> Rect? {
|
||||||
|
|
||||||
guard let firstPos = contents.first?.place else {
|
guard let firstPos = contents.first?.place else {
|
||||||
return .None
|
return .none
|
||||||
}
|
}
|
||||||
|
|
||||||
guard var union = contents.first?.bounds()?.applyTransform(firstPos) else {
|
guard var union = contents.first?.bounds()?.applyTransform(firstPos) else {
|
||||||
|
|
||||||
return .None
|
return .none
|
||||||
}
|
}
|
||||||
|
|
||||||
contents.forEach { node in
|
contents.forEach { node in
|
||||||
|
@ -1,40 +1,40 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Image: Node {
|
open class Image: Node {
|
||||||
|
|
||||||
public let srcVar: Variable<String>
|
open let srcVar: Variable<String>
|
||||||
public var src: String {
|
open var src: String {
|
||||||
get { return srcVar.value }
|
get { return srcVar.value }
|
||||||
set(val) { srcVar.value = val }
|
set(val) { srcVar.value = val }
|
||||||
}
|
}
|
||||||
|
|
||||||
public let xAlignVar: Variable<Align>
|
open let xAlignVar: Variable<Align>
|
||||||
public var xAlign: Align {
|
open var xAlign: Align {
|
||||||
get { return xAlignVar.value }
|
get { return xAlignVar.value }
|
||||||
set(val) { xAlignVar.value = val }
|
set(val) { xAlignVar.value = val }
|
||||||
}
|
}
|
||||||
|
|
||||||
public let yAlignVar: Variable<Align>
|
open let yAlignVar: Variable<Align>
|
||||||
public var yAlign: Align {
|
open var yAlign: Align {
|
||||||
get { return yAlignVar.value }
|
get { return yAlignVar.value }
|
||||||
set(val) { yAlignVar.value = val }
|
set(val) { yAlignVar.value = val }
|
||||||
}
|
}
|
||||||
|
|
||||||
public let aspectRatioVar: Variable<AspectRatio>
|
open let aspectRatioVar: Variable<AspectRatio>
|
||||||
public var aspectRatio: AspectRatio {
|
open var aspectRatio: AspectRatio {
|
||||||
get { return aspectRatioVar.value }
|
get { return aspectRatioVar.value }
|
||||||
set(val) { aspectRatioVar.value = val }
|
set(val) { aspectRatioVar.value = val }
|
||||||
}
|
}
|
||||||
|
|
||||||
public let wVar: Variable<Int>
|
open let wVar: Variable<Int>
|
||||||
public var w: Int {
|
open var w: Int {
|
||||||
get { return wVar.value }
|
get { return wVar.value }
|
||||||
set(val) { wVar.value = val }
|
set(val) { wVar.value = val }
|
||||||
}
|
}
|
||||||
|
|
||||||
public let hVar: Variable<Int>
|
open let hVar: Variable<Int>
|
||||||
public var h: Int {
|
open var h: Int {
|
||||||
get { return hVar.value }
|
get { return hVar.value }
|
||||||
set(val) { hVar.value = val }
|
set(val) { hVar.value = val }
|
||||||
}
|
}
|
||||||
|
@ -1,34 +1,34 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Node: Drawable {
|
open class Node: Drawable {
|
||||||
|
|
||||||
public let placeVar: AnimatableVariable<Transform>
|
open let placeVar: AnimatableVariable<Transform>
|
||||||
public var place: Transform {
|
open var place: Transform {
|
||||||
get { return placeVar.value }
|
get { return placeVar.value }
|
||||||
set(val) { placeVar.value = val }
|
set(val) { placeVar.value = val }
|
||||||
}
|
}
|
||||||
|
|
||||||
public let opaqueVar: Variable<Bool>
|
open let opaqueVar: Variable<Bool>
|
||||||
public var opaque: Bool {
|
open var opaque: Bool {
|
||||||
get { return opaqueVar.value }
|
get { return opaqueVar.value }
|
||||||
set(val) { opaqueVar.value = val }
|
set(val) { opaqueVar.value = val }
|
||||||
}
|
}
|
||||||
|
|
||||||
public let opacityVar: AnimatableVariable<Double>
|
open let opacityVar: AnimatableVariable<Double>
|
||||||
public var opacity: Double {
|
open var opacity: Double {
|
||||||
get { return opacityVar.value }
|
get { return opacityVar.value }
|
||||||
set(val) { opacityVar.value = val }
|
set(val) { opacityVar.value = val }
|
||||||
}
|
}
|
||||||
|
|
||||||
public let clipVar: Variable<Locus?>
|
open let clipVar: Variable<Locus?>
|
||||||
public var clip: Locus? {
|
open var clip: Locus? {
|
||||||
get { return clipVar.value }
|
get { return clipVar.value }
|
||||||
set(val) { clipVar.value = val }
|
set(val) { clipVar.value = val }
|
||||||
}
|
}
|
||||||
|
|
||||||
public let effectVar: Variable<Effect?>
|
open let effectVar: Variable<Effect?>
|
||||||
public var effect: Effect? {
|
open var effect: Effect? {
|
||||||
get { return effectVar.value }
|
get { return effectVar.value }
|
||||||
set(val) { effectVar.value = val }
|
set(val) { effectVar.value = val }
|
||||||
}
|
}
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Shape: Node {
|
open class Shape: Node {
|
||||||
|
|
||||||
public let formVar: Variable<Locus>
|
open let formVar: Variable<Locus>
|
||||||
public var form: Locus {
|
open var form: Locus {
|
||||||
get { return formVar.value }
|
get { return formVar.value }
|
||||||
set(val) { formVar.value = val }
|
set(val) { formVar.value = val }
|
||||||
}
|
}
|
||||||
|
|
||||||
public let fillVar: Variable<Fill?>
|
open let fillVar: Variable<Fill?>
|
||||||
public var fill: Fill? {
|
open var fill: Fill? {
|
||||||
get { return fillVar.value }
|
get { return fillVar.value }
|
||||||
set(val) { fillVar.value = val }
|
set(val) { fillVar.value = val }
|
||||||
}
|
}
|
||||||
|
|
||||||
public let strokeVar: Variable<Stroke?>
|
open let strokeVar: Variable<Stroke?>
|
||||||
public var stroke: Stroke? {
|
open var stroke: Stroke? {
|
||||||
get { return strokeVar.value }
|
get { return strokeVar.value }
|
||||||
set(val) { strokeVar.value = val }
|
set(val) { strokeVar.value = val }
|
||||||
}
|
}
|
||||||
|
|
||||||
public let onTap = PublishSubject<TapEvent>()
|
open let onTap = PublishSubject<TapEvent>()
|
||||||
public let onPan = PublishSubject<PanEvent>()
|
open let onPan = PublishSubject<PanEvent>()
|
||||||
public let onRotate = PublishSubject<RotateEvent>()
|
open let onRotate = PublishSubject<RotateEvent>()
|
||||||
public let onPinch = PublishSubject<PinchEvent>()
|
open let onPinch = PublishSubject<PinchEvent>()
|
||||||
|
|
||||||
public init(form: Locus, fill: Fill? = nil, stroke: Stroke? = nil, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) {
|
public init(form: Locus, fill: Fill? = nil, stroke: Stroke? = nil, place: Transform = Transform.identity, opaque: Bool = true, opacity: Double = 1, clip: Locus? = nil, effect: Effect? = nil, visible: Bool = true, tag: [String] = []) {
|
||||||
self.formVar = Variable<Locus>(form)
|
self.formVar = Variable<Locus>(form)
|
||||||
|
@ -1,34 +1,34 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import RxSwift
|
import RxSwift
|
||||||
|
|
||||||
public class Text: Node {
|
open class Text: Node {
|
||||||
|
|
||||||
public let textVar: Variable<String>
|
open let textVar: Variable<String>
|
||||||
public var text: String {
|
open var text: String {
|
||||||
get { return textVar.value }
|
get { return textVar.value }
|
||||||
set(val) { textVar.value = val }
|
set(val) { textVar.value = val }
|
||||||
}
|
}
|
||||||
|
|
||||||
public let fontVar: Variable<Font?>
|
open let fontVar: Variable<Font?>
|
||||||
public var font: Font? {
|
open var font: Font? {
|
||||||
get { return fontVar.value }
|
get { return fontVar.value }
|
||||||
set(val) { fontVar.value = val }
|
set(val) { fontVar.value = val }
|
||||||
}
|
}
|
||||||
|
|
||||||
public let fillVar: Variable<Fill>
|
open let fillVar: Variable<Fill>
|
||||||
public var fill: Fill {
|
open var fill: Fill {
|
||||||
get { return fillVar.value }
|
get { return fillVar.value }
|
||||||
set(val) { fillVar.value = val }
|
set(val) { fillVar.value = val }
|
||||||
}
|
}
|
||||||
|
|
||||||
public let alignVar: Variable<Align>
|
open let alignVar: Variable<Align>
|
||||||
public var align: Align {
|
open var align: Align {
|
||||||
get { return alignVar.value }
|
get { return alignVar.value }
|
||||||
set(val) { alignVar.value = val }
|
set(val) { alignVar.value = val }
|
||||||
}
|
}
|
||||||
|
|
||||||
public let baselineVar: Variable<Baseline>
|
open let baselineVar: Variable<Baseline>
|
||||||
public var baseline: Baseline {
|
open var baseline: Baseline {
|
||||||
get { return baselineVar.value }
|
get { return baselineVar.value }
|
||||||
set(val) { baselineVar.value = val }
|
set(val) { baselineVar.value = val }
|
||||||
}
|
}
|
||||||
@ -57,14 +57,14 @@ public class Text: Node {
|
|||||||
if let customFont = UIFont(name: f.name, size: CGFloat(f.size)) {
|
if let customFont = UIFont(name: f.name, size: CGFloat(f.size)) {
|
||||||
font = customFont
|
font = customFont
|
||||||
} else {
|
} else {
|
||||||
font = UIFont.systemFontOfSize(CGFloat(f.size))
|
font = UIFont.systemFont(ofSize: CGFloat(f.size))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
font = UIFont.systemFontOfSize(UIFont.systemFontSize())
|
font = UIFont.systemFont(ofSize: UIFont.systemFontSize)
|
||||||
}
|
}
|
||||||
var stringAttributes: [String: AnyObject] = [:]
|
var stringAttributes: [String: AnyObject] = [:]
|
||||||
stringAttributes[NSFontAttributeName] = font
|
stringAttributes[NSFontAttributeName] = font
|
||||||
let size = (text as NSString).sizeWithAttributes(stringAttributes)
|
let size = (text as NSString).size(attributes: stringAttributes)
|
||||||
if (self.baseline == Baseline.bottom) {
|
if (self.baseline == Baseline.bottom) {
|
||||||
return Rect(x: 0, y: -Double(size.height), w: Double(size.width), h: Double(size.height))
|
return Rect(x: 0, y: -Double(size.height), w: Double(size.width), h: Double(size.height))
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ class GroupRenderer: NodeRenderer {
|
|||||||
|
|
||||||
let group: Group
|
let group: Group
|
||||||
|
|
||||||
private var renderers: [NodeRenderer] = []
|
fileprivate var renderers: [NodeRenderer] = []
|
||||||
|
|
||||||
init(group: Group, ctx: RenderContext, animationCache: AnimationCache) {
|
init(group: Group, ctx: RenderContext, animationCache: AnimationCache) {
|
||||||
self.group = group
|
self.group = group
|
||||||
@ -24,27 +24,27 @@ class GroupRenderer: NodeRenderer {
|
|||||||
return group
|
return group
|
||||||
}
|
}
|
||||||
|
|
||||||
override func doRender(force: Bool, opacity: Double) {
|
override func doRender(_ force: Bool, opacity: Double) {
|
||||||
renderers.forEach { renderer in
|
renderers.forEach { renderer in
|
||||||
CGContextSaveGState(ctx.cgContext!)
|
ctx.cgContext!.saveGState()
|
||||||
CGContextConcatCTM(ctx.cgContext!, RenderUtils.mapTransform(renderer.node().place))
|
ctx.cgContext!.concatenate(RenderUtils.mapTransform(renderer.node().place))
|
||||||
setClip(renderer.node())
|
setClip(renderer.node())
|
||||||
renderer.render(force, opacity: renderer.node().opacity * opacity)
|
renderer.render(force, opacity: renderer.node().opacity * opacity)
|
||||||
CGContextRestoreGState(ctx.cgContext!)
|
ctx.cgContext!.restoreGState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func detectTouches(location: CGPoint) -> [Shape] {
|
override func detectTouches(_ location: CGPoint) -> [Shape] {
|
||||||
var touchedShapes = [Shape]()
|
var touchedShapes = [Shape]()
|
||||||
renderers.forEach { renderer in
|
renderers.forEach { renderer in
|
||||||
if let inverted = renderer.node().place.invert() {
|
if let inverted = renderer.node().place.invert() {
|
||||||
CGContextSaveGState(ctx.cgContext!)
|
ctx.cgContext!.saveGState()
|
||||||
CGContextConcatCTM(ctx.cgContext!, RenderUtils.mapTransform(renderer.node().place))
|
ctx.cgContext!.concatenate(RenderUtils.mapTransform(renderer.node().place))
|
||||||
let translatedLocation = CGPointApplyAffineTransform(location, RenderUtils.mapTransform(inverted))
|
let translatedLocation = location.applying(RenderUtils.mapTransform(inverted))
|
||||||
setClip(renderer.node())
|
setClip(renderer.node())
|
||||||
let offsetLocation = CGPoint(x: translatedLocation.x, y: translatedLocation.y)
|
let offsetLocation = CGPoint(x: translatedLocation.x, y: translatedLocation.y)
|
||||||
touchedShapes.appendContentsOf(renderer.detectTouches(offsetLocation))
|
touchedShapes.append(contentsOf: renderer.detectTouches(offsetLocation))
|
||||||
CGContextRestoreGState(ctx.cgContext!)
|
ctx.cgContext!.restoreGState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,20 +59,20 @@ class GroupRenderer: NodeRenderer {
|
|||||||
|
|
||||||
// TODO: extract to NodeRenderer
|
// TODO: extract to NodeRenderer
|
||||||
// TODO: path support
|
// TODO: path support
|
||||||
func setClip(node: Node) {
|
func setClip(_ node: Node) {
|
||||||
if let rect = node.clip as? Rect {
|
if let rect = node.clip as? Rect {
|
||||||
CGContextClipToRect(ctx.cgContext!, CGRect(x: rect.x, y: rect.y, width: rect.w, height: rect.h))
|
ctx.cgContext!.clip(to: CGRect(x: rect.x, y: rect.y, width: rect.w, height: rect.h))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateRenderers() {
|
fileprivate func updateRenderers() {
|
||||||
var nodeToRenderer: [Node: NodeRenderer] = [:]
|
var nodeToRenderer: [Node: NodeRenderer] = [:]
|
||||||
for renderer in renderers {
|
for renderer in renderers {
|
||||||
nodeToRenderer[renderer.node()] = renderer
|
nodeToRenderer[renderer.node()] = renderer
|
||||||
}
|
}
|
||||||
self.renderers = []
|
self.renderers = []
|
||||||
for node in group.contents {
|
for node in group.contents {
|
||||||
if let renderer = nodeToRenderer.removeValueForKey(node) {
|
if let renderer = nodeToRenderer.removeValue(forKey: node) {
|
||||||
self.renderers.append(renderer)
|
self.renderers.append(renderer)
|
||||||
} else {
|
} else {
|
||||||
self.renderers.append(RenderUtils.createNodeRenderer(node, context: ctx, animationCache: animationCache))
|
self.renderers.append(RenderUtils.createNodeRenderer(node, context: ctx, animationCache: animationCache))
|
||||||
|
@ -25,14 +25,14 @@ class ImageRenderer: NodeRenderer {
|
|||||||
observe(image.hVar)
|
observe(image.hVar)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func doRender(force: Bool, opacity: Double) {
|
override func doRender(_ force: Bool, opacity: Double) {
|
||||||
if let uiimage = UIImage(named: image.src) {
|
if let uiimage = UIImage(named: image.src) {
|
||||||
let imageSize = uiimage.size
|
let imageSize = uiimage.size
|
||||||
var w = CGFloat(image.w)
|
var w = CGFloat(image.w)
|
||||||
var h = CGFloat(image.h)
|
var h = CGFloat(image.h)
|
||||||
var rect: CGRect
|
var rect: CGRect
|
||||||
if ((w == 0 || w == imageSize.width) && (h == 0 || h == imageSize.height)) {
|
if ((w == 0 || w == imageSize.width) && (h == 0 || h == imageSize.height)) {
|
||||||
rect = CGRectMake(0, 0, imageSize.width, imageSize.height)
|
rect = CGRect(x: 0, y: 0, width: imageSize.width, height: imageSize.height)
|
||||||
} else {
|
} else {
|
||||||
if (w == 0) {
|
if (w == 0) {
|
||||||
w = imageSize.width * h / imageSize.height
|
w = imageSize.width * h / imageSize.height
|
||||||
@ -44,25 +44,25 @@ class ImageRenderer: NodeRenderer {
|
|||||||
rect = calculateMeetAspectRatio(image, size: imageSize)
|
rect = calculateMeetAspectRatio(image, size: imageSize)
|
||||||
case AspectRatio.slice:
|
case AspectRatio.slice:
|
||||||
rect = calculateSliceAspectRatio(image, size: imageSize)
|
rect = calculateSliceAspectRatio(image, size: imageSize)
|
||||||
CGContextClipToRect(ctx.cgContext!, CGRectMake(0, 0, w, h))
|
ctx.cgContext!.clip(to: CGRect(x: 0, y: 0, width: w, height: h))
|
||||||
default:
|
default:
|
||||||
rect = CGRectMake(0, 0, w, h)
|
rect = CGRect(x: 0, y: 0, width: w, height: h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CGContextScaleCTM(ctx.cgContext!, 1.0, -1.0)
|
ctx.cgContext!.scaleBy(x: 1.0, y: -1.0)
|
||||||
CGContextTranslateCTM(ctx.cgContext!, 0.0, -1.0 * rect.height)
|
ctx.cgContext!.translateBy(x: 0.0, y: -1.0 * rect.height)
|
||||||
|
|
||||||
CGContextSetAlpha(ctx.cgContext!, CGFloat(opacity))
|
ctx.cgContext!.setAlpha(CGFloat(opacity))
|
||||||
CGContextDrawImage(ctx.cgContext!, rect, uiimage.CGImage!)
|
ctx.cgContext!.draw(uiimage.cgImage!, in: rect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func detectTouches(location: CGPoint) -> [Shape] {
|
override func detectTouches(_ location: CGPoint) -> [Shape] {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
private func calculateMeetAspectRatio(image: Image, size: CGSize) -> CGRect {
|
fileprivate func calculateMeetAspectRatio(_ image: Image, size: CGSize) -> CGRect {
|
||||||
let w = CGFloat(image.w)
|
let w = CGFloat(image.w)
|
||||||
let h = CGFloat(image.h)
|
let h = CGFloat(image.h)
|
||||||
// destination and source aspect ratios
|
// destination and source aspect ratios
|
||||||
@ -97,10 +97,10 @@ class ImageRenderer: NodeRenderer {
|
|||||||
case Align.max:
|
case Align.max:
|
||||||
destY = h - resultH
|
destY = h - resultH
|
||||||
}
|
}
|
||||||
return CGRectMake(destX, destY, resultW, resultH)
|
return CGRect(x: destX, y: destY, width: resultW, height: resultH)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func calculateSliceAspectRatio(image: Image, size: CGSize) -> CGRect {
|
fileprivate func calculateSliceAspectRatio(_ image: Image, size: CGSize) -> CGRect {
|
||||||
let w = CGFloat(image.w)
|
let w = CGFloat(image.w)
|
||||||
let h = CGFloat(image.h)
|
let h = CGFloat(image.h)
|
||||||
var srcX = CGFloat(0)
|
var srcX = CGFloat(0)
|
||||||
@ -135,6 +135,6 @@ class ImageRenderer: NodeRenderer {
|
|||||||
srcX = -(totalW - w)
|
srcX = -(totalW - w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return CGRectMake(srcX, srcY, totalW, totalH)
|
return CGRect(x: srcX, y: srcY, width: totalW, height: totalH)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,9 @@ class NodeRenderer {
|
|||||||
|
|
||||||
let ctx: RenderContext
|
let ctx: RenderContext
|
||||||
|
|
||||||
private let onNodeChange: (Any) -> Void
|
fileprivate let onNodeChange: (Any) -> Void
|
||||||
private let disposables = GroupDisposable()
|
fileprivate let disposables = GroupDisposable()
|
||||||
private var active = false
|
fileprivate var active = false
|
||||||
let animationCache: AnimationCache
|
let animationCache: AnimationCache
|
||||||
|
|
||||||
init(node: Node, ctx: RenderContext, animationCache: AnimationCache) {
|
init(node: Node, ctx: RenderContext, animationCache: AnimationCache) {
|
||||||
@ -26,27 +26,27 @@ class NodeRenderer {
|
|||||||
observe(node().effectVar)
|
observe(node().effectVar)
|
||||||
}
|
}
|
||||||
|
|
||||||
func observe<E>(variable: Variable<E>) {
|
func observe<E>(_ variable: Variable<E>) {
|
||||||
observe(variable.asObservable())
|
observe(variable.asObservable())
|
||||||
}
|
}
|
||||||
|
|
||||||
func observe<E>(observable: Observable<E>) {
|
func observe<E>(_ observable: Observable<E>) {
|
||||||
addDisposable(observable.subscribeNext(onNodeChange))
|
addDisposable(observable.subscribeNext(onNodeChange))
|
||||||
}
|
}
|
||||||
|
|
||||||
func addDisposable(disposable: Disposable) {
|
func addDisposable(_ disposable: Disposable) {
|
||||||
disposable.addTo(disposables)
|
disposable.addTo(disposables)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func dispose() {
|
open func dispose() {
|
||||||
removeObservers()
|
removeObservers()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func node() -> Node {
|
open func node() -> Node {
|
||||||
fatalError("Unsupported")
|
fatalError("Unsupported")
|
||||||
}
|
}
|
||||||
|
|
||||||
final public func render(force: Bool, opacity: Double) {
|
final public func render(_ force: Bool, opacity: Double) {
|
||||||
if animationCache.isAnimating(node()) {
|
if animationCache.isAnimating(node()) {
|
||||||
self.removeObservers()
|
self.removeObservers()
|
||||||
if (!force) {
|
if (!force) {
|
||||||
@ -58,26 +58,26 @@ class NodeRenderer {
|
|||||||
doRender(force, opacity: opacity)
|
doRender(force, opacity: opacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
func doRender(force: Bool, opacity: Double) {
|
func doRender(_ force: Bool, opacity: Double) {
|
||||||
fatalError("Unsupported")
|
fatalError("Unsupported")
|
||||||
}
|
}
|
||||||
|
|
||||||
public func detectTouches(location: CGPoint) -> [Shape] {
|
open func detectTouches(_ location: CGPoint) -> [Shape] {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
private func addObservers() {
|
fileprivate func addObservers() {
|
||||||
if (!active) {
|
if (!active) {
|
||||||
active = true
|
active = true
|
||||||
doAddObservers()
|
doAddObservers()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func removeObservers() {
|
fileprivate func removeObservers() {
|
||||||
if (active) {
|
if (active) {
|
||||||
active = false
|
active = false
|
||||||
disposables.dispose()
|
disposables.dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,44 +2,44 @@ import Foundation
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
class RenderUtils {
|
class RenderUtils {
|
||||||
class func mapColor(color: Color) -> CGColor {
|
class func mapColor(_ color: Color) -> CGColor {
|
||||||
let red = CGFloat(Double(color.r()) / 255.0)
|
let red = CGFloat(Double(color.r()) / 255.0)
|
||||||
let green = CGFloat(Double(color.g()) / 255.0)
|
let green = CGFloat(Double(color.g()) / 255.0)
|
||||||
let blue = CGFloat(Double(color.b()) / 255.0)
|
let blue = CGFloat(Double(color.b()) / 255.0)
|
||||||
let alpha = CGFloat(Double(color.a()) / 255.0)
|
let alpha = CGFloat(Double(color.a()) / 255.0)
|
||||||
return UIColor(red: red, green: green, blue: blue, alpha: alpha).CGColor
|
return UIColor(red: red, green: green, blue: blue, alpha: alpha).cgColor
|
||||||
}
|
}
|
||||||
|
|
||||||
class func mapTransform(t: Transform) -> CGAffineTransform {
|
class func mapTransform(_ t: Transform) -> CGAffineTransform {
|
||||||
return CGAffineTransform(a: CGFloat(t.m11), b: CGFloat(t.m12), c: CGFloat(t.m21),
|
return CGAffineTransform(a: CGFloat(t.m11), b: CGFloat(t.m12), c: CGFloat(t.m21),
|
||||||
d: CGFloat(t.m22), tx: CGFloat(t.dx), ty: CGFloat(t.dy))
|
d: CGFloat(t.m22), tx: CGFloat(t.dx), ty: CGFloat(t.dy))
|
||||||
}
|
}
|
||||||
|
|
||||||
class func mapLineJoin(join: LineJoin?) -> CGLineJoin {
|
class func mapLineJoin(_ join: LineJoin?) -> CGLineJoin {
|
||||||
switch join {
|
switch join {
|
||||||
case LineJoin.round?: return CGLineJoin.Round
|
case LineJoin.round?: return CGLineJoin.round
|
||||||
case LineJoin.bevel?: return CGLineJoin.Bevel
|
case LineJoin.bevel?: return CGLineJoin.bevel
|
||||||
default: return CGLineJoin.Miter
|
default: return CGLineJoin.miter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class func mapLineCap(cap: LineCap?) -> CGLineCap {
|
class func mapLineCap(_ cap: LineCap?) -> CGLineCap {
|
||||||
switch cap {
|
switch cap {
|
||||||
case LineCap.round?: return CGLineCap.Round
|
case LineCap.round?: return CGLineCap.round
|
||||||
case LineCap.square?: return CGLineCap.Square
|
case LineCap.square?: return CGLineCap.square
|
||||||
default: return CGLineCap.Butt
|
default: return CGLineCap.butt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class func mapDash(dashes: [Double]) -> UnsafeMutablePointer<CGFloat> {
|
class func mapDash(_ dashes: [Double]) -> UnsafeMutablePointer<CGFloat> {
|
||||||
let p = UnsafeMutablePointer<CGFloat>(calloc(dashes.count, sizeof(CGFloat)))
|
let p = UnsafeMutablePointer<CGFloat>(calloc(dashes.count, sizeof(CGFloat)))
|
||||||
for (index, item) in dashes.enumerate() {
|
for (index, item) in dashes.enumerated() {
|
||||||
p[index] = CGFloat(item)
|
p[index] = CGFloat(item)
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
class func createNodeRenderer(node: Node, context: RenderContext, animationCache: AnimationCache) -> NodeRenderer {
|
class func createNodeRenderer(_ node: Node, context: RenderContext, animationCache: AnimationCache) -> NodeRenderer {
|
||||||
if let group = node as? Group {
|
if let group = node as? Group {
|
||||||
return GroupRenderer(group: group, ctx: context, animationCache: animationCache)
|
return GroupRenderer(group: group, ctx: context, animationCache: animationCache)
|
||||||
} else if let shape = node as? Shape {
|
} else if let shape = node as? Shape {
|
||||||
@ -52,7 +52,7 @@ class RenderUtils {
|
|||||||
fatalError("Unsupported node: \(node)");
|
fatalError("Unsupported node: \(node)");
|
||||||
}
|
}
|
||||||
|
|
||||||
class func applyOpacity(color: Color, opacity: Double) -> Color {
|
class func applyOpacity(_ color: Color, opacity: Double) -> Color {
|
||||||
return Color.rgba(r: color.r(), g: color.g(), b: color.b(), a: Double(color.a()) / 255.0 * opacity)
|
return Color.rgba(r: color.r(), g: color.g(), b: color.b(), a: Double(color.a()) / 255.0 * opacity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,61 +21,61 @@ class ShapeRenderer: NodeRenderer {
|
|||||||
observe(shape.strokeVar)
|
observe(shape.strokeVar)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func doRender(force: Bool, opacity: Double) {
|
override func doRender(_ force: Bool, opacity: Double) {
|
||||||
setGeometry(shape.form, ctx: ctx.cgContext!)
|
setGeometry(shape.form, ctx: ctx.cgContext!)
|
||||||
drawPath(shape.fill, stroke: shape.stroke, ctx: ctx.cgContext!, opacity: opacity)
|
drawPath(shape.fill, stroke: shape.stroke, ctx: ctx.cgContext!, opacity: opacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func detectTouches(location: CGPoint) -> [Shape] {
|
override func detectTouches(_ location: CGPoint) -> [Shape] {
|
||||||
var touchedShapes = [Shape]()
|
var touchedShapes = [Shape]()
|
||||||
|
|
||||||
setGeometry(shape.form, ctx: ctx.cgContext!)
|
setGeometry(shape.form, ctx: ctx.cgContext!)
|
||||||
|
|
||||||
var drawingMode: CGPathDrawingMode? = nil
|
var drawingMode: CGPathDrawingMode? = nil
|
||||||
if let _ = shape.stroke, _ = shape.fill {
|
if let _ = shape.stroke, let _ = shape.fill {
|
||||||
drawingMode = .FillStroke
|
drawingMode = .fillStroke
|
||||||
} else if let _ = shape.stroke {
|
} else if let _ = shape.stroke {
|
||||||
drawingMode = .Stroke
|
drawingMode = .stroke
|
||||||
} else if let _ = shape.fill {
|
} else if let _ = shape.fill {
|
||||||
drawingMode = .Fill
|
drawingMode = .fill
|
||||||
}
|
}
|
||||||
|
|
||||||
var contains = false
|
var contains = false
|
||||||
if let mode = drawingMode {
|
if let mode = drawingMode {
|
||||||
contains = CGContextPathContainsPoint(ctx.cgContext!, location, mode)
|
contains = ctx.cgContext!.pathContains(location, mode: mode)
|
||||||
}
|
}
|
||||||
if contains {
|
if contains {
|
||||||
touchedShapes.append(shape)
|
touchedShapes.append(shape)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare for next figure hittesting - clear current context path
|
// Prepare for next figure hittesting - clear current context path
|
||||||
CGContextBeginPath(ctx.cgContext!)
|
ctx.cgContext!.beginPath()
|
||||||
return touchedShapes
|
return touchedShapes
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setGeometry(locus: Locus, ctx: CGContext) {
|
fileprivate func setGeometry(_ locus: Locus, ctx: CGContext) {
|
||||||
if let rect = locus as? Rect {
|
if let rect = locus as? Rect {
|
||||||
CGContextAddRect(ctx, newCGRect(rect))
|
ctx.addRect(newCGRect(rect))
|
||||||
} else if let round = locus as? RoundRect {
|
} else if let round = locus as? RoundRect {
|
||||||
let corners = CGSizeMake(CGFloat(round.rx), CGFloat(round.ry))
|
let corners = CGSize(width: CGFloat(round.rx), height: CGFloat(round.ry))
|
||||||
let path = UIBezierPath(roundedRect: newCGRect(round.rect), byRoundingCorners:
|
let path = UIBezierPath(roundedRect: newCGRect(round.rect), byRoundingCorners:
|
||||||
UIRectCorner.AllCorners, cornerRadii: corners).CGPath
|
UIRectCorner.allCorners, cornerRadii: corners).cgPath
|
||||||
CGContextAddPath(ctx, path)
|
ctx.addPath(path)
|
||||||
} else if let circle = locus as? Circle {
|
} else if let circle = locus as? Circle {
|
||||||
let cx = circle.cx
|
let cx = circle.cx
|
||||||
let cy = circle.cy
|
let cy = circle.cy
|
||||||
let r = circle.r
|
let r = circle.r
|
||||||
CGContextAddEllipseInRect(ctx, CGRect(x: cx - r, y: cy - r, width: r * 2, height: r * 2))
|
ctx.addEllipse(in: CGRect(x: cx - r, y: cy - r, width: r * 2, height: r * 2))
|
||||||
} else if let ellipse = locus as? Ellipse {
|
} else if let ellipse = locus as? Ellipse {
|
||||||
let cx = ellipse.cx
|
let cx = ellipse.cx
|
||||||
let cy = ellipse.cy
|
let cy = ellipse.cy
|
||||||
let rx = ellipse.rx
|
let rx = ellipse.rx
|
||||||
let ry = ellipse.ry
|
let ry = ellipse.ry
|
||||||
CGContextAddEllipseInRect(ctx, CGRect(x: cx - rx, y: cy - ry, width: rx * 2, height: ry * 2))
|
ctx.addEllipse(in: CGRect(x: cx - rx, y: cy - ry, width: rx * 2, height: ry * 2))
|
||||||
} else if let arc = locus as? Arc {
|
} else if let arc = locus as? Arc {
|
||||||
if arc.ellipse.rx == arc.ellipse.ry {
|
if arc.ellipse.rx == arc.ellipse.ry {
|
||||||
// Only circle arc supported for now
|
// Only circle arc supported for now
|
||||||
CGContextAddPath(ctx, toBezierPath(arc).CGPath)
|
ctx.addPath(toBezierPath(arc).cgPath)
|
||||||
} else {
|
} else {
|
||||||
// http://stackoverflow.com/questions/11365775/how-to-draw-an-elliptical-arc-with-coregraphics
|
// http://stackoverflow.com/questions/11365775/how-to-draw-an-elliptical-arc-with-coregraphics
|
||||||
// input parameters
|
// input parameters
|
||||||
@ -85,60 +85,60 @@ class ShapeRenderer: NodeRenderer {
|
|||||||
let r = CGFloat(ellipse.rx)
|
let r = CGFloat(ellipse.rx)
|
||||||
let scale = CGFloat(ellipse.ry / ellipse.rx)
|
let scale = CGFloat(ellipse.ry / ellipse.rx)
|
||||||
|
|
||||||
let path = CGPathCreateMutable()
|
let path = CGMutablePath()
|
||||||
var t = CGAffineTransformMakeTranslation(CGFloat(ellipse.cx), CGFloat(ellipse.cy))
|
var t = CGAffineTransform(translationX: CGFloat(ellipse.cx), y: CGFloat(ellipse.cy))
|
||||||
t = CGAffineTransformConcat(CGAffineTransformMakeScale(1.0, scale), t);
|
t = CGAffineTransform(scaleX: 1.0, y: scale).concatenating(t);
|
||||||
CGPathAddArc(path, &t, 0, 0, r, startAngle, endAngle, false)
|
CGPathAddArc(path, &t, 0, 0, r, startAngle, endAngle, false)
|
||||||
CGContextAddPath(ctx, path)
|
ctx.addPath(path)
|
||||||
}
|
}
|
||||||
} else if let point = locus as? Point {
|
} else if let point = locus as? Point {
|
||||||
let path = UIBezierPath()
|
let path = UIBezierPath()
|
||||||
path.moveToPoint(CGPointMake(CGFloat(point.x), CGFloat(point.y)))
|
path.move(to: CGPoint(x: CGFloat(point.x), y: CGFloat(point.y)))
|
||||||
path.addLineToPoint(CGPointMake(CGFloat(point.x), CGFloat(point.y)))
|
path.addLine(to: CGPoint(x: CGFloat(point.x), y: CGFloat(point.y)))
|
||||||
CGContextAddPath(ctx, path.CGPath)
|
ctx.addPath(path.cgPath)
|
||||||
} else if let line = locus as? Line {
|
} else if let line = locus as? Line {
|
||||||
let path = UIBezierPath()
|
let path = UIBezierPath()
|
||||||
path.moveToPoint(CGPointMake(CGFloat(line.x1), CGFloat(line.y1)))
|
path.move(to: CGPoint(x: CGFloat(line.x1), y: CGFloat(line.y1)))
|
||||||
path.addLineToPoint(CGPointMake(CGFloat(line.x2), CGFloat(line.y2)))
|
path.addLine(to: CGPoint(x: CGFloat(line.x2), y: CGFloat(line.y2)))
|
||||||
CGContextAddPath(ctx, path.CGPath)
|
ctx.addPath(path.cgPath)
|
||||||
} else if let polygon = locus as? Polygon {
|
} else if let polygon = locus as? Polygon {
|
||||||
let path = toBezierPath(polygon.points)
|
let path = toBezierPath(polygon.points)
|
||||||
path.closePath()
|
path.close()
|
||||||
CGContextAddPath(ctx, path.CGPath)
|
ctx.addPath(path.cgPath)
|
||||||
} else if let polygon = locus as? Polyline {
|
} else if let polygon = locus as? Polyline {
|
||||||
CGContextAddPath(ctx, toBezierPath(polygon.points).CGPath)
|
ctx.addPath(toBezierPath(polygon.points).cgPath)
|
||||||
} else if let path = locus as? Path {
|
} else if let path = locus as? Path {
|
||||||
CGContextAddPath(ctx, toBezierPath(path).CGPath)
|
ctx.addPath(toBezierPath(path).cgPath)
|
||||||
} else {
|
} else {
|
||||||
print("Unsupported locus: \(locus)")
|
print("Unsupported locus: \(locus)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func toBezierPath(arc: Arc) -> UIBezierPath {
|
fileprivate func toBezierPath(_ arc: Arc) -> UIBezierPath {
|
||||||
let shift = CGFloat(arc.shift)
|
let shift = CGFloat(arc.shift)
|
||||||
let end = shift + CGFloat(arc.extent)
|
let end = shift + CGFloat(arc.extent)
|
||||||
let ellipse = arc.ellipse
|
let ellipse = arc.ellipse
|
||||||
let center = CGPointMake(CGFloat(ellipse.cx), CGFloat(ellipse.cy))
|
let center = CGPoint(x: CGFloat(ellipse.cx), y: CGFloat(ellipse.cy))
|
||||||
return UIBezierPath(arcCenter: center, radius: CGFloat(ellipse.rx), startAngle: shift, endAngle: end, clockwise: true)
|
return UIBezierPath(arcCenter: center, radius: CGFloat(ellipse.rx), startAngle: shift, endAngle: end, clockwise: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func toBezierPath(points: [Double]) -> UIBezierPath {
|
fileprivate func toBezierPath(_ points: [Double]) -> UIBezierPath {
|
||||||
let parts = 0.stride(to: points.count, by: 2).map { Array(points[$0 ..< $0 + 2]) }
|
let parts = stride(from: 0, to: points.count, by: 2).map { Array(points[$0 ..< $0 + 2]) }
|
||||||
let path = UIBezierPath()
|
let path = UIBezierPath()
|
||||||
var first = true
|
var first = true
|
||||||
for part in parts {
|
for part in parts {
|
||||||
let point = CGPointMake(CGFloat(part[0]), CGFloat(part[1]))
|
let point = CGPoint(x: CGFloat(part[0]), y: CGFloat(part[1]))
|
||||||
if (first) {
|
if (first) {
|
||||||
path.moveToPoint(point)
|
path.move(to: point)
|
||||||
first = false
|
first = false
|
||||||
} else {
|
} else {
|
||||||
path.addLineToPoint(point)
|
path.addLine(to: point)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
private func toBezierPath(path: Path) -> UIBezierPath {
|
fileprivate func toBezierPath(_ path: Path) -> UIBezierPath {
|
||||||
let bezierPath = UIBezierPath()
|
let bezierPath = UIBezierPath()
|
||||||
|
|
||||||
var currentPoint: CGPoint?
|
var currentPoint: CGPoint?
|
||||||
@ -146,119 +146,119 @@ class ShapeRenderer: NodeRenderer {
|
|||||||
var quadrPoint: CGPoint?
|
var quadrPoint: CGPoint?
|
||||||
var initialPoint: CGPoint?
|
var initialPoint: CGPoint?
|
||||||
|
|
||||||
func M(x: Double, y: Double) {
|
func M(_ x: Double, y: Double) {
|
||||||
let point = CGPointMake(CGFloat(x), CGFloat(y))
|
let point = CGPoint(x: CGFloat(x), y: CGFloat(y))
|
||||||
bezierPath.moveToPoint(point)
|
bezierPath.move(to: point)
|
||||||
setInitPoint(point)
|
setInitPoint(point)
|
||||||
}
|
}
|
||||||
|
|
||||||
func m(x: Double, y: Double) {
|
func m(_ x: Double, y: Double) {
|
||||||
if let cur = currentPoint {
|
if let cur = currentPoint {
|
||||||
let next = CGPointMake(CGFloat(x) + cur.x, CGFloat(y) + cur.y)
|
let next = CGPoint(x: CGFloat(x) + cur.x, y: CGFloat(y) + cur.y)
|
||||||
bezierPath.moveToPoint(next)
|
bezierPath.move(to: next)
|
||||||
setInitPoint(next)
|
setInitPoint(next)
|
||||||
} else {
|
} else {
|
||||||
M(x, y: y)
|
M(x, y: y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func L(x: Double, y: Double) {
|
func L(_ x: Double, y: Double) {
|
||||||
lineTo(CGPointMake(CGFloat(x), CGFloat(y)))
|
lineTo(CGPoint(x: CGFloat(x), y: CGFloat(y)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func l(x: Double, y: Double) {
|
func l(_ x: Double, y: Double) {
|
||||||
if let cur = currentPoint {
|
if let cur = currentPoint {
|
||||||
lineTo(CGPointMake(CGFloat(x) + cur.x, CGFloat(y) + cur.y))
|
lineTo(CGPoint(x: CGFloat(x) + cur.x, y: CGFloat(y) + cur.y))
|
||||||
} else {
|
} else {
|
||||||
L(x, y: y)
|
L(x, y: y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func H(x: Double) {
|
func H(_ x: Double) {
|
||||||
if let cur = currentPoint {
|
if let cur = currentPoint {
|
||||||
lineTo(CGPointMake(CGFloat(x), CGFloat(cur.y)))
|
lineTo(CGPoint(x: CGFloat(x), y: CGFloat(cur.y)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func h(x: Double) {
|
func h(_ x: Double) {
|
||||||
if let cur = currentPoint {
|
if let cur = currentPoint {
|
||||||
lineTo(CGPointMake(CGFloat(x) + cur.x, CGFloat(cur.y)))
|
lineTo(CGPoint(x: CGFloat(x) + cur.x, y: CGFloat(cur.y)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func V(y: Double) {
|
func V(_ y: Double) {
|
||||||
if let cur = currentPoint {
|
if let cur = currentPoint {
|
||||||
lineTo(CGPointMake(CGFloat(cur.x), CGFloat(y)))
|
lineTo(CGPoint(x: CGFloat(cur.x), y: CGFloat(y)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func v(y: Double) {
|
func v(_ y: Double) {
|
||||||
if let cur = currentPoint {
|
if let cur = currentPoint {
|
||||||
lineTo(CGPointMake(CGFloat(cur.x), CGFloat(y) + cur.y))
|
lineTo(CGPoint(x: CGFloat(cur.x), y: CGFloat(y) + cur.y))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func lineTo(p: CGPoint) {
|
func lineTo(_ p: CGPoint) {
|
||||||
bezierPath.addLineToPoint(p)
|
bezierPath.addLine(to: p)
|
||||||
setPoint(p)
|
setPoint(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func c(x1: Double, y1: Double, x2: Double, y2: Double, x: Double, y: Double) {
|
func c(_ x1: Double, y1: Double, x2: Double, y2: Double, x: Double, y: Double) {
|
||||||
if let cur = currentPoint {
|
if let cur = currentPoint {
|
||||||
let endPoint = CGPointMake(CGFloat(x) + cur.x, CGFloat(y) + cur.y)
|
let endPoint = CGPoint(x: CGFloat(x) + cur.x, y: CGFloat(y) + cur.y)
|
||||||
let controlPoint1 = CGPointMake(CGFloat(x1) + cur.x, CGFloat(y1) + cur.y)
|
let controlPoint1 = CGPoint(x: CGFloat(x1) + cur.x, y: CGFloat(y1) + cur.y)
|
||||||
let controlPoint2 = CGPointMake(CGFloat(x2) + cur.x, CGFloat(y2) + cur.y)
|
let controlPoint2 = CGPoint(x: CGFloat(x2) + cur.x, y: CGFloat(y2) + cur.y)
|
||||||
bezierPath.addCurveToPoint(endPoint, controlPoint1: controlPoint1, controlPoint2: controlPoint2)
|
bezierPath.addCurve(to: endPoint, controlPoint1: controlPoint1, controlPoint2: controlPoint2)
|
||||||
setCubicPoint(endPoint, cubic: controlPoint2)
|
setCubicPoint(endPoint, cubic: controlPoint2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func C(x1: Double, y1: Double, x2: Double, y2: Double, x: Double, y: Double) {
|
func C(_ x1: Double, y1: Double, x2: Double, y2: Double, x: Double, y: Double) {
|
||||||
let endPoint = CGPointMake(CGFloat(x), CGFloat(y))
|
let endPoint = CGPoint(x: CGFloat(x), y: CGFloat(y))
|
||||||
let controlPoint1 = CGPointMake(CGFloat(x1), CGFloat(y1))
|
let controlPoint1 = CGPoint(x: CGFloat(x1), y: CGFloat(y1))
|
||||||
let controlPoint2 = CGPointMake(CGFloat(x2), CGFloat(y2))
|
let controlPoint2 = CGPoint(x: CGFloat(x2), y: CGFloat(y2))
|
||||||
bezierPath.addCurveToPoint(endPoint, controlPoint1: controlPoint1, controlPoint2: controlPoint2)
|
bezierPath.addCurve(to: endPoint, controlPoint1: controlPoint1, controlPoint2: controlPoint2)
|
||||||
setCubicPoint(endPoint, cubic: controlPoint2)
|
setCubicPoint(endPoint, cubic: controlPoint2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func s(x2: Double, y2: Double, x: Double, y: Double) {
|
func s(_ x2: Double, y2: Double, x: Double, y: Double) {
|
||||||
if let cur = currentPoint {
|
if let cur = currentPoint {
|
||||||
let nextCubic = CGPointMake(CGFloat(x2) + cur.x, CGFloat(y2) + cur.y)
|
let nextCubic = CGPoint(x: CGFloat(x2) + cur.x, y: CGFloat(y2) + cur.y)
|
||||||
let next = CGPointMake(CGFloat(x) + cur.x, CGFloat(y) + cur.y)
|
let next = CGPoint(x: CGFloat(x) + cur.x, y: CGFloat(y) + cur.y)
|
||||||
|
|
||||||
var xy1: CGPoint?
|
var xy1: CGPoint?
|
||||||
if let curCubicVal = cubicPoint {
|
if let curCubicVal = cubicPoint {
|
||||||
xy1 = CGPointMake(CGFloat(2 * cur.x) - curCubicVal.x, CGFloat(2 * cur.y) - curCubicVal.y)
|
xy1 = CGPoint(x: CGFloat(2 * cur.x) - curCubicVal.x, y: CGFloat(2 * cur.y) - curCubicVal.y)
|
||||||
} else {
|
} else {
|
||||||
xy1 = cur
|
xy1 = cur
|
||||||
}
|
}
|
||||||
bezierPath.addCurveToPoint(next, controlPoint1: xy1!, controlPoint2: nextCubic)
|
bezierPath.addCurve(to: next, controlPoint1: xy1!, controlPoint2: nextCubic)
|
||||||
setCubicPoint(next, cubic: nextCubic)
|
setCubicPoint(next, cubic: nextCubic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func S(x2: Double, y2: Double, x: Double, y: Double) {
|
func S(_ x2: Double, y2: Double, x: Double, y: Double) {
|
||||||
if let cur = currentPoint {
|
if let cur = currentPoint {
|
||||||
let nextCubic = CGPointMake(CGFloat(x2), CGFloat(y2))
|
let nextCubic = CGPoint(x: CGFloat(x2), y: CGFloat(y2))
|
||||||
let next = CGPointMake(CGFloat(x), CGFloat(y))
|
let next = CGPoint(x: CGFloat(x), y: CGFloat(y))
|
||||||
var xy1: CGPoint?
|
var xy1: CGPoint?
|
||||||
if let curCubicVal = cubicPoint {
|
if let curCubicVal = cubicPoint {
|
||||||
xy1 = CGPointMake(CGFloat(2 * cur.x) - curCubicVal.x, CGFloat(2 * cur.y) - curCubicVal.y)
|
xy1 = CGPoint(x: CGFloat(2 * cur.x) - curCubicVal.x, y: CGFloat(2 * cur.y) - curCubicVal.y)
|
||||||
} else {
|
} else {
|
||||||
xy1 = cur
|
xy1 = cur
|
||||||
}
|
}
|
||||||
bezierPath.addCurveToPoint(next, controlPoint1: xy1!, controlPoint2: nextCubic)
|
bezierPath.addCurve(to: next, controlPoint1: xy1!, controlPoint2: nextCubic)
|
||||||
setCubicPoint(next, cubic: nextCubic)
|
setCubicPoint(next, cubic: nextCubic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func a(rx: Double, ry: Double, angle: Double, largeArc: Bool, sweep: Bool, x: Double, y: Double) {
|
func a(_ rx: Double, ry: Double, angle: Double, largeArc: Bool, sweep: Bool, x: Double, y: Double) {
|
||||||
if let cur = currentPoint {
|
if let cur = currentPoint {
|
||||||
A(rx, ry: ry, angle: angle, largeArc: largeArc, sweep: sweep, x: x + Double(cur.x), y: y + Double(cur.y))
|
A(rx, ry: ry, angle: angle, largeArc: largeArc, sweep: sweep, x: x + Double(cur.x), y: y + Double(cur.y))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func A(rx: Double, ry: Double, angle: Double, largeArc: Bool, sweep: Bool, x: Double, y: Double) {
|
func A(_ rx: Double, ry: Double, angle: Double, largeArc: Bool, sweep: Bool, x: Double, y: Double) {
|
||||||
if let cur = currentPoint {
|
if let cur = currentPoint {
|
||||||
let x1 = Double(cur.x)
|
let x1 = Double(cur.x)
|
||||||
let y1 = Double(cur.y)
|
let y1 = Double(cur.y)
|
||||||
@ -294,19 +294,19 @@ class ShapeRenderer: NodeRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
E(cx - rx, y: cy - ry, w: 2 * rx, h: 2 * ry, startAngle: t1, arcAngle: delta);
|
E(cx - rx, y: cy - ry, w: 2 * rx, h: 2 * ry, startAngle: t1, arcAngle: delta);
|
||||||
setPoint(CGPointMake(CGFloat(x), CGFloat(y)))
|
setPoint(CGPoint(x: CGFloat(x), y: CGFloat(y)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func E(x: Double, y: Double, w: Double, h: Double, startAngle: Double, arcAngle: Double) {
|
func E(_ x: Double, y: Double, w: Double, h: Double, startAngle: Double, arcAngle: Double) {
|
||||||
// TODO: only circle now
|
// TODO: only circle now
|
||||||
let extent = CGFloat(startAngle)
|
let extent = CGFloat(startAngle)
|
||||||
let end = extent + CGFloat(arcAngle)
|
let end = extent + CGFloat(arcAngle)
|
||||||
let center = CGPointMake(CGFloat(x + w / 2), CGFloat(y + h / 2))
|
let center = CGPoint(x: CGFloat(x + w / 2), y: CGFloat(y + h / 2))
|
||||||
bezierPath.addArcWithCenter(center, radius: CGFloat(w / 2), startAngle: extent, endAngle: end, clockwise: true)
|
bezierPath.addArc(withCenter: center, radius: CGFloat(w / 2), startAngle: extent, endAngle: end, clockwise: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func e(x: Double, y: Double, w: Double, h: Double, startAngle: Double, arcAngle: Double) {
|
func e(_ x: Double, y: Double, w: Double, h: Double, startAngle: Double, arcAngle: Double) {
|
||||||
// TODO: only circle now
|
// TODO: only circle now
|
||||||
if let cur = currentPoint {
|
if let cur = currentPoint {
|
||||||
E(x + Double(cur.x), y: y + Double(cur.y), w: w, h: h, startAngle: startAngle, arcAngle: arcAngle)
|
E(x + Double(cur.x), y: y + Double(cur.y), w: w, h: h, startAngle: startAngle, arcAngle: arcAngle)
|
||||||
@ -317,21 +317,21 @@ class ShapeRenderer: NodeRenderer {
|
|||||||
if let initPoint = initialPoint {
|
if let initPoint = initialPoint {
|
||||||
lineTo(initPoint)
|
lineTo(initPoint)
|
||||||
}
|
}
|
||||||
bezierPath.closePath()
|
bezierPath.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func setCubicPoint(p: CGPoint, cubic: CGPoint) {
|
func setCubicPoint(_ p: CGPoint, cubic: CGPoint) {
|
||||||
currentPoint = p
|
currentPoint = p
|
||||||
cubicPoint = cubic
|
cubicPoint = cubic
|
||||||
quadrPoint = nil
|
quadrPoint = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setInitPoint(p: CGPoint) {
|
func setInitPoint(_ p: CGPoint) {
|
||||||
setPoint(p)
|
setPoint(p)
|
||||||
initialPoint = p
|
initialPoint = p
|
||||||
}
|
}
|
||||||
|
|
||||||
func setPoint(p: CGPoint) {
|
func setPoint(_ p: CGPoint) {
|
||||||
currentPoint = p
|
currentPoint = p
|
||||||
cubicPoint = nil
|
cubicPoint = nil
|
||||||
quadrPoint = nil
|
quadrPoint = nil
|
||||||
@ -343,27 +343,27 @@ class ShapeRenderer: NodeRenderer {
|
|||||||
switch part.type {
|
switch part.type {
|
||||||
case .M:
|
case .M:
|
||||||
M(data[0], y: data[1])
|
M(data[0], y: data[1])
|
||||||
data.removeRange(Range(start: 0, end: 2))
|
data.removeSubrange((0 ..< 2))
|
||||||
while data.count >= 2 {
|
while data.count >= 2 {
|
||||||
L(data[0], y: data[1])
|
L(data[0], y: data[1])
|
||||||
data.removeRange(Range(start: 0, end: 2))
|
data.removeSubrange((0 ..< 2))
|
||||||
}
|
}
|
||||||
case .m:
|
case .m:
|
||||||
m(data[0], y: data[1])
|
m(data[0], y: data[1])
|
||||||
data.removeRange(Range(start: 0, end: 2))
|
data.removeSubrange((0 ..< 2))
|
||||||
while data.count >= 2 {
|
while data.count >= 2 {
|
||||||
l(data[0], y: data[1])
|
l(data[0], y: data[1])
|
||||||
data.removeRange(Range(start: 0, end: 2))
|
data.removeSubrange((0 ..< 2))
|
||||||
}
|
}
|
||||||
case .L:
|
case .L:
|
||||||
while data.count >= 2 {
|
while data.count >= 2 {
|
||||||
L(data[0], y: data[1])
|
L(data[0], y: data[1])
|
||||||
data.removeRange(Range(start: 0, end: 2))
|
data.removeSubrange((0 ..< 2))
|
||||||
}
|
}
|
||||||
case .l:
|
case .l:
|
||||||
while data.count >= 2 {
|
while data.count >= 2 {
|
||||||
l(data[0], y: data[1])
|
l(data[0], y: data[1])
|
||||||
data.removeRange(Range(start: 0, end: 2))
|
data.removeSubrange((0 ..< 2))
|
||||||
}
|
}
|
||||||
case .H:
|
case .H:
|
||||||
H(data[0])
|
H(data[0])
|
||||||
@ -376,22 +376,22 @@ class ShapeRenderer: NodeRenderer {
|
|||||||
case .C:
|
case .C:
|
||||||
while data.count >= 6 {
|
while data.count >= 6 {
|
||||||
C(data[0], y1: data[1], x2: data[2], y2: data[3], x: data[4], y: data[5])
|
C(data[0], y1: data[1], x2: data[2], y2: data[3], x: data[4], y: data[5])
|
||||||
data.removeRange(Range(start: 0, end: 6))
|
data.removeSubrange((0 ..< 6))
|
||||||
}
|
}
|
||||||
case .c:
|
case .c:
|
||||||
while data.count >= 6 {
|
while data.count >= 6 {
|
||||||
c(data[0], y1: data[1], x2: data[2], y2: data[3], x: data[4], y: data[5])
|
c(data[0], y1: data[1], x2: data[2], y2: data[3], x: data[4], y: data[5])
|
||||||
data.removeRange(Range(start: 0, end: 6))
|
data.removeSubrange((0 ..< 6))
|
||||||
}
|
}
|
||||||
case .S:
|
case .S:
|
||||||
while data.count >= 4 {
|
while data.count >= 4 {
|
||||||
S(data[0], y2: data[1], x: data[2], y: data[3])
|
S(data[0], y2: data[1], x: data[2], y: data[3])
|
||||||
data.removeRange(Range(start: 0, end: 4))
|
data.removeSubrange((0 ..< 4))
|
||||||
}
|
}
|
||||||
case .s:
|
case .s:
|
||||||
while data.count >= 4 {
|
while data.count >= 4 {
|
||||||
s(data[0], y2: data[1], x: data[2], y: data[3])
|
s(data[0], y2: data[1], x: data[2], y: data[3])
|
||||||
data.removeRange(Range(start: 0, end: 4))
|
data.removeSubrange((0 ..< 4))
|
||||||
}
|
}
|
||||||
case .A:
|
case .A:
|
||||||
let flags = numToBools(data[3])
|
let flags = numToBools(data[3])
|
||||||
@ -399,7 +399,7 @@ class ShapeRenderer: NodeRenderer {
|
|||||||
case .a:
|
case .a:
|
||||||
let flags = numToBools(data[3])
|
let flags = numToBools(data[3])
|
||||||
a(data[0], ry: data[1], angle: data[2], largeArc: flags[0], sweep: flags[1], x: data[4], y: data[5])
|
a(data[0], ry: data[1], angle: data[2], largeArc: flags[0], sweep: flags[1], x: data[4], y: data[5])
|
||||||
case .Z:
|
case .z:
|
||||||
Z()
|
Z()
|
||||||
default:
|
default:
|
||||||
fatalError("Unknown segment: \(part.type)")
|
fatalError("Unknown segment: \(part.type)")
|
||||||
@ -408,54 +408,54 @@ class ShapeRenderer: NodeRenderer {
|
|||||||
return bezierPath
|
return bezierPath
|
||||||
}
|
}
|
||||||
|
|
||||||
private func numToBools(num: Double) -> [Bool] {
|
fileprivate func numToBools(_ num: Double) -> [Bool] {
|
||||||
let val: Int = Int(num);
|
let val: Int = Int(num);
|
||||||
return [(val & 1) > 0, (val & 2) > 0];
|
return [(val & 1) > 0, (val & 2) > 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private func newCGRect(rect: Rect) -> CGRect {
|
fileprivate func newCGRect(_ rect: Rect) -> CGRect {
|
||||||
return CGRect(x: CGFloat(rect.x), y: CGFloat(rect.y), width: CGFloat(rect.w), height: CGFloat(rect.h))
|
return CGRect(x: CGFloat(rect.x), y: CGFloat(rect.y), width: CGFloat(rect.w), height: CGFloat(rect.h))
|
||||||
}
|
}
|
||||||
|
|
||||||
private func drawPath(fill: Fill?, stroke: Stroke?, ctx: CGContext?, opacity: Double) {
|
fileprivate func drawPath(_ fill: Fill?, stroke: Stroke?, ctx: CGContext?, opacity: Double) {
|
||||||
var shouldStrokePath = false
|
var shouldStrokePath = false
|
||||||
if fill is Gradient || stroke?.fill is Gradient {
|
if fill is Gradient || stroke?.fill is Gradient {
|
||||||
shouldStrokePath = true
|
shouldStrokePath = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if let fill = fill, stroke = stroke {
|
if let fill = fill, let stroke = stroke {
|
||||||
let path = CGContextCopyPath(ctx!)
|
let path = ctx!.path
|
||||||
setFill(fill, ctx: ctx, opacity: opacity)
|
setFill(fill, ctx: ctx, opacity: opacity)
|
||||||
if stroke.fill is Gradient && !(fill is Gradient) {
|
if stroke.fill is Gradient && !(fill is Gradient) {
|
||||||
CGContextDrawPath(ctx!, .Fill)
|
ctx!.drawPath(using: .fill)
|
||||||
}
|
}
|
||||||
drawWithStroke(stroke, ctx: ctx, opacity: opacity, shouldStrokePath: shouldStrokePath, path: path, mode: .FillStroke)
|
drawWithStroke(stroke, ctx: ctx, opacity: opacity, shouldStrokePath: shouldStrokePath, path: path, mode: .fillStroke)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if let fill = fill {
|
if let fill = fill {
|
||||||
setFill(fill, ctx: ctx, opacity: opacity)
|
setFill(fill, ctx: ctx, opacity: opacity)
|
||||||
CGContextDrawPath(ctx!, .Fill)
|
ctx!.drawPath(using: .fill)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if let stroke = stroke {
|
if let stroke = stroke {
|
||||||
drawWithStroke(stroke, ctx: ctx, opacity: opacity, shouldStrokePath: shouldStrokePath, mode: .Stroke)
|
drawWithStroke(stroke, ctx: ctx, opacity: opacity, shouldStrokePath: shouldStrokePath, mode: .stroke)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
CGContextSetLineWidth(ctx!, 2.0)
|
ctx!.setLineWidth(2.0)
|
||||||
CGContextSetStrokeColorWithColor(ctx!, UIColor.blackColor().CGColor)
|
ctx!.setStrokeColor(UIColor.black.cgColor)
|
||||||
CGContextDrawPath(ctx!, .Stroke)
|
ctx!.drawPath(using: .stroke)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setFill(fill: Fill?, ctx: CGContext?, opacity: Double) {
|
fileprivate func setFill(_ fill: Fill?, ctx: CGContext?, opacity: Double) {
|
||||||
guard let fill = fill else {
|
guard let fill = fill else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if let fillColor = fill as? Color {
|
if let fillColor = fill as? Color {
|
||||||
let color = RenderUtils.applyOpacity(fillColor, opacity: opacity)
|
let color = RenderUtils.applyOpacity(fillColor, opacity: opacity)
|
||||||
CGContextSetFillColorWithColor(ctx!, RenderUtils.mapColor(color))
|
ctx!.setFillColor(RenderUtils.mapColor(color))
|
||||||
} else if let gradient = fill as? Gradient {
|
} else if let gradient = fill as? Gradient {
|
||||||
drawGradient(gradient, ctx: ctx, opacity: opacity)
|
drawGradient(gradient, ctx: ctx, opacity: opacity)
|
||||||
} else {
|
} else {
|
||||||
@ -463,9 +463,9 @@ class ShapeRenderer: NodeRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func drawWithStroke(stroke: Stroke, ctx: CGContext?, opacity: Double, shouldStrokePath: Bool = false, path: CGPath? = nil, mode: CGPathDrawingMode) {
|
fileprivate func drawWithStroke(_ stroke: Stroke, ctx: CGContext?, opacity: Double, shouldStrokePath: Bool = false, path: CGPath? = nil, mode: CGPathDrawingMode) {
|
||||||
if let path = path where shouldStrokePath {
|
if let path = path , shouldStrokePath {
|
||||||
CGContextAddPath(ctx!, path)
|
ctx!.addPath(path)
|
||||||
}
|
}
|
||||||
setStrokeAttributes(stroke, ctx: ctx)
|
setStrokeAttributes(stroke, ctx: ctx)
|
||||||
|
|
||||||
@ -476,42 +476,42 @@ class ShapeRenderer: NodeRenderer {
|
|||||||
colorStroke(stroke, ctx: ctx, opacity: opacity)
|
colorStroke(stroke, ctx: ctx, opacity: opacity)
|
||||||
}
|
}
|
||||||
if shouldStrokePath {
|
if shouldStrokePath {
|
||||||
CGContextStrokePath(ctx!)
|
ctx!.strokePath()
|
||||||
} else {
|
} else {
|
||||||
CGContextDrawPath(ctx!, mode)
|
ctx!.drawPath(using: mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setStrokeAttributes(stroke: Stroke, ctx: CGContext?) {
|
fileprivate func setStrokeAttributes(_ stroke: Stroke, ctx: CGContext?) {
|
||||||
CGContextSetLineWidth(ctx!, CGFloat(stroke.width))
|
ctx!.setLineWidth(CGFloat(stroke.width))
|
||||||
CGContextSetLineJoin(ctx!, RenderUtils.mapLineJoin(stroke.join))
|
ctx!.setLineJoin(RenderUtils.mapLineJoin(stroke.join))
|
||||||
CGContextSetLineCap(ctx!, RenderUtils.mapLineCap(stroke.cap))
|
ctx!.setLineCap(RenderUtils.mapLineCap(stroke.cap))
|
||||||
let dashes = stroke.dashes
|
let dashes = stroke.dashes
|
||||||
if !dashes.isEmpty {
|
if !dashes.isEmpty {
|
||||||
let dashPointer = RenderUtils.mapDash(dashes)
|
let dashPointer = RenderUtils.mapDash(dashes)
|
||||||
CGContextSetLineDash(ctx!, 0, dashPointer, dashes.count)
|
CGContextSetLineDash(ctx!, 0, dashPointer, dashes.count)
|
||||||
dashPointer.dealloc(dashes.count)
|
dashPointer.deallocateCapacity(dashes.count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func colorStroke(stroke: Stroke, ctx: CGContext?, opacity: Double) {
|
fileprivate func colorStroke(_ stroke: Stroke, ctx: CGContext?, opacity: Double) {
|
||||||
guard let strokeColor = stroke.fill as? Color else {
|
guard let strokeColor = stroke.fill as? Color else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let color = RenderUtils.applyOpacity(strokeColor, opacity: opacity)
|
let color = RenderUtils.applyOpacity(strokeColor, opacity: opacity)
|
||||||
CGContextSetStrokeColorWithColor(ctx!, RenderUtils.mapColor(color))
|
ctx!.setStrokeColor(RenderUtils.mapColor(color))
|
||||||
}
|
}
|
||||||
|
|
||||||
private func gradientStroke(stroke: Stroke, ctx: CGContext?, opacity: Double) {
|
fileprivate func gradientStroke(_ stroke: Stroke, ctx: CGContext?, opacity: Double) {
|
||||||
guard let gradient = stroke.fill as? Gradient else {
|
guard let gradient = stroke.fill as? Gradient else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
CGContextReplacePathWithStrokedPath(ctx!)
|
ctx!.replacePathWithStrokedPath()
|
||||||
drawGradient(gradient, ctx: ctx, opacity: opacity)
|
drawGradient(gradient, ctx: ctx, opacity: opacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func drawGradient(gradient: Gradient, ctx: CGContext?, opacity: Double) {
|
fileprivate func drawGradient(_ gradient: Gradient, ctx: CGContext?, opacity: Double) {
|
||||||
CGContextSaveGState(ctx!)
|
ctx!.saveGState()
|
||||||
var colors: [CGColor] = []
|
var colors: [CGColor] = []
|
||||||
var stops: [CGFloat] = []
|
var stops: [CGFloat] = []
|
||||||
for stop in gradient.stops {
|
for stop in gradient.stops {
|
||||||
@ -521,22 +521,22 @@ class ShapeRenderer: NodeRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let gradient = gradient as? LinearGradient {
|
if let gradient = gradient as? LinearGradient {
|
||||||
var start = CGPointMake(CGFloat(gradient.x1), CGFloat(gradient.y1))
|
var start = CGPoint(x: CGFloat(gradient.x1), y: CGFloat(gradient.y1))
|
||||||
var end = CGPointMake(CGFloat(gradient.x2), CGFloat(gradient.y2))
|
var end = CGPoint(x: CGFloat(gradient.x2), y: CGFloat(gradient.y2))
|
||||||
if !gradient.userSpace {
|
if !gradient.userSpace {
|
||||||
let bounds = CGContextGetPathBoundingBox(ctx!)
|
let bounds = ctx!.boundingBoxOfPath
|
||||||
start = CGPointMake(start.x * bounds.width + bounds.minX, start.y * bounds.height + bounds.minY)
|
start = CGPoint(x: start.x * bounds.width + bounds.minX, y: start.y * bounds.height + bounds.minY)
|
||||||
end = CGPointMake(end.x * bounds.width + bounds.minX, end.y * bounds.height + bounds.minY)
|
end = CGPoint(x: end.x * bounds.width + bounds.minX, y: end.y * bounds.height + bounds.minY)
|
||||||
}
|
}
|
||||||
CGContextClip(ctx!)
|
ctx!.clip()
|
||||||
let cgGradient = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), colors, stops)
|
let cgGradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: colors as CFArray, locations: stops)
|
||||||
CGContextDrawLinearGradient(ctx!, cgGradient!, start, end, [.DrawsAfterEndLocation, .DrawsBeforeStartLocation])
|
ctx!.drawLinearGradient(cgGradient!, start: start, end: end, options: [.drawsAfterEndLocation, .drawsBeforeStartLocation])
|
||||||
} else if let gradient = gradient as? RadialGradient {
|
} else if let gradient = gradient as? RadialGradient {
|
||||||
var innerCenter = CGPointMake(CGFloat(gradient.fx), CGFloat(gradient.fy))
|
var innerCenter = CGPoint(x: CGFloat(gradient.fx), y: CGFloat(gradient.fy))
|
||||||
var outerCenter = CGPointMake(CGFloat(gradient.cx), CGFloat(gradient.cy))
|
var outerCenter = CGPoint(x: CGFloat(gradient.cx), y: CGFloat(gradient.cy))
|
||||||
var radius = CGFloat(gradient.r)
|
var radius = CGFloat(gradient.r)
|
||||||
if !gradient.userSpace {
|
if !gradient.userSpace {
|
||||||
var bounds = CGContextGetPathBoundingBox(ctx!)
|
var bounds = ctx!.boundingBoxOfPath
|
||||||
var scaleX: CGFloat = 1
|
var scaleX: CGFloat = 1
|
||||||
var scaleY: CGFloat = 1
|
var scaleY: CGFloat = 1
|
||||||
if bounds.width > bounds.height {
|
if bounds.width > bounds.height {
|
||||||
@ -544,18 +544,18 @@ class ShapeRenderer: NodeRenderer {
|
|||||||
} else {
|
} else {
|
||||||
scaleX = bounds.width / bounds.height
|
scaleX = bounds.width / bounds.height
|
||||||
}
|
}
|
||||||
CGContextScaleCTM(ctx!, scaleX, scaleY)
|
ctx!.scaleBy(x: scaleX, y: scaleY)
|
||||||
bounds = CGContextGetPathBoundingBox(ctx!)
|
bounds = ctx!.boundingBoxOfPath
|
||||||
innerCenter = CGPointMake(innerCenter.x * bounds.width + bounds.minX, innerCenter.y * bounds.height + bounds.minY)
|
innerCenter = CGPoint(x: innerCenter.x * bounds.width + bounds.minX, y: innerCenter.y * bounds.height + bounds.minY)
|
||||||
outerCenter = CGPointMake(outerCenter.x * bounds.width + bounds.minX, outerCenter.y * bounds.height + bounds.minY)
|
outerCenter = CGPoint(x: outerCenter.x * bounds.width + bounds.minX, y: outerCenter.y * bounds.height + bounds.minY)
|
||||||
radius = min(radius * bounds.width, radius * bounds.height)
|
radius = min(radius * bounds.width, radius * bounds.height)
|
||||||
|
|
||||||
}
|
}
|
||||||
CGContextClip(ctx!)
|
ctx!.clip()
|
||||||
let cgGradient = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), colors, stops)
|
let cgGradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: colors as CFArray, locations: stops)
|
||||||
CGContextDrawRadialGradient(ctx!, cgGradient!, innerCenter, 0, outerCenter, radius, [.DrawsAfterEndLocation, .DrawsBeforeStartLocation])
|
ctx!.drawRadialGradient(cgGradient!, startCenter: innerCenter, startRadius: 0, endCenter: outerCenter, endRadius: radius, options: [.drawsAfterEndLocation, .drawsBeforeStartLocation])
|
||||||
}
|
}
|
||||||
CGContextRestoreGState(ctx!)
|
ctx!.restoreGState()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,17 +22,17 @@ class TextRenderer: NodeRenderer {
|
|||||||
observe(text.baselineVar)
|
observe(text.baselineVar)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func doRender(force: Bool, opacity: Double) {
|
override func doRender(_ force: Bool, opacity: Double) {
|
||||||
let message = text.text
|
let message = text.text
|
||||||
var font: UIFont
|
var font: UIFont
|
||||||
if let textFont = text.font {
|
if let textFont = text.font {
|
||||||
if let customFont = UIFont(name: textFont.name, size: CGFloat(textFont.size)) {
|
if let customFont = UIFont(name: textFont.name, size: CGFloat(textFont.size)) {
|
||||||
font = customFont
|
font = customFont
|
||||||
} else {
|
} else {
|
||||||
font = UIFont.systemFontOfSize(CGFloat(textFont.size))
|
font = UIFont.systemFont(ofSize: CGFloat(textFont.size))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
font = UIFont.systemFontOfSize(UIFont.systemFontSize())
|
font = UIFont.systemFont(ofSize: UIFont.systemFontSize)
|
||||||
}
|
}
|
||||||
// positive NSBaselineOffsetAttributeName values don't work, couldn't find why
|
// positive NSBaselineOffsetAttributeName values don't work, couldn't find why
|
||||||
// for now move the rect itself
|
// for now move the rect itself
|
||||||
@ -41,25 +41,25 @@ class TextRenderer: NodeRenderer {
|
|||||||
color = RenderUtils.applyOpacity(color, opacity: opacity)
|
color = RenderUtils.applyOpacity(color, opacity: opacity)
|
||||||
let textAttributes = [
|
let textAttributes = [
|
||||||
NSFontAttributeName: font,
|
NSFontAttributeName: font,
|
||||||
NSForegroundColorAttributeName: getTextColor(color)]
|
NSForegroundColorAttributeName: getTextColor(color)] as [String : Any]
|
||||||
let textSize = NSString(string: text.text).sizeWithAttributes(textAttributes)
|
let textSize = NSString(string: text.text).size(attributes: textAttributes)
|
||||||
|
|
||||||
guard let cgContext = ctx.cgContext else {
|
guard let cgContext = ctx.cgContext else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
UIGraphicsPushContext(cgContext)
|
UIGraphicsPushContext(cgContext)
|
||||||
message.drawInRect(CGRectMake(calculateAlignmentOffset(text, font: font), calculateBaselineOffset(text, font: font),
|
message.draw(in: CGRect(x: calculateAlignmentOffset(text, font: font), y: calculateBaselineOffset(text, font: font),
|
||||||
CGFloat(textSize.width), CGFloat(textSize.height)), withAttributes: textAttributes)
|
width: CGFloat(textSize.width), height: CGFloat(textSize.height)), withAttributes: textAttributes)
|
||||||
UIGraphicsPopContext()
|
UIGraphicsPopContext()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func detectTouches(location: CGPoint) -> [Shape] {
|
override func detectTouches(_ location: CGPoint) -> [Shape] {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
private func calculateBaselineOffset(text: Text, font: UIFont) -> CGFloat {
|
fileprivate func calculateBaselineOffset(_ text: Text, font: UIFont) -> CGFloat {
|
||||||
var baselineOffset = CGFloat(0)
|
var baselineOffset = CGFloat(0)
|
||||||
switch text.baseline {
|
switch text.baseline {
|
||||||
case Baseline.alphabetic:
|
case Baseline.alphabetic:
|
||||||
@ -74,11 +74,11 @@ class TextRenderer: NodeRenderer {
|
|||||||
return -baselineOffset
|
return -baselineOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
private func calculateAlignmentOffset(text: Text, font: UIFont) -> CGFloat {
|
fileprivate func calculateAlignmentOffset(_ text: Text, font: UIFont) -> CGFloat {
|
||||||
let textAttributes = [
|
let textAttributes = [
|
||||||
NSFontAttributeName: font
|
NSFontAttributeName: font
|
||||||
]
|
]
|
||||||
let textSize = NSString(string: text.text).sizeWithAttributes(textAttributes)
|
let textSize = NSString(string: text.text).size(attributes: textAttributes)
|
||||||
var alignmentOffset = CGFloat(0)
|
var alignmentOffset = CGFloat(0)
|
||||||
switch text.align {
|
switch text.align {
|
||||||
case Align.mid:
|
case Align.mid:
|
||||||
@ -91,10 +91,10 @@ class TextRenderer: NodeRenderer {
|
|||||||
return -alignmentOffset
|
return -alignmentOffset
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getTextColor(fill: Fill) -> UIColor {
|
fileprivate func getTextColor(_ fill: Fill) -> UIColor {
|
||||||
if let color = fill as? Color {
|
if let color = fill as? Color {
|
||||||
return UIColor(CGColor: RenderUtils.mapColor(color))
|
return UIColor(cgColor: RenderUtils.mapColor(color))
|
||||||
}
|
}
|
||||||
return UIColor.blackColor()
|
return UIColor.black
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,18 +2,18 @@ import Foundation
|
|||||||
|
|
||||||
class SVGParserRegexHelper {
|
class SVGParserRegexHelper {
|
||||||
|
|
||||||
private static let transformAttributePattern = "([a-z]+)\\(((\\-?\\d+\\.?\\d*\\s*,?\\s*)+)\\)"
|
fileprivate static let transformAttributePattern = "([a-z]+)\\(((\\-?\\d+\\.?\\d*\\s*,?\\s*)+)\\)"
|
||||||
private static let transformPattern = "\\-?\\d+\\.?\\d*"
|
fileprivate static let transformPattern = "\\-?\\d+\\.?\\d*"
|
||||||
private static let textElementPattern = "<text.*?>((?s:.*))<\\/text>"
|
fileprivate static let textElementPattern = "<text.*?>((?s:.*))<\\/text>"
|
||||||
|
|
||||||
private static var transformMatcher: NSRegularExpression?
|
fileprivate static var transformMatcher: NSRegularExpression?
|
||||||
private static var transformAttributeMatcher: NSRegularExpression?
|
fileprivate static var transformAttributeMatcher: NSRegularExpression?
|
||||||
private static var textElementMatcher: NSRegularExpression?
|
fileprivate static var textElementMatcher: NSRegularExpression?
|
||||||
|
|
||||||
class func getTransformAttributeMatcher() -> NSRegularExpression? {
|
class func getTransformAttributeMatcher() -> NSRegularExpression? {
|
||||||
if self.transformAttributeMatcher == nil {
|
if self.transformAttributeMatcher == nil {
|
||||||
do {
|
do {
|
||||||
self.transformAttributeMatcher = try NSRegularExpression(pattern: transformAttributePattern, options: .CaseInsensitive)
|
self.transformAttributeMatcher = try NSRegularExpression(pattern: transformAttributePattern, options: .caseInsensitive)
|
||||||
} catch {
|
} catch {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -24,7 +24,7 @@ class SVGParserRegexHelper {
|
|||||||
class func getTransformMatcher() -> NSRegularExpression? {
|
class func getTransformMatcher() -> NSRegularExpression? {
|
||||||
if self.transformMatcher == nil {
|
if self.transformMatcher == nil {
|
||||||
do {
|
do {
|
||||||
self.transformMatcher = try NSRegularExpression(pattern: transformPattern, options: .CaseInsensitive)
|
self.transformMatcher = try NSRegularExpression(pattern: transformPattern, options: .caseInsensitive)
|
||||||
} catch {
|
} catch {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -35,7 +35,7 @@ class SVGParserRegexHelper {
|
|||||||
class func getTextElementMatcher() -> NSRegularExpression? {
|
class func getTextElementMatcher() -> NSRegularExpression? {
|
||||||
if self.textElementMatcher == nil {
|
if self.textElementMatcher == nil {
|
||||||
do {
|
do {
|
||||||
self.textElementMatcher = try NSRegularExpression(pattern: textElementPattern, options: .CaseInsensitive)
|
self.textElementMatcher = try NSRegularExpression(pattern: textElementPattern, options: .caseInsensitive)
|
||||||
} catch {
|
} catch {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
24
Source/thirdparty/CAAnimationClosure.swift
vendored
24
Source/thirdparty/CAAnimationClosure.swift
vendored
@ -17,15 +17,15 @@ class CAAnimationDelegateImpl:NSObject, CAAnimationDelegate {
|
|||||||
var completion: ((Bool) -> Void)?
|
var completion: ((Bool) -> Void)?
|
||||||
|
|
||||||
/// startTime: animation start date
|
/// startTime: animation start date
|
||||||
private var startTime: NSDate!
|
fileprivate var startTime: Date!
|
||||||
private var animationDuration: NSTimeInterval!
|
fileprivate var animationDuration: TimeInterval!
|
||||||
private var animatingTimer: NSTimer!
|
fileprivate var animatingTimer: Timer!
|
||||||
|
|
||||||
/// animating: A block (closure) object to be executed when the animation is animating. This block has no return value and takes a single CGFloat argument that indicates the progress of the animation (From 0 ..< 1)
|
/// animating: A block (closure) object to be executed when the animation is animating. This block has no return value and takes a single CGFloat argument that indicates the progress of the animation (From 0 ..< 1)
|
||||||
var animating: ((CGFloat) -> Void)? {
|
var animating: ((CGFloat) -> Void)? {
|
||||||
willSet {
|
willSet {
|
||||||
if animatingTimer == nil {
|
if animatingTimer == nil {
|
||||||
animatingTimer = NSTimer(timeInterval: 0, target: self, selector: "animationIsAnimating:", userInfo: nil, repeats: true)
|
animatingTimer = Timer(timeInterval: 0, target: self, selector: #selector(CAAnimationDelegateImpl.animationIsAnimating(_:)), userInfo: nil, repeats: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -35,12 +35,12 @@ class CAAnimationDelegateImpl:NSObject, CAAnimationDelegate {
|
|||||||
|
|
||||||
- parameter theAnimation: the animation about to start
|
- parameter theAnimation: the animation about to start
|
||||||
*/
|
*/
|
||||||
func animationDidStart(theAnimation: CAAnimation) {
|
func animationDidStart(_ theAnimation: CAAnimation) {
|
||||||
start?()
|
start?()
|
||||||
if animating != nil {
|
if animating != nil {
|
||||||
animationDuration = theAnimation.duration
|
animationDuration = theAnimation.duration
|
||||||
startTime = NSDate()
|
startTime = Date()
|
||||||
NSRunLoop.currentRunLoop().addTimer(animatingTimer, forMode: NSDefaultRunLoopMode)
|
RunLoop.current.add(animatingTimer, forMode: RunLoopMode.defaultRunLoopMode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ class CAAnimationDelegateImpl:NSObject, CAAnimationDelegate {
|
|||||||
- parameter theAnimation: the animation about to end
|
- parameter theAnimation: the animation about to end
|
||||||
- parameter finished: A Boolean value indicates whether or not the animations actually finished.
|
- parameter finished: A Boolean value indicates whether or not the animations actually finished.
|
||||||
*/
|
*/
|
||||||
func animationDidStop(theAnimation: CAAnimation, finished: Bool) {
|
func animationDidStop(_ theAnimation: CAAnimation, finished: Bool) {
|
||||||
completion?(finished)
|
completion?(finished)
|
||||||
animatingTimer?.invalidate()
|
animatingTimer?.invalidate()
|
||||||
}
|
}
|
||||||
@ -60,8 +60,8 @@ class CAAnimationDelegateImpl:NSObject, CAAnimationDelegate {
|
|||||||
|
|
||||||
- parameter timer: timer
|
- parameter timer: timer
|
||||||
*/
|
*/
|
||||||
func animationIsAnimating(timer: NSTimer) {
|
func animationIsAnimating(_ timer: Timer) {
|
||||||
let progress = CGFloat(NSDate().timeIntervalSinceDate(startTime) / animationDuration)
|
let progress = CGFloat(Date().timeIntervalSince(startTime) / animationDuration)
|
||||||
if progress <= 1.0 {
|
if progress <= 1.0 {
|
||||||
animating?(progress)
|
animating?(progress)
|
||||||
}
|
}
|
||||||
@ -152,8 +152,8 @@ public extension CALayer {
|
|||||||
- parameter key: A string that identifies the animation. Only one animation per unique key is added to the layer. The special key kCATransition is automatically used for transition animations. You may specify nil for this parameter.
|
- parameter key: A string that identifies the animation. Only one animation per unique key is added to the layer. The special key kCATransition is automatically used for transition animations. You may specify nil for this parameter.
|
||||||
- parameter completion: A block object to be executed when the animation ends. This block has no return value and takes a single Boolean argument that indicates whether or not the animations actually finished before the completion handler was called. Default value is nil.
|
- parameter completion: A block object to be executed when the animation ends. This block has no return value and takes a single Boolean argument that indicates whether or not the animations actually finished before the completion handler was called. Default value is nil.
|
||||||
*/
|
*/
|
||||||
func addAnimation(anim: CAAnimation, forKey key: String?, withCompletion completion: ((Bool) -> Void)?) {
|
func addAnimation(_ anim: CAAnimation, forKey key: String?, withCompletion completion: ((Bool) -> Void)?) {
|
||||||
anim.completion = completion
|
anim.completion = completion
|
||||||
addAnimation(anim, forKey: key)
|
add(anim, forKey: key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
Source/thirdparty/NSTimer+Closure.swift
vendored
10
Source/thirdparty/NSTimer+Closure.swift
vendored
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension NSTimer {
|
extension Timer {
|
||||||
/**
|
/**
|
||||||
Creates and schedules a one-time `NSTimer` instance.
|
Creates and schedules a one-time `NSTimer` instance.
|
||||||
|
|
||||||
@ -11,10 +11,10 @@ extension NSTimer {
|
|||||||
|
|
||||||
- Returns: The newly-created `NSTimer` instance.
|
- Returns: The newly-created `NSTimer` instance.
|
||||||
*/
|
*/
|
||||||
class func schedule(delay delay: NSTimeInterval, handler: NSTimer! -> Void) -> NSTimer {
|
class func schedule(delay: TimeInterval, handler: @escaping (Timer!) -> Void) -> Timer {
|
||||||
let fireDate = delay + CFAbsoluteTimeGetCurrent()
|
let fireDate = delay + CFAbsoluteTimeGetCurrent()
|
||||||
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, 0, 0, 0, handler)
|
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, 0, 0, 0, handler)
|
||||||
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes)
|
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
|
||||||
return timer
|
return timer
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,10 +29,10 @@ extension NSTimer {
|
|||||||
|
|
||||||
- Returns: The newly-created `NSTimer` instance.
|
- Returns: The newly-created `NSTimer` instance.
|
||||||
*/
|
*/
|
||||||
class func schedule(repeatInterval interval: NSTimeInterval, handler: NSTimer! -> Void) -> NSTimer {
|
class func schedule(repeatInterval interval: TimeInterval, handler: @escaping (Timer!) -> Void) -> Timer {
|
||||||
let fireDate = interval + CFAbsoluteTimeGetCurrent()
|
let fireDate = interval + CFAbsoluteTimeGetCurrent()
|
||||||
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, interval, 0, 0, handler)
|
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, interval, 0, 0, handler)
|
||||||
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes)
|
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
|
||||||
return timer
|
return timer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,10 @@ import UIKit
|
|||||||
/// MacawView is a main class used to embed Macaw scene into your Cocoa UI.
|
/// MacawView is a main class used to embed Macaw scene into your Cocoa UI.
|
||||||
/// You could create your own view extended from MacawView with predefined scene.
|
/// You could create your own view extended from MacawView with predefined scene.
|
||||||
///
|
///
|
||||||
public class MacawView: UIView {
|
open class MacawView: UIView {
|
||||||
|
|
||||||
/// Scene root node
|
/// Scene root node
|
||||||
public var node: Node = Group() {
|
open var node: Node = Group() {
|
||||||
willSet {
|
willSet {
|
||||||
nodesMap.remove(node)
|
nodesMap.remove(node)
|
||||||
}
|
}
|
||||||
@ -26,7 +26,7 @@ public class MacawView: UIView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override public var frame: CGRect {
|
override open var frame: CGRect {
|
||||||
didSet {
|
didSet {
|
||||||
super.frame = frame
|
super.frame = frame
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ public class MacawView: UIView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func didMoveToSuperview() {
|
override open func didMoveToSuperview() {
|
||||||
super.didMoveToSuperview()
|
super.didMoveToSuperview()
|
||||||
|
|
||||||
if !frameSetFirstTime {
|
if !frameSetFirstTime {
|
||||||
@ -51,7 +51,7 @@ public class MacawView: UIView {
|
|||||||
animationProducer.addStoredAnimations(node)
|
animationProducer.addStoredAnimations(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var selectedShape: Shape? = nil
|
fileprivate var selectedShape: Shape? = nil
|
||||||
|
|
||||||
var context: RenderContext!
|
var context: RenderContext!
|
||||||
var renderer: NodeRenderer?
|
var renderer: NodeRenderer?
|
||||||
@ -86,26 +86,26 @@ public class MacawView: UIView {
|
|||||||
self.init(node: Group(), coder: aDecoder)
|
self.init(node: Group(), coder: aDecoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func drawRect(rect: CGRect) {
|
override open func draw(_ rect: CGRect) {
|
||||||
self.context.cgContext = UIGraphicsGetCurrentContext()
|
self.context.cgContext = UIGraphicsGetCurrentContext()
|
||||||
|
|
||||||
CGContextSaveGState(self.context.cgContext!)
|
self.context.cgContext!.saveGState()
|
||||||
CGContextConcatCTM(self.context.cgContext!, RenderUtils.mapTransform(node.place))
|
self.context.cgContext!.concatenate(RenderUtils.mapTransform(node.place))
|
||||||
renderer?.render(false, opacity: node.opacity)
|
renderer?.render(false, opacity: node.opacity)
|
||||||
CGContextRestoreGState(self.context.cgContext!)
|
self.context.cgContext!.restoreGState()
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
|
open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
self.selectedShape = nil
|
self.selectedShape = nil
|
||||||
if let inverted = node.place.invert() {
|
if let inverted = node.place.invert() {
|
||||||
for touch in touches {
|
for touch in touches {
|
||||||
let location = touch.locationInView(self)
|
let location = touch.location(in: self)
|
||||||
let translatedLocation = CGPointApplyAffineTransform(location, RenderUtils.mapTransform(inverted))
|
let translatedLocation = location.applying(RenderUtils.mapTransform(inverted))
|
||||||
let offsetLocation = CGPoint(x: translatedLocation.x, y: translatedLocation.y)
|
let offsetLocation = CGPoint(x: translatedLocation.x, y: translatedLocation.y)
|
||||||
CGContextSaveGState(self.context.cgContext!)
|
self.context.cgContext!.saveGState()
|
||||||
CGContextConcatCTM(self.context.cgContext!, RenderUtils.mapTransform(node.place))
|
self.context.cgContext!.concatenate(RenderUtils.mapTransform(node.place))
|
||||||
let shapes = renderer?.detectTouches(offsetLocation)
|
let shapes = renderer?.detectTouches(offsetLocation)
|
||||||
CGContextRestoreGState(self.context.cgContext!)
|
self.context.cgContext!.restoreGState()
|
||||||
self.selectedShape = shapes?.first
|
self.selectedShape = shapes?.first
|
||||||
if let shape = self.selectedShape {
|
if let shape = self.selectedShape {
|
||||||
shape.onTap.onNext(TapEvent(location: Point(x: Double(offsetLocation.x), y: Double(offsetLocation.y))))
|
shape.onTap.onNext(TapEvent(location: Point(x: Double(offsetLocation.x), y: Double(offsetLocation.y))))
|
||||||
@ -115,20 +115,20 @@ public class MacawView: UIView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handlePan(recognizer: UIPanGestureRecognizer) {
|
func handlePan(_ recognizer: UIPanGestureRecognizer) {
|
||||||
var translation = recognizer.translationInView(self)
|
let translation = recognizer.translation(in: self)
|
||||||
recognizer.setTranslation(CGPointZero, inView: self)
|
recognizer.setTranslation(CGPoint.zero, in: self)
|
||||||
if let shape = self.selectedShape {
|
if let shape = self.selectedShape {
|
||||||
// get the rotation and scale of the shape and apply to the translation
|
// get the rotation and scale of the shape and apply to the translation
|
||||||
let transform = shape.place
|
let transform = shape.place
|
||||||
let rotation = -CGFloat(atan2f(Float(transform.m12), Float(transform.m11)))
|
let rotation = -CGFloat(atan2f(Float(transform.m12), Float(transform.m11)))
|
||||||
let scale = CGFloat(sqrt(transform.m11 * transform.m11 + transform.m21 * transform.m21))
|
let scale = CGFloat(sqrt(transform.m11 * transform.m11 + transform.m21 * transform.m21))
|
||||||
var translatedLocation = CGPointApplyAffineTransform(translation, CGAffineTransformMakeRotation(rotation))
|
let translatedLocation = translation.applying(CGAffineTransform(rotationAngle: rotation))
|
||||||
shape.onPan.onNext(PanEvent(dx: Double(translatedLocation.x / scale), dy: Double(translatedLocation.y / scale)))
|
shape.onPan.onNext(PanEvent(dx: Double(translatedLocation.x / scale), dy: Double(translatedLocation.y / scale)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleRotation(recognizer: UIRotationGestureRecognizer) {
|
func handleRotation(_ recognizer: UIRotationGestureRecognizer) {
|
||||||
let rotation = Double(recognizer.rotation)
|
let rotation = Double(recognizer.rotation)
|
||||||
recognizer.rotation = 0
|
recognizer.rotation = 0
|
||||||
if let shape = self.selectedShape {
|
if let shape = self.selectedShape {
|
||||||
@ -136,7 +136,7 @@ public class MacawView: UIView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handlePinch(recognizer: UIPinchGestureRecognizer) {
|
func handlePinch(_ recognizer: UIPinchGestureRecognizer) {
|
||||||
let scale = Double(recognizer.scale)
|
let scale = Double(recognizer.scale)
|
||||||
recognizer.scale = 1
|
recognizer.scale = 1
|
||||||
if let shape = self.selectedShape {
|
if let shape = self.selectedShape {
|
||||||
|
@ -8,7 +8,7 @@ class NodesMap {
|
|||||||
var map = [Node: MacawView]()
|
var map = [Node: MacawView]()
|
||||||
|
|
||||||
// MARK: - Macaw View
|
// MARK: - Macaw View
|
||||||
func add(node: Node, view: MacawView) {
|
func add(_ node: Node, view: MacawView) {
|
||||||
map[node] = view
|
map[node] = view
|
||||||
|
|
||||||
if let group = node as? Group {
|
if let group = node as? Group {
|
||||||
@ -19,17 +19,17 @@ class NodesMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getView(node: Node) -> MacawView? {
|
func getView(_ node: Node) -> MacawView? {
|
||||||
return map[node]
|
return map[node]
|
||||||
}
|
}
|
||||||
|
|
||||||
func remove(node: Node) {
|
func remove(_ node: Node) {
|
||||||
map.removeValueForKey(node)
|
map.removeValue(forKey: node)
|
||||||
parentsMap.removeValueForKey(node)
|
parentsMap.removeValue(forKey: node)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Parents
|
// MARK: - Parents
|
||||||
func add(node: Node, parent: Node) {
|
func add(_ node: Node, parent: Node) {
|
||||||
if var nodesSet = parentsMap[node] {
|
if var nodesSet = parentsMap[node] {
|
||||||
nodesSet.insert(parent)
|
nodesSet.insert(parent)
|
||||||
} else {
|
} else {
|
||||||
@ -37,7 +37,7 @@ class NodesMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func parents(node: Node) -> [Node] {
|
func parents(_ node: Node) -> [Node] {
|
||||||
guard let nodesSet = parentsMap[node] else {
|
guard let nodesSet = parentsMap[node] else {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ class ShapeLayer: CAShapeLayer {
|
|||||||
var renderTransform: CGAffineTransform?
|
var renderTransform: CGAffineTransform?
|
||||||
var animationCache: AnimationCache?
|
var animationCache: AnimationCache?
|
||||||
|
|
||||||
override func drawInContext(ctx: CGContext) {
|
override func draw(in ctx: CGContext) {
|
||||||
guard let node = node else {
|
guard let node = node else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -14,15 +14,15 @@ class ShapeLayer: CAShapeLayer {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let renderContext = RenderContext(view: .None)
|
let renderContext = RenderContext(view: .none)
|
||||||
renderContext.cgContext = ctx
|
renderContext.cgContext = ctx
|
||||||
|
|
||||||
if let renderTransform = renderTransform {
|
if let renderTransform = renderTransform {
|
||||||
CGContextConcatCTM(ctx, renderTransform)
|
ctx.concatenate(renderTransform)
|
||||||
}
|
}
|
||||||
|
|
||||||
let renderer = RenderUtils.createNodeRenderer(node, context: renderContext, animationCache: animationCache)
|
let renderer = RenderUtils.createNodeRenderer(node, context: renderContext, animationCache: animationCache)
|
||||||
renderer.render(true, opacity: 1.0)
|
renderer.render(true, opacity: 1.0)
|
||||||
renderer.dispose()
|
renderer.dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user