diff --git a/LotteAnimator.xcodeproj/project.pbxproj b/LotteAnimator.xcodeproj/project.pbxproj index 89eff1863a..cc582a180f 100644 --- a/LotteAnimator.xcodeproj/project.pbxproj +++ b/LotteAnimator.xcodeproj/project.pbxproj @@ -22,8 +22,13 @@ 48372A441C1F84D700AD0293 /* LACompView.m in Sources */ = {isa = PBXBuildFile; fileRef = 48372A431C1F84D700AD0293 /* LACompView.m */; }; 48372A471C1F8B4C00AD0293 /* LAPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 48372A461C1F8B4C00AD0293 /* LAPath.m */; }; 48372A4A1C1F8D7D00AD0293 /* LAMask.m in Sources */ = {isa = PBXBuildFile; fileRef = 48372A491C1F8D7D00AD0293 /* LAMask.m */; }; - 48372A4C1C1F94A200AD0293 /* data.json in Resources */ = {isa = PBXBuildFile; fileRef = 48372A4B1C1F94A200AD0293 /* data.json */; }; 48372A4F1C1F99C600AD0293 /* LAShape.m in Sources */ = {isa = PBXBuildFile; fileRef = 48372A4E1C1F99C600AD0293 /* LAShape.m */; }; + 48372A521C20973300AD0293 /* LAShapeItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 48372A511C20973300AD0293 /* LAShapeItem.m */; }; + 48372A551C209A5F00AD0293 /* LAShapePath.m in Sources */ = {isa = PBXBuildFile; fileRef = 48372A541C209A5F00AD0293 /* LAShapePath.m */; }; + 48372A581C209A6C00AD0293 /* LAShapeStroke.m in Sources */ = {isa = PBXBuildFile; fileRef = 48372A571C209A6C00AD0293 /* LAShapeStroke.m */; }; + 48372A5B1C209A7A00AD0293 /* LAShapeFill.m in Sources */ = {isa = PBXBuildFile; fileRef = 48372A5A1C209A7A00AD0293 /* LAShapeFill.m */; }; + 48372A5E1C209A8900AD0293 /* LAShapeTransform.m in Sources */ = {isa = PBXBuildFile; fileRef = 48372A5D1C209A8900AD0293 /* LAShapeTransform.m */; }; + 48372A611C20A88E00AD0293 /* data.json in Resources */ = {isa = PBXBuildFile; fileRef = 48372A601C20A88E00AD0293 /* data.json */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -55,9 +60,20 @@ 48372A461C1F8B4C00AD0293 /* LAPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAPath.m; sourceTree = ""; }; 48372A481C1F8D7D00AD0293 /* LAMask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAMask.h; sourceTree = ""; }; 48372A491C1F8D7D00AD0293 /* LAMask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAMask.m; sourceTree = ""; }; - 48372A4B1C1F94A200AD0293 /* data.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = data.json; sourceTree = ""; }; 48372A4D1C1F99C600AD0293 /* LAShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAShape.h; sourceTree = ""; }; 48372A4E1C1F99C600AD0293 /* LAShape.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAShape.m; sourceTree = ""; }; + 48372A501C20973300AD0293 /* LAShapeItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAShapeItem.h; sourceTree = ""; }; + 48372A511C20973300AD0293 /* LAShapeItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAShapeItem.m; sourceTree = ""; }; + 48372A531C209A5F00AD0293 /* LAShapePath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAShapePath.h; sourceTree = ""; }; + 48372A541C209A5F00AD0293 /* LAShapePath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAShapePath.m; sourceTree = ""; }; + 48372A561C209A6C00AD0293 /* LAShapeStroke.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAShapeStroke.h; sourceTree = ""; }; + 48372A571C209A6C00AD0293 /* LAShapeStroke.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAShapeStroke.m; sourceTree = ""; }; + 48372A591C209A7A00AD0293 /* LAShapeFill.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAShapeFill.h; sourceTree = ""; }; + 48372A5A1C209A7A00AD0293 /* LAShapeFill.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAShapeFill.m; sourceTree = ""; }; + 48372A5C1C209A8900AD0293 /* LAShapeTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAShapeTransform.h; sourceTree = ""; }; + 48372A5D1C209A8900AD0293 /* LAShapeTransform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAShapeTransform.m; sourceTree = ""; }; + 48372A5F1C209AA200AD0293 /* LAModels.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LAModels.h; sourceTree = ""; }; + 48372A601C20A88E00AD0293 /* data.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = data.json; sourceTree = ""; }; 64D18A4F59FB72C8B3DEBCDE /* Pods-LotteAnimator.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LotteAnimator.release.xcconfig"; path = "Pods/Target Support Files/Pods-LotteAnimator/Pods-LotteAnimator.release.xcconfig"; sourceTree = ""; }; A3DACE6859B88B69187ADCF9 /* Pods-LotteAnimator.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LotteAnimator.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LotteAnimator/Pods-LotteAnimator.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -118,7 +134,7 @@ 4804B3051C1F55E600DA8AF7 /* LaunchScreen.storyboard */, 4804B3081C1F55E600DA8AF7 /* Info.plist */, 4804B31B1C1F738800DA8AF7 /* PrefixHeader.pch */, - 48372A4B1C1F94A200AD0293 /* data.json */, + 48372A601C20A88E00AD0293 /* data.json */, 4804B2F71C1F55E600DA8AF7 /* Supporting Files */, ); path = LotteAnimator; @@ -135,6 +151,7 @@ 4804B3131C1F5B0900DA8AF7 /* Models */ = { isa = PBXGroup; children = ( + 48372A5F1C209AA200AD0293 /* LAModels.h */, 4804B3141C1F5B2000DA8AF7 /* LALayer.h */, 4804B3151C1F5B2000DA8AF7 /* LALayer.m */, 4804B3171C1F6DEA00DA8AF7 /* LAScene.h */, @@ -145,6 +162,16 @@ 48372A491C1F8D7D00AD0293 /* LAMask.m */, 48372A4D1C1F99C600AD0293 /* LAShape.h */, 48372A4E1C1F99C600AD0293 /* LAShape.m */, + 48372A501C20973300AD0293 /* LAShapeItem.h */, + 48372A511C20973300AD0293 /* LAShapeItem.m */, + 48372A531C209A5F00AD0293 /* LAShapePath.h */, + 48372A541C209A5F00AD0293 /* LAShapePath.m */, + 48372A561C209A6C00AD0293 /* LAShapeStroke.h */, + 48372A571C209A6C00AD0293 /* LAShapeStroke.m */, + 48372A591C209A7A00AD0293 /* LAShapeFill.h */, + 48372A5A1C209A7A00AD0293 /* LAShapeFill.m */, + 48372A5C1C209A8900AD0293 /* LAShapeTransform.h */, + 48372A5D1C209A8900AD0293 /* LAShapeTransform.m */, ); name = Models; sourceTree = ""; @@ -231,7 +258,7 @@ 4804B3071C1F55E600DA8AF7 /* LaunchScreen.storyboard in Resources */, 4804B3041C1F55E600DA8AF7 /* Assets.xcassets in Resources */, 4804B3021C1F55E600DA8AF7 /* Main.storyboard in Resources */, - 48372A4C1C1F94A200AD0293 /* data.json in Resources */, + 48372A611C20A88E00AD0293 /* data.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -285,8 +312,13 @@ 4804B32C1C1F835F00DA8AF7 /* LALayerView.m in Sources */, 48372A4A1C1F8D7D00AD0293 /* LAMask.m in Sources */, 4804B3161C1F5B2000DA8AF7 /* LALayer.m in Sources */, + 48372A521C20973300AD0293 /* LAShapeItem.m in Sources */, 48372A4F1C1F99C600AD0293 /* LAShape.m in Sources */, + 48372A581C209A6C00AD0293 /* LAShapeStroke.m in Sources */, + 48372A5B1C209A7A00AD0293 /* LAShapeFill.m in Sources */, 4804B2F91C1F55E600DA8AF7 /* main.m in Sources */, + 48372A551C209A5F00AD0293 /* LAShapePath.m in Sources */, + 48372A5E1C209A8900AD0293 /* LAShapeTransform.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/LotteAnimator.xcworkspace/xcuserdata/brandonwithrow.xcuserdatad/UserInterfaceState.xcuserstate b/LotteAnimator.xcworkspace/xcuserdata/brandonwithrow.xcuserdatad/UserInterfaceState.xcuserstate index 02fe3fd288..698f48fc85 100644 Binary files a/LotteAnimator.xcworkspace/xcuserdata/brandonwithrow.xcuserdatad/UserInterfaceState.xcuserstate and b/LotteAnimator.xcworkspace/xcuserdata/brandonwithrow.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/LotteAnimator.xcworkspace/xcuserdata/brandonwithrow.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/LotteAnimator.xcworkspace/xcuserdata/brandonwithrow.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 65ae7783ca..3e73dcabaf 100644 --- a/LotteAnimator.xcworkspace/xcuserdata/brandonwithrow.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/LotteAnimator.xcworkspace/xcuserdata/brandonwithrow.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -3,19 +3,29 @@ type = "0" version = "2.0"> + + + + @@ -25,45 +35,13 @@ shouldBeEnabled = "Yes" ignoreCount = "0" continueAfterRunningActions = "No" - filePath = "LotteAnimator/LACompView.m" - timestampString = "471828350.46684" + filePath = "LotteAnimator/LAShapeItem.m" + timestampString = "471902261.314685" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "30" - endingLineNumber = "30" - landmarkName = "-_viewtapped" - landmarkType = "5"> - - - - - - - - diff --git a/LotteAnimator/LALayer.m b/LotteAnimator/LALayer.m index acfeff4914..25cefe74e8 100644 --- a/LotteAnimator/LALayer.m +++ b/LotteAnimator/LALayer.m @@ -18,16 +18,21 @@ @"layerID" : @"ind", @"width" : @"width", @"height" : @"height", - @"rotation" : @"", + @"rotation" : @"ks.r", @"positionArray" : @"ks.p", @"anchorPointArray" : @"ks.a", @"scaleArray" : @"ks.s", @"opacity" : @"ks.o", @"color" : @"color", - @"masks" : @"masksProperties" + @"masks" : @"masksProperties", + @"shapes" : @"shapes" }; } ++ (NSValueTransformer *)shapesJSONTransformer { + return [MTLJSONAdapter arrayTransformerWithModelClass:[LAShape class]]; +} + + (NSValueTransformer *)masksJSONTransformer { return [MTLJSONAdapter arrayTransformerWithModelClass:[LAMask class]]; } diff --git a/LotteAnimator/LALayerView.h b/LotteAnimator/LALayerView.h index 5d7bfd4fd6..da988306ea 100644 --- a/LotteAnimator/LALayerView.h +++ b/LotteAnimator/LALayerView.h @@ -7,6 +7,7 @@ // #import +#import "LAModels.h" @interface LALayerView : UIView diff --git a/LotteAnimator/LALayerView.m b/LotteAnimator/LALayerView.m index a857097c82..064f642a0c 100644 --- a/LotteAnimator/LALayerView.m +++ b/LotteAnimator/LALayerView.m @@ -20,6 +20,7 @@ self.alpha = model.alpha; _layerModel = model; if (model.masks) { + self.clipsToBounds = NO; LAMask *maskModel = model.masks.firstObject; UIBezierPath *myClippingPath = [maskModel.maskPath bezierPath:maskModel.isClosed]; @@ -29,6 +30,47 @@ self.layer.mask = mask; } + if (model.shapes) { + self.clipsToBounds = NO; + for (LAShape *shape in model.shapes) { + // Get Path + LAShapePath *path = shape.paths.count ? shape.paths.firstObject : nil; + + // Get Stroke + LAShapeStroke *stroke = shape.strokes.count ? shape.strokes.firstObject : nil; + + //Get Fill + LAShapeFill *fill = shape.fills.count ? shape.fills.firstObject : nil; + + //Get Transform + LAShapeTransform *transform = shape.transforms.count ? shape.transforms.firstObject : nil; + + if (!path) { + continue; + } + UIBezierPath *shapePath = [path.shapePath bezierPath:path.isClosed]; + CAShapeLayer *shapeLayer = [CAShapeLayer layer]; + shapeLayer.path = shapePath.CGPath; + + if (stroke) { + shapeLayer.strokeColor = stroke.color.CGColor; + shapeLayer.lineWidth = stroke.width.floatValue; + } + + if (fill) { + shapeLayer.fillColor = fill.color.CGColor; + shapeLayer.opacity = fill.alpha; + } + + if (transform) { +// shapeLayer.anchorPoint = transform.anchorPoint; +// shapeLayer.position = +// shapeLayer.transform = CATransform3DMakeAffineTransform(transform.transform); + } + [self.layer addSublayer:shapeLayer]; + } + } + UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_viewtapped)]; [self addGestureRecognizer:tapGesture]; } diff --git a/LotteAnimator/LAModels.h b/LotteAnimator/LAModels.h new file mode 100644 index 0000000000..9dc8920b58 --- /dev/null +++ b/LotteAnimator/LAModels.h @@ -0,0 +1,23 @@ +// +// LAModels.h +// LotteAnimator +// +// Created by Brandon Withrow on 12/15/15. +// Copyright © 2015 Brandon Withrow. All rights reserved. +// + +#ifndef LAModels_h +#define LAModels_h + +#import "LAPath.h" +#import "LAMask.h" +#import "LAScene.h" +#import "LALayer.h" +#import "LAShape.h" +#import "LAShapeItem.h" +#import "LAShapePath.h" +#import "LAShapeStroke.h" +#import "LAShapeFill.h" +#import "LAShapeTransform.h" + +#endif /* LAModels_h */ diff --git a/LotteAnimator/LAShape.h b/LotteAnimator/LAShape.h index f434adfa1a..8f16780bde 100644 --- a/LotteAnimator/LAShape.h +++ b/LotteAnimator/LAShape.h @@ -10,20 +10,11 @@ @interface LAShape : MTLModel -@property (nonatomic, getter=isClosed) BOOL closed; -@property (nonatomic, strong) LAPath *shapePath; +@property (nonatomic, copy) NSArray *shapeItems; -@property (nonatomic, strong) NSNumber *strokeWidth; -@property (nonatomic, strong) NSNumber *strokeOpacity; -@property (nonatomic, strong) NSArray *strokeColorElements; - -@property (nonatomic, strong) NSNumber *fillOpacity; -@property (nonatomic, strong) NSArray *fillColorElements; - -@property (nonatomic, copy) NSArray *positionArray; -@property (nonatomic, copy) NSArray *anchorPointArray; -@property (nonatomic, copy) NSArray *scaleArray; -@property (nonatomic, copy) NSNumber *rotation; -@property (nonatomic, copy) NSNumber *opacity; +@property (nonatomic, readonly) NSArray *paths; +@property (nonatomic, readonly) NSArray *strokes; +@property (nonatomic, readonly) NSArray *fills; +@property (nonatomic, readonly) NSArray *transforms; @end diff --git a/LotteAnimator/LAShape.m b/LotteAnimator/LAShape.m index b2981f0fe4..a9f3b079e5 100644 --- a/LotteAnimator/LAShape.m +++ b/LotteAnimator/LAShape.m @@ -7,7 +7,77 @@ // #import "LAShape.h" +#import "LAShapeItem.h" @implementation LAShape ++ (NSDictionary *)JSONKeyPathsByPropertyKey { + return @{@"shapeItems" : @"it"}; +} + ++ (NSValueTransformer *)shapeItemsJSONTransformer { + // tell Mantle to populate diaAttributes property with an array of MDAttribute objects + return [MTLJSONAdapter arrayTransformerWithModelClass:[LAShapeItem class]]; +} + +- (NSArray *)paths { + if (!self.shapeItems) { + return @[]; + } + NSMutableArray *paths = [NSMutableArray array]; + + for (LAShapeItem *item in self.shapeItems) { + if ([item.itemType isEqualToString:LAShapeItemType.Path]) { + [paths addObject:item]; + } + } + + return paths; +} + +- (NSArray *)strokes { + if (!self.shapeItems) { + return @[]; + } + NSMutableArray *strokes = [NSMutableArray array]; + + for (LAShapeItem *item in self.shapeItems) { + if ([item.itemType isEqualToString:LAShapeItemType.Stroke]) { + [strokes addObject:item]; + } + } + + return strokes; +} + +- (NSArray *)fills { + if (!self.shapeItems) { + return @[]; + } + NSMutableArray *fills = [NSMutableArray array]; + + for (LAShapeItem *item in self.shapeItems) { + if ([item.itemType isEqualToString:LAShapeItemType.Fill]) { + [fills addObject:item]; + } + } + + return fills; +} + +- (NSArray *)transforms { + if (!self.shapeItems) { + return @[]; + } + NSMutableArray *transforms = [NSMutableArray array]; + + for (LAShapeItem *item in self.shapeItems) { + if ([item.itemType isEqualToString:LAShapeItemType.Transform]) { + [transforms addObject:item]; + } + } + + return transforms; +} + @end diff --git a/LotteAnimator/LAShapeFill.h b/LotteAnimator/LAShapeFill.h new file mode 100644 index 0000000000..72cb5d0fd4 --- /dev/null +++ b/LotteAnimator/LAShapeFill.h @@ -0,0 +1,19 @@ +// +// LAShapeFill.h +// LotteAnimator +// +// Created by Brandon Withrow on 12/15/15. +// Copyright © 2015 Brandon Withrow. All rights reserved. +// + +#import "LAShapeItem.h" + +@interface LAShapeFill : LAShapeItem + +@property (nonatomic, getter=isFillEnabled) BOOL fillEnabled; +@property (nonatomic, copy) NSArray *colorElements; +@property (nonatomic, copy) NSNumber *opacity; + +@property (nonatomic, readonly) UIColor *color; +@property (nonatomic, readonly) CGFloat alpha; +@end diff --git a/LotteAnimator/LAShapeFill.m b/LotteAnimator/LAShapeFill.m new file mode 100644 index 0000000000..e779f5086f --- /dev/null +++ b/LotteAnimator/LAShapeFill.m @@ -0,0 +1,41 @@ +// +// LAShapeFill.m +// LotteAnimator +// +// Created by Brandon Withrow on 12/15/15. +// Copyright © 2015 Brandon Withrow. All rights reserved. +// + +#import "LAShapeFill.h" + +@implementation LAShapeFill + ++ (NSDictionary *)JSONKeyPathsByPropertyKey { + return @{@"itemType" : @"ty", + @"fillEnabled" : @"fillEnabled", + @"colorElements" : @"c", + @"opacity" : @"o"}; +} + ++ (NSValueTransformer *)fillEnabledJSONTransformer { + return [NSValueTransformer valueTransformerForName:MTLBooleanValueTransformerName]; +} + +- (CGFloat)alpha { + if (!self.opacity) { + return 1; + } + return self.opacity.floatValue / 100.f; +} + +- (UIColor *)color { + if (!self.colorElements) { + return [UIColor clearColor]; + } + return [UIColor colorWithRed:([self.colorElements[0] floatValue]/255.f) + green:([self.colorElements[1] floatValue]/255.f) + blue:([self.colorElements[2] floatValue]/255.f) + alpha:([self.colorElements[3] floatValue]/255.f)]; +} + +@end diff --git a/LotteAnimator/LAShapeItem.h b/LotteAnimator/LAShapeItem.h new file mode 100644 index 0000000000..fc43958fd9 --- /dev/null +++ b/LotteAnimator/LAShapeItem.h @@ -0,0 +1,24 @@ +// +// LAShapeItem.h +// LotteAnimator +// +// Created by Brandon Withrow on 12/15/15. +// Copyright © 2015 Brandon Withrow. All rights reserved. +// + +#import "MTLModel.h" + +struct LAShapeItemType { + __unsafe_unretained NSString * const Path; + __unsafe_unretained NSString * const Stroke; + __unsafe_unretained NSString * const Fill; + __unsafe_unretained NSString * const Transform; +}; + +extern const struct LAShapeItemType LAShapeItemType; + +@interface LAShapeItem : MTLModel + +@property (nonatomic, copy) NSString *itemType; + +@end diff --git a/LotteAnimator/LAShapeItem.m b/LotteAnimator/LAShapeItem.m new file mode 100644 index 0000000000..f64133ea72 --- /dev/null +++ b/LotteAnimator/LAShapeItem.m @@ -0,0 +1,44 @@ +// +// LAShapeItem.m +// LotteAnimator +// +// Created by Brandon Withrow on 12/15/15. +// Copyright © 2015 Brandon Withrow. All rights reserved. +// + +#import "LAShapeItem.h" + +const struct LAShapeItemType LAShapeItemType = { + .Path = @"sh", + .Stroke = @"st", + .Fill = @"fl", + .Transform = @"tr" +}; + +@implementation LAShapeItem + ++ (NSDictionary *)JSONKeyPathsByPropertyKey { + return @{@"itemType" : @"ty"}; +} + ++ (Class)classForParsingJSONDictionary:(NSDictionary *)JSONDictionary { + if ([JSONDictionary[@"ty"] isEqual:LAShapeItemType.Path]) { + return LAShapePath.class; + } + + if ([JSONDictionary[@"ty"] isEqual:LAShapeItemType.Stroke]) { + return LAShapeStroke.class; + } + + if ([JSONDictionary[@"ty"] isEqual:LAShapeItemType.Fill]) { + return LAShapeFill.class; + } + + if ([JSONDictionary[@"ty"] isEqual:LAShapeItemType.Transform]) { + return LAShapeTransform.class; + } + + return self; +} + +@end diff --git a/LotteAnimator/LAShapePath.h b/LotteAnimator/LAShapePath.h new file mode 100644 index 0000000000..5410460dfe --- /dev/null +++ b/LotteAnimator/LAShapePath.h @@ -0,0 +1,16 @@ +// +// LAShapePath.h +// LotteAnimator +// +// Created by Brandon Withrow on 12/15/15. +// Copyright © 2015 Brandon Withrow. All rights reserved. +// + +#import "LAShapeItem.h" + +@interface LAShapePath : LAShapeItem + +@property (nonatomic, getter=isClosed) BOOL closed; +@property (nonatomic, strong) LAPath *shapePath; + +@end diff --git a/LotteAnimator/LAShapePath.m b/LotteAnimator/LAShapePath.m new file mode 100644 index 0000000000..a5d1ff1fdc --- /dev/null +++ b/LotteAnimator/LAShapePath.m @@ -0,0 +1,28 @@ +// +// LAShapePath.m +// LotteAnimator +// +// Created by Brandon Withrow on 12/15/15. +// Copyright © 2015 Brandon Withrow. All rights reserved. +// + +#import "LAShapePath.h" + +@implementation LAShapePath + ++ (NSDictionary *)JSONKeyPathsByPropertyKey { + return @{@"itemType" : @"ty", + @"closed" : @"closed", + @"shapePath" : @"ks"}; +} + ++ (NSValueTransformer *)shapePathJSONTransformer { + // tell Mantle to populate diaAttributes property with an array of MDAttribute objects + return [MTLJSONAdapter dictionaryTransformerWithModelClass:[LAPath class]]; +} + ++ (NSValueTransformer *)closedJSONTransformer { + return [NSValueTransformer valueTransformerForName:MTLBooleanValueTransformerName]; +} + +@end diff --git a/LotteAnimator/LAShapeStroke.h b/LotteAnimator/LAShapeStroke.h new file mode 100644 index 0000000000..49d01f4de7 --- /dev/null +++ b/LotteAnimator/LAShapeStroke.h @@ -0,0 +1,21 @@ +// +// LAShapeStroke.h +// LotteAnimator +// +// Created by Brandon Withrow on 12/15/15. +// Copyright © 2015 Brandon Withrow. All rights reserved. +// + +#import "LAShapeItem.h" + +@interface LAShapeStroke : LAShapeItem + +@property (nonatomic, getter=isFillEnabled) BOOL fillEnabled; +@property (nonatomic, copy) NSArray *colorElements; +@property (nonatomic, copy) NSNumber *opacity; +@property (nonatomic, copy) NSNumber *width; + +@property (nonatomic, readonly) UIColor *color; +@property (nonatomic, readonly) CGFloat alpha; + +@end diff --git a/LotteAnimator/LAShapeStroke.m b/LotteAnimator/LAShapeStroke.m new file mode 100644 index 0000000000..d0ddb31c87 --- /dev/null +++ b/LotteAnimator/LAShapeStroke.m @@ -0,0 +1,42 @@ +// +// LAShapeStroke.m +// LotteAnimator +// +// Created by Brandon Withrow on 12/15/15. +// Copyright © 2015 Brandon Withrow. All rights reserved. +// + +#import "LAShapeStroke.h" + +@implementation LAShapeStroke + ++ (NSDictionary *)JSONKeyPathsByPropertyKey { + return @{@"itemType" : @"ty", + @"fillEnabled" : @"fillEnabled", + @"colorElements" : @"c", + @"opacity" : @"o", + @"width" : @"w"}; +} + ++ (NSValueTransformer *)fillEnabledJSONTransformer { + return [NSValueTransformer valueTransformerForName:MTLBooleanValueTransformerName]; +} + +- (CGFloat)alpha { + if (!self.opacity) { + return 1; + } + return self.opacity.floatValue / 100.f; +} + +- (UIColor *)color { + if (!self.colorElements) { + return [UIColor clearColor]; + } + return [UIColor colorWithRed:([self.colorElements[0] floatValue]/255.f) + green:([self.colorElements[1] floatValue]/255.f) + blue:([self.colorElements[2] floatValue]/255.f) + alpha:([self.colorElements[3] floatValue]/255.f)]; +} + +@end diff --git a/LotteAnimator/LAShapeTransform.h b/LotteAnimator/LAShapeTransform.h new file mode 100644 index 0000000000..60a5393220 --- /dev/null +++ b/LotteAnimator/LAShapeTransform.h @@ -0,0 +1,25 @@ +// +// LAShapeTransform.h +// LotteAnimator +// +// Created by Brandon Withrow on 12/15/15. +// Copyright © 2015 Brandon Withrow. All rights reserved. +// + +#import "LAShapeItem.h" + +@interface LAShapeTransform : LAShapeItem + +@property (nonatomic, copy) NSArray *positionArray; +@property (nonatomic, copy) NSArray *anchorPointArray; +@property (nonatomic, copy) NSArray *scaleArray; +@property (nonatomic, copy) NSNumber *rotation; +@property (nonatomic, copy) NSNumber *opacity; + +@property (nonatomic, readonly) CGPoint position; +@property (nonatomic, readonly) CGPoint anchorPoint; +@property (nonatomic, readonly) CGSize scale; +@property (nonatomic, readonly) CGFloat alpha; +@property (nonatomic, readonly) CGAffineTransform transform; + +@end diff --git a/LotteAnimator/LAShapeTransform.m b/LotteAnimator/LAShapeTransform.m new file mode 100644 index 0000000000..a9a786b6fc --- /dev/null +++ b/LotteAnimator/LAShapeTransform.m @@ -0,0 +1,63 @@ +// +// LAShapeTransform.m +// LotteAnimator +// +// Created by Brandon Withrow on 12/15/15. +// Copyright © 2015 Brandon Withrow. All rights reserved. +// + +#import "LAShapeTransform.h" + +@implementation LAShapeTransform + ++ (NSDictionary *)JSONKeyPathsByPropertyKey { + return @{@"itemType" : @"ty", + @"positionArray" : @"p", + @"anchorPointArray" : @"a", + @"scaleArray" : @"s", + @"rotation" : @"r", + @"opacity" : @"o"}; +} + +- (CGPoint)position { + if (!self.positionArray) { + return CGPointZero; + } + CGPoint aePosition = CGPointMake([self.positionArray[0] floatValue], [self.positionArray[1] floatValue]); + if (self.anchorPointArray) { + aePosition.x -= [self.anchorPointArray[0] floatValue]; + aePosition.y -= [self.anchorPointArray[1] floatValue]; + } + return aePosition; +} + +- (CGPoint)anchorPoint { + if (!self.anchorPointArray) { + return CGPointZero; + } + CGPoint aeAnchorPoint = CGPointMake([self.anchorPointArray[0] floatValue], [self.anchorPointArray[1] floatValue]); +// CGPoint uikitAnchorPoint = CGPointMake(aeAnchorPoint.x / self.size.width, +// aeAnchorPoint.y / self.size.height); + // TODO Figure out this crazy thing + return aeAnchorPoint; +} + +- (CGSize)scale { + if (!self.scaleArray) { + return CGSizeZero; + } + return CGSizeMake([self.scaleArray[0] floatValue] / 100.f, [self.scaleArray[1] floatValue] / 100.f); +} + +- (CGFloat)alpha { + if (!self.opacity) { + return 1; + } + return self.opacity.floatValue / 100.f; +} + +- (CGAffineTransform)transform { + return CGAffineTransformRotate(CGAffineTransformMakeScale(self.scale.width, self.scale.height), DegreesToRadians(self.rotation ? self.rotation.floatValue : 0.f)); +} + +@end diff --git a/LotteAnimator/data.json b/LotteAnimator/data.json index 044cb470c4..1b546c24b8 100644 --- a/LotteAnimator/data.json +++ b/LotteAnimator/data.json @@ -1 +1 @@ -{"animation":{"layers":[{"ind":0,"type":"SolidLayer","layerName":"SquareLayer","threeD":false,"an":{},"width":150,"height":150,"color":"#f62fec","inPoint":0,"outPoint":121,"startTime":0,"ks":{"o":100,"r":0,"p":[228,200.5,0],"a":[75,75,0],"s":[100,100,100]}},{"ind":1,"type":"ShapeLayer","shapes":[{"ty":"gr","it":[{"ty":"sh","closed":true,"ks":{"i":[[92,36],[52,-72],[0,0],[0,44]],"o":[[-92,-36],[-52,72],[0,0],[0,-44]],"v":[[8,-256.5],[-92,-192.5],[-116,-76.5],[-48,-152.5]]}},{"ty":"st","fillEnabled":true,"c":[255,255,255,255],"o":100,"w":2},{"ty":"fl","fillEnabled":true,"c":[255,0,0,255],"o":100},{"ty":"tr","p":[0,0],"a":[0,0],"s":[100,100],"r":0,"o":100}]}],"rectData":{"l":0,"t":0,"b":0,"r":0,"w":0,"h":0},"layerName":"ShapeLayer","threeD":false,"an":{},"width":320,"height":585,"inPoint":0,"outPoint":121,"startTime":0,"ks":{"o":100,"r":0,"p":[210,312.5,0],"a":[0,0,0],"s":[100,100,100]}},{"ind":2,"masksProperties":[{"cl":true,"inv":false,"mode":"a","pt":{"i":[[84,0],[122,-80],[-76,136],[-75.735,21.822]],"o":[[-84,0],[-63.862,41.877],[46.831,-83.802],[118,-34]],"v":[[144,164],[144,428],[250,402],[260,200]]},"o":100}],"hasMask":true,"type":"SolidLayer","layerName":"PathLayer","threeD":false,"an":{},"width":320,"height":585,"color":"#3df673","inPoint":0,"outPoint":121,"startTime":0,"ks":{"o":100,"r":0,"p":[152,366.5,0],"a":[160,292.5,0],"s":[100,100,100]}},{"ind":3,"type":"NullLayer","layerName":"Null 1","threeD":false,"an":{},"inPoint":0,"outPoint":121,"startTime":0,"ks":{"o":0,"r":0,"p":[92,36,0],"a":[0,0,0],"s":[100,100,100]}}],"totalFrames":86,"frameRate":24,"ff":1.45833333333333,"compWidth":320,"compHeight":585},"assets":[],"v":"2.0.6"} \ No newline at end of file +{"animation":{"layers":[{"ind":0,"type":"SolidLayer","layerName":"SquareLayer","threeD":false,"an":{},"width":150,"height":150,"color":"#f62fec","inPoint":0,"outPoint":121,"startTime":0,"ks":{"o":100,"r":0,"p":[228,200.5,0],"a":[75,75,0],"s":[100,100,100]}},{"ind":1,"type":"ShapeLayer","shapes":[{"ty":"gr","it":[{"ty":"sh","closed":true,"ks":{"i":[[92,36],[52,-72],[0,0],[0,44]],"o":[[-92,-36],[-52,72],[0,0],[0,-44]],"v":[[8,-256.5],[-92,-192.5],[-116,-76.5],[-48,-152.5]]}},{"ty":"st","fillEnabled":true,"c":[255,0,0,255],"o":100,"w":2},{"ty":"fl","fillEnabled":true,"c":[255,0,0,255],"o":100},{"ty":"tr","p":[0,0],"a":[0,0],"s":[100,100],"r":0,"o":100}]}],"rectData":{"l":0,"t":0,"b":0,"r":0,"w":0,"h":0},"layerName":"ShapeLayer","threeD":false,"an":{},"width":320,"height":585,"inPoint":0,"outPoint":121,"startTime":0,"ks":{"o":100,"r":0,"p":[146,334.5,0],"a":[0,0,0],"s":[100,100,100]}},{"ind":2,"masksProperties":[{"cl":true,"inv":false,"mode":"a","pt":{"i":[[84,0],[122,-80],[-76,136],[-75.735,21.822]],"o":[[-84,0],[-63.862,41.877],[46.831,-83.802],[118,-34]],"v":[[144,164],[144,428],[250,402],[260,200]]},"o":100}],"hasMask":true,"type":"SolidLayer","layerName":"PathLayer","threeD":false,"an":{},"width":320,"height":585,"color":"#3df673","inPoint":0,"outPoint":121,"startTime":0,"ks":{"o":100,"r":0,"p":[152,366.5,0],"a":[160,292.5,0],"s":[100,100,100]}},{"ind":3,"type":"NullLayer","layerName":"Null 1","threeD":false,"an":{},"inPoint":0,"outPoint":121,"startTime":0,"ks":{"o":0,"r":0,"p":[92,36,0],"a":[0,0,0],"s":[100,100,100]}}],"totalFrames":86,"frameRate":24,"ff":1.45833333333333,"compWidth":320,"compHeight":585},"assets":[],"v":"2.0.6"} \ No newline at end of file diff --git a/PrefixHeader.pch b/PrefixHeader.pch index a9c2580114..8eda0a27b5 100644 --- a/PrefixHeader.pch +++ b/PrefixHeader.pch @@ -16,11 +16,8 @@ #import #import "UIColor+Expanded.h" #import "BWMath.h" -#import "LAScene.h" -#import "LALayer.h" #import "LALayerView.h" #import "LACompView.h" -#import "LAPath.h" -#import "LAMask.h" +#import "LAModels.h" #endif /* PrefixHeader_pch */