mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-01-24 04:58:59 +00:00
Updated Animated properties. Started removing mantle
This commit is contained in:
@@ -17,10 +17,8 @@
|
||||
4804B3191C1F6DEA00DA8AF7 /* LAComposition.m in Sources */ = {isa = PBXBuildFile; fileRef = 4804B3181C1F6DEA00DA8AF7 /* LAComposition.m */; };
|
||||
4804B31E1C1F757600DA8AF7 /* UIColor+Expanded.m in Sources */ = {isa = PBXBuildFile; fileRef = 4804B31D1C1F757600DA8AF7 /* UIColor+Expanded.m */; };
|
||||
4804B3211C1F761800DA8AF7 /* BWMath.m in Sources */ = {isa = PBXBuildFile; fileRef = 4804B3201C1F761800DA8AF7 /* BWMath.m */; };
|
||||
48372A471C1F8B4C00AD0293 /* LAPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 48372A461C1F8B4C00AD0293 /* LAPath.m */; };
|
||||
48372A4A1C1F8D7D00AD0293 /* LAMask.m in Sources */ = {isa = PBXBuildFile; fileRef = 48372A491C1F8D7D00AD0293 /* LAMask.m */; };
|
||||
48372A4F1C1F99C600AD0293 /* LAShape.m in Sources */ = {isa = PBXBuildFile; fileRef = 48372A4E1C1F99C600AD0293 /* LAShape.m */; };
|
||||
48372A521C20973300AD0293 /* LAShapeItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 48372A511C20973300AD0293 /* LAShapeItem.m */; };
|
||||
48372A4F1C1F99C600AD0293 /* LAShapeGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 48372A4E1C1F99C600AD0293 /* LAShapeGroup.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 */; };
|
||||
@@ -76,6 +74,10 @@
|
||||
620A565F1D1C81750030EBFB /* LAAnimatablePointValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 620A565E1D1C81750030EBFB /* LAAnimatablePointValue.m */; };
|
||||
620A56621D1C81850030EBFB /* LAAnimatableNumberValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 620A56611D1C81850030EBFB /* LAAnimatableNumberValue.m */; };
|
||||
620A56651D1C81930030EBFB /* LAAnimatableShapeValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 620A56641D1C81930030EBFB /* LAAnimatableShapeValue.m */; };
|
||||
620CD7CD1D3415F000055AD1 /* LAAnimatableRectValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 620CD7CC1D3415F000055AD1 /* LAAnimatableRectValue.m */; };
|
||||
620CD7D01D343A2500055AD1 /* LAAnimatableScaleValue.m in Sources */ = {isa = PBXBuildFile; fileRef = 620CD7CF1D343A2500055AD1 /* LAAnimatableScaleValue.m */; };
|
||||
620CD7D11D35AB9C00055AD1 /* LALayerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4804B32B1C1F835F00DA8AF7 /* LALayerView.m */; };
|
||||
620CD7D21D35AB9F00055AD1 /* LACompView.m in Sources */ = {isa = PBXBuildFile; fileRef = 48372A431C1F84D700AD0293 /* LACompView.m */; };
|
||||
629737DF1D25D7FC007B4AC9 /* allHold_KeyTest.json in Resources */ = {isa = PBXBuildFile; fileRef = 629737DB1D25D7FC007B4AC9 /* allHold_KeyTest.json */; };
|
||||
629737E01D25D7FC007B4AC9 /* firstHold_KeyTest.json in Resources */ = {isa = PBXBuildFile; fileRef = 629737DC1D25D7FC007B4AC9 /* firstHold_KeyTest.json */; };
|
||||
629737E11D25D7FC007B4AC9 /* lastHold_KeyTest.json in Resources */ = {isa = PBXBuildFile; fileRef = 629737DD1D25D7FC007B4AC9 /* lastHold_KeyTest.json */; };
|
||||
@@ -109,14 +111,10 @@
|
||||
4804B32B1C1F835F00DA8AF7 /* LALayerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LALayerView.m; sourceTree = "<group>"; };
|
||||
48372A421C1F84D700AD0293 /* LACompView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LACompView.h; sourceTree = "<group>"; };
|
||||
48372A431C1F84D700AD0293 /* LACompView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LACompView.m; sourceTree = "<group>"; };
|
||||
48372A451C1F8B4C00AD0293 /* LAPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAPath.h; sourceTree = "<group>"; };
|
||||
48372A461C1F8B4C00AD0293 /* LAPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAPath.m; sourceTree = "<group>"; };
|
||||
48372A481C1F8D7D00AD0293 /* LAMask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAMask.h; sourceTree = "<group>"; };
|
||||
48372A491C1F8D7D00AD0293 /* LAMask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAMask.m; sourceTree = "<group>"; };
|
||||
48372A4D1C1F99C600AD0293 /* LAShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAShape.h; sourceTree = "<group>"; };
|
||||
48372A4E1C1F99C600AD0293 /* LAShape.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAShape.m; sourceTree = "<group>"; };
|
||||
48372A501C20973300AD0293 /* LAShapeItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAShapeItem.h; sourceTree = "<group>"; };
|
||||
48372A511C20973300AD0293 /* LAShapeItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAShapeItem.m; sourceTree = "<group>"; };
|
||||
48372A4D1C1F99C600AD0293 /* LAShapeGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAShapeGroup.h; sourceTree = "<group>"; };
|
||||
48372A4E1C1F99C600AD0293 /* LAShapeGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAShapeGroup.m; sourceTree = "<group>"; };
|
||||
48372A531C209A5F00AD0293 /* LAShapePath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAShapePath.h; sourceTree = "<group>"; };
|
||||
48372A541C209A5F00AD0293 /* LAShapePath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAShapePath.m; sourceTree = "<group>"; };
|
||||
48372A561C209A6C00AD0293 /* LAShapeStroke.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAShapeStroke.h; sourceTree = "<group>"; };
|
||||
@@ -176,7 +174,6 @@
|
||||
4872BEDB1D146D850028E0B3 /* animatedTransformHold.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = animatedTransformHold.json; sourceTree = "<group>"; };
|
||||
4872BEDD1D146D850028E0B3 /* animatedTransform.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = animatedTransform.json; sourceTree = "<group>"; };
|
||||
488990EC1D08A2A400425189 /* curve.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = curve.json; sourceTree = "<group>"; };
|
||||
620A56451D1B2D3D0030EBFB /* LAAnimatableValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = LAAnimatableValue.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
620A56481D1B3B150030EBFB /* FullLayerModel_Animation.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = FullLayerModel_Animation.json; sourceTree = "<group>"; };
|
||||
620A565A1D1C81610030EBFB /* LAAnimatableColorValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAAnimatableColorValue.h; sourceTree = "<group>"; };
|
||||
620A565B1D1C81610030EBFB /* LAAnimatableColorValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAAnimatableColorValue.m; sourceTree = "<group>"; };
|
||||
@@ -186,6 +183,10 @@
|
||||
620A56611D1C81850030EBFB /* LAAnimatableNumberValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAAnimatableNumberValue.m; sourceTree = "<group>"; };
|
||||
620A56631D1C81930030EBFB /* LAAnimatableShapeValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAAnimatableShapeValue.h; sourceTree = "<group>"; };
|
||||
620A56641D1C81930030EBFB /* LAAnimatableShapeValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAAnimatableShapeValue.m; sourceTree = "<group>"; };
|
||||
620CD7CB1D3415F000055AD1 /* LAAnimatableRectValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAAnimatableRectValue.h; sourceTree = "<group>"; };
|
||||
620CD7CC1D3415F000055AD1 /* LAAnimatableRectValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAAnimatableRectValue.m; sourceTree = "<group>"; };
|
||||
620CD7CE1D343A2500055AD1 /* LAAnimatableScaleValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAAnimatableScaleValue.h; sourceTree = "<group>"; };
|
||||
620CD7CF1D343A2500055AD1 /* LAAnimatableScaleValue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAAnimatableScaleValue.m; sourceTree = "<group>"; };
|
||||
629737DB1D25D7FC007B4AC9 /* allHold_KeyTest.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = allHold_KeyTest.json; sourceTree = "<group>"; };
|
||||
629737DC1D25D7FC007B4AC9 /* firstHold_KeyTest.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = firstHold_KeyTest.json; sourceTree = "<group>"; };
|
||||
629737DD1D25D7FC007B4AC9 /* lastHold_KeyTest.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = lastHold_KeyTest.json; sourceTree = "<group>"; };
|
||||
@@ -281,14 +282,10 @@
|
||||
4804B3181C1F6DEA00DA8AF7 /* LAComposition.m */,
|
||||
4804B3141C1F5B2000DA8AF7 /* LALayer.h */,
|
||||
4804B3151C1F5B2000DA8AF7 /* LALayer.m */,
|
||||
48372A451C1F8B4C00AD0293 /* LAPath.h */,
|
||||
48372A461C1F8B4C00AD0293 /* LAPath.m */,
|
||||
48372A481C1F8D7D00AD0293 /* LAMask.h */,
|
||||
48372A491C1F8D7D00AD0293 /* LAMask.m */,
|
||||
48372A4D1C1F99C600AD0293 /* LAShape.h */,
|
||||
48372A4E1C1F99C600AD0293 /* LAShape.m */,
|
||||
48372A501C20973300AD0293 /* LAShapeItem.h */,
|
||||
48372A511C20973300AD0293 /* LAShapeItem.m */,
|
||||
48372A4D1C1F99C600AD0293 /* LAShapeGroup.h */,
|
||||
48372A4E1C1F99C600AD0293 /* LAShapeGroup.m */,
|
||||
48372A561C209A6C00AD0293 /* LAShapeStroke.h */,
|
||||
48372A571C209A6C00AD0293 /* LAShapeStroke.m */,
|
||||
48372A591C209A7A00AD0293 /* LAShapeFill.h */,
|
||||
@@ -371,7 +368,6 @@
|
||||
62F683871D26EF420088C015 /* AnimatableProperties */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
620A56451D1B2D3D0030EBFB /* LAAnimatableValue.h */,
|
||||
620A565A1D1C81610030EBFB /* LAAnimatableColorValue.h */,
|
||||
620A565B1D1C81610030EBFB /* LAAnimatableColorValue.m */,
|
||||
620A565D1D1C81750030EBFB /* LAAnimatablePointValue.h */,
|
||||
@@ -380,6 +376,10 @@
|
||||
620A56611D1C81850030EBFB /* LAAnimatableNumberValue.m */,
|
||||
620A56631D1C81930030EBFB /* LAAnimatableShapeValue.h */,
|
||||
620A56641D1C81930030EBFB /* LAAnimatableShapeValue.m */,
|
||||
620CD7CB1D3415F000055AD1 /* LAAnimatableRectValue.h */,
|
||||
620CD7CC1D3415F000055AD1 /* LAAnimatableRectValue.m */,
|
||||
620CD7CE1D343A2500055AD1 /* LAAnimatableScaleValue.h */,
|
||||
620CD7CF1D343A2500055AD1 /* LAAnimatableScaleValue.m */,
|
||||
);
|
||||
name = AnimatableProperties;
|
||||
sourceTree = "<group>";
|
||||
@@ -563,28 +563,30 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
4804B31E1C1F757600DA8AF7 /* UIColor+Expanded.m in Sources */,
|
||||
620CD7D21D35AB9F00055AD1 /* LACompView.m in Sources */,
|
||||
4804B2FF1C1F55E600DA8AF7 /* ViewController.m in Sources */,
|
||||
48372A641C20A91C00AD0293 /* LAJSONExplorerViewController.m in Sources */,
|
||||
620A56651D1C81930030EBFB /* LAAnimatableShapeValue.m in Sources */,
|
||||
4804B3191C1F6DEA00DA8AF7 /* LAComposition.m in Sources */,
|
||||
4804B2FC1C1F55E600DA8AF7 /* AppDelegate.m in Sources */,
|
||||
4804B3211C1F761800DA8AF7 /* BWMath.m in Sources */,
|
||||
48372A471C1F8B4C00AD0293 /* LAPath.m in Sources */,
|
||||
48372AB41C20C13700AD0293 /* CGGeometryAdditions.m in Sources */,
|
||||
620A565F1D1C81750030EBFB /* LAAnimatablePointValue.m in Sources */,
|
||||
48372A4A1C1F8D7D00AD0293 /* LAMask.m in Sources */,
|
||||
4804B3161C1F5B2000DA8AF7 /* LALayer.m in Sources */,
|
||||
48372A521C20973300AD0293 /* LAShapeItem.m in Sources */,
|
||||
48372A4F1C1F99C600AD0293 /* LAShape.m in Sources */,
|
||||
48372A4F1C1F99C600AD0293 /* LAShapeGroup.m in Sources */,
|
||||
48372A581C209A6C00AD0293 /* LAShapeStroke.m in Sources */,
|
||||
620CD7D11D35AB9C00055AD1 /* LALayerView.m in Sources */,
|
||||
48372ABA1C20D98200AD0293 /* LAShapeRectangle.m in Sources */,
|
||||
48372A5B1C209A7A00AD0293 /* LAShapeFill.m in Sources */,
|
||||
4804B2F91C1F55E600DA8AF7 /* main.m in Sources */,
|
||||
620A56621D1C81850030EBFB /* LAAnimatableNumberValue.m in Sources */,
|
||||
48372A551C209A5F00AD0293 /* LAShapePath.m in Sources */,
|
||||
48372AB71C20D97200AD0293 /* LAShapeCircle.m in Sources */,
|
||||
620CD7CD1D3415F000055AD1 /* LAAnimatableRectValue.m in Sources */,
|
||||
620A565C1D1C81610030EBFB /* LAAnimatableColorValue.m in Sources */,
|
||||
48372A5E1C209A8900AD0293 /* LAShapeTransform.m in Sources */,
|
||||
620CD7D01D343A2500055AD1 /* LAAnimatableScaleValue.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
Binary file not shown.
@@ -29,22 +29,6 @@
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LotteAnimator/LALayer.m"
|
||||
timestampString = "489098771.583377"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "51"
|
||||
endingLineNumber = "51"
|
||||
landmarkName = "+rotationJSONTransformer"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
|
||||
@@ -6,17 +6,18 @@
|
||||
// Copyright © 2016 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAAnimatableValue.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface LAAnimatableColorValue : NSObject
|
||||
|
||||
- (instancetype)initWithColorValues:(NSDictionary *)colorValues;
|
||||
|
||||
- (void)prepareAnimationsForKeyPath:(NSString *)keyPath frameRate:(NSNumber *)frameRate;
|
||||
|
||||
@property (nonatomic, readonly) UIColor *initialColor;
|
||||
@property (nonatomic, readonly) NSString *keyPath;
|
||||
@property (nonatomic, readonly) CAKeyframeAnimation *animation;
|
||||
|
||||
@property (nonatomic, readonly) NSArray<UIColor *> *colorKeyframes;
|
||||
@property (nonatomic, readonly) NSArray<NSNumber *> *keyTimes;
|
||||
@property (nonatomic, readonly) NSArray<CAMediaTimingFunction *> *timingFunctions;
|
||||
@property (nonatomic, readonly) NSNumber *startFrame;
|
||||
@property (nonatomic, readonly) NSNumber *durationFrames;
|
||||
|
||||
@end
|
||||
|
||||
@@ -9,21 +9,16 @@
|
||||
#import "LAAnimatableColorValue.h"
|
||||
|
||||
@implementation LAAnimatableColorValue
|
||||
@synthesize animation = _animation;
|
||||
@synthesize keyPath = _keyPath;
|
||||
|
||||
- (instancetype)initWithColorValues:(NSDictionary *)colorValues
|
||||
keyPath:(NSString *)keyPath
|
||||
frameRate:(NSNumber *)frameRate {
|
||||
- (instancetype)initWithColorValues:(NSDictionary *)colorValues {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_keyPath = [keyPath copy];
|
||||
NSArray *value = colorValues[@"k"];
|
||||
if ([value isKindOfClass:[NSArray class]] &&
|
||||
[[(NSArray *)value firstObject] isKindOfClass:[NSDictionary class]] &&
|
||||
[(NSDictionary *)[(NSArray *)value firstObject] objectForKey:@"t"]) {
|
||||
//Keframes
|
||||
[self _buildAnimationForKeyframes:value keyPath:keyPath frameRate:frameRate];
|
||||
[self _buildAnimationForKeyframes:value];
|
||||
} else {
|
||||
//Single Value, no animation
|
||||
_initialColor = [[self _colorValueFromArray:value] copy];
|
||||
@@ -32,23 +27,19 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_buildAnimationForKeyframes:(NSArray<NSDictionary *> *)keyframes
|
||||
keyPath:(NSString *)keyPath
|
||||
frameRate:(NSNumber *)frameRate {
|
||||
- (void)_buildAnimationForKeyframes:(NSArray<NSDictionary *> *)keyframes {
|
||||
NSMutableArray *keyTimes = [NSMutableArray array];
|
||||
NSMutableArray *timingFunctions = [NSMutableArray array];
|
||||
NSMutableArray<UIColor *> *colorValues = [NSMutableArray array];
|
||||
|
||||
NSNumber *startFrame = keyframes.firstObject[@"t"];
|
||||
_startFrame = keyframes.firstObject[@"t"];
|
||||
NSNumber *endFrame = keyframes.lastObject[@"t"];
|
||||
|
||||
NSAssert((startFrame && endFrame && startFrame.integerValue < endFrame.integerValue),
|
||||
NSAssert((_startFrame && endFrame && _startFrame.integerValue < endFrame.integerValue),
|
||||
@"Lotte: Keyframe animation has incorrect time values or invalid number of keyframes");
|
||||
|
||||
// Calculate time bounds
|
||||
NSTimeInterval beginTime = startFrame.floatValue / frameRate.floatValue;
|
||||
NSNumber *durationFrames = @(endFrame.floatValue - startFrame.floatValue);
|
||||
NSTimeInterval durationTime = durationFrames.floatValue / frameRate.floatValue;
|
||||
// Calculate time duration
|
||||
_durationFrames = @(endFrame.floatValue - _startFrame.floatValue);
|
||||
|
||||
BOOL addStartValue = YES;
|
||||
BOOL addTimePadding = NO;
|
||||
@@ -59,11 +50,11 @@
|
||||
NSNumber *frame = keyframe[@"t"];
|
||||
// Calculate percentage value for keyframe.
|
||||
//CA Animations accept time values of 0-1 as a percentage of animation completed.
|
||||
NSNumber *timePercentage = @((frame.floatValue - startFrame.floatValue) / durationFrames.floatValue);
|
||||
NSNumber *timePercentage = @((frame.floatValue - _startFrame.floatValue) / _durationFrames.floatValue);
|
||||
|
||||
if (outColor) {
|
||||
//add out value
|
||||
[colorValues addObject:(id)[[outColor copy] CGColor]];
|
||||
[colorValues addObject:[outColor copy]];
|
||||
[timingFunctions addObject:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
|
||||
outColor = nil;
|
||||
}
|
||||
@@ -75,7 +66,7 @@
|
||||
if (keyframe == keyframes.firstObject) {
|
||||
_initialColor = startColor;
|
||||
}
|
||||
[colorValues addObject:(id)[[startColor copy] CGColor]];
|
||||
[colorValues addObject:[startColor copy]];
|
||||
if (timingFunctions.count) {
|
||||
[timingFunctions addObject:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
|
||||
}
|
||||
@@ -93,7 +84,7 @@
|
||||
// add end value if present for keyframe
|
||||
UIColor *endColor = [self _colorValueFromArray:keyframe[@"e"]];
|
||||
if (endColor) {
|
||||
[colorValues addObject:(id)[[endColor copy] CGColor]];
|
||||
[colorValues addObject:[endColor copy]];
|
||||
/*
|
||||
* Timing Function for time interpolations between keyframes
|
||||
* Should be n-1 where n is the number of keyframes
|
||||
@@ -126,13 +117,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
_animation = [CAKeyframeAnimation animationWithKeyPath:keyPath];
|
||||
_animation.values = colorValues;
|
||||
_animation.keyTimes = keyTimes;
|
||||
_animation.timingFunctions = timingFunctions;
|
||||
_animation.beginTime = beginTime;
|
||||
_animation.duration = durationTime;
|
||||
_animation.fillMode = kCAFillModeForwards;
|
||||
_colorKeyframes = colorValues;
|
||||
_keyTimes = keyTimes;
|
||||
_timingFunctions = timingFunctions;
|
||||
}
|
||||
|
||||
- (UIColor *)_colorValueFromArray:(NSArray<NSNumber *> *)colorArray {
|
||||
|
||||
@@ -6,17 +6,17 @@
|
||||
// Copyright © 2016 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAAnimatableValue.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface LAAnimatableNumberValue : NSObject
|
||||
|
||||
- (instancetype)initWithNumberValues:(NSDictionary *)numberValues
|
||||
keyPath:(NSString *)keyPath
|
||||
frameRate:(NSNumber *)frameRate;
|
||||
- (instancetype)initWithNumberValues:(NSDictionary *)numberValues;
|
||||
|
||||
@property (nonatomic, readonly) NSNumber *initialValue;
|
||||
@property (nonatomic, readonly) NSString *keyPath;
|
||||
@property (nonatomic, readonly) CAKeyframeAnimation *animation;
|
||||
@property (nonatomic, readonly) NSArray<NSNumber *> *valueKeyframes;
|
||||
@property (nonatomic, readonly) NSArray<NSNumber *> *keyTimes;
|
||||
@property (nonatomic, readonly) NSArray<CAMediaTimingFunction *> *timingFunctions;
|
||||
@property (nonatomic, readonly) NSNumber *startFrame;
|
||||
@property (nonatomic, readonly) NSNumber *durationFrames;
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,18 +10,15 @@
|
||||
|
||||
@implementation LAAnimatableNumberValue
|
||||
|
||||
- (instancetype)initWithNumberValues:(NSDictionary *)numberValues
|
||||
keyPath:(NSString *)keyPath
|
||||
frameRate:(NSNumber *)frameRate {
|
||||
- (instancetype)initWithNumberValues:(NSDictionary *)numberValues {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_keyPath = [keyPath copy];
|
||||
id value = numberValues[@"k"];
|
||||
if ([value isKindOfClass:[NSArray class]] &&
|
||||
[[(NSArray *)value firstObject] isKindOfClass:[NSDictionary class]] &&
|
||||
[(NSDictionary *)[(NSArray *)value firstObject] objectForKey:@"t"]) {
|
||||
//Keframes
|
||||
[self _buildAnimationForKeyframes:value keyPath:keyPath frameRate:frameRate];
|
||||
[self _buildAnimationForKeyframes:value];
|
||||
} else {
|
||||
//Single Value, no animation
|
||||
_initialValue = [[self _numberValueFromObject:value] copy];
|
||||
@@ -30,23 +27,21 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_buildAnimationForKeyframes:(NSArray<NSDictionary *> *)keyframes
|
||||
keyPath:(NSString *)keyPath
|
||||
frameRate:(NSNumber *)frameRate {
|
||||
- (void)_buildAnimationForKeyframes:(NSArray<NSDictionary *> *)keyframes {
|
||||
|
||||
NSMutableArray *keyTimes = [NSMutableArray array];
|
||||
NSMutableArray *timingFunctions = [NSMutableArray array];
|
||||
NSMutableArray<NSNumber *> *numberValues = [NSMutableArray array];
|
||||
|
||||
NSNumber *startFrame = keyframes.firstObject[@"t"];
|
||||
_startFrame = keyframes.firstObject[@"t"];
|
||||
NSNumber *endFrame = keyframes.lastObject[@"t"];
|
||||
|
||||
NSAssert((startFrame && endFrame && startFrame.integerValue < endFrame.integerValue),
|
||||
NSAssert((_startFrame && endFrame && _startFrame.integerValue < endFrame.integerValue),
|
||||
@"Lotte: Keyframe animation has incorrect time values or invalid number of keyframes");
|
||||
|
||||
// Calculate time bounds in second-time.
|
||||
NSTimeInterval beginTime = startFrame.floatValue / frameRate.floatValue;
|
||||
NSNumber *durationFrames = @(endFrame.floatValue - startFrame.floatValue);
|
||||
NSTimeInterval durationTime = durationFrames.floatValue / frameRate.floatValue;
|
||||
// Calculate time duration
|
||||
_durationFrames = @(endFrame.floatValue - _startFrame.floatValue);
|
||||
|
||||
|
||||
BOOL addStartValue = YES;
|
||||
BOOL addTimePadding = NO;
|
||||
@@ -57,7 +52,7 @@
|
||||
NSNumber *frame = keyframe[@"t"];
|
||||
// Calculate percentage value for keyframe.
|
||||
//CA Animations accept time values of 0-1 as a percentage of animation completed.
|
||||
NSNumber *timePercentage = @((frame.floatValue - startFrame.floatValue) / durationFrames.floatValue);
|
||||
NSNumber *timePercentage = @((frame.floatValue - _startFrame.floatValue) / _durationFrames.floatValue);
|
||||
|
||||
if (outValue) {
|
||||
//add out value
|
||||
@@ -123,14 +118,9 @@
|
||||
addTimePadding = YES;
|
||||
}
|
||||
}
|
||||
|
||||
_animation = [CAKeyframeAnimation animationWithKeyPath:keyPath];
|
||||
_animation.values = numberValues;
|
||||
_animation.keyTimes = keyTimes;
|
||||
_animation.timingFunctions = timingFunctions;
|
||||
_animation.beginTime = beginTime;
|
||||
_animation.duration = durationTime;
|
||||
_animation.fillMode = kCAFillModeForwards;
|
||||
_valueKeyframes = numberValues;
|
||||
_keyTimes = keyTimes;
|
||||
_timingFunctions = timingFunctions;
|
||||
}
|
||||
|
||||
- (NSNumber *)_numberValueFromObject:(id)valueObject {
|
||||
|
||||
@@ -6,17 +6,17 @@
|
||||
// Copyright © 2016 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAAnimatableValue.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface LAAnimatablePointValue : NSObject
|
||||
|
||||
- (instancetype)initWithPointValues:(NSDictionary *)pointValues
|
||||
keyPath:(NSString *)keyPath
|
||||
frameRate:(NSNumber *)frameRate;
|
||||
- (instancetype)initWithPointValues:(NSDictionary *)pointValues;
|
||||
|
||||
@property (nonatomic, readonly) CGPoint initialPoint;
|
||||
@property (nonatomic, readonly) NSString *keyPath;
|
||||
@property (nonatomic, readonly) CAKeyframeAnimation *animation;
|
||||
@property (nonatomic, readonly) UIBezierPath *animationPath;
|
||||
@property (nonatomic, readonly) NSArray<NSNumber *> *keyTimes;
|
||||
@property (nonatomic, readonly) NSArray<CAMediaTimingFunction *> *timingFunctions;
|
||||
@property (nonatomic, readonly) NSNumber *startFrame;
|
||||
@property (nonatomic, readonly) NSNumber *durationFrames;
|
||||
|
||||
@end
|
||||
|
||||
@@ -9,21 +9,16 @@
|
||||
#import "LAAnimatablePointValue.h"
|
||||
|
||||
@implementation LAAnimatablePointValue
|
||||
@synthesize animation = _animation;
|
||||
@synthesize keyPath = _keyPath;
|
||||
|
||||
- (instancetype)initWithPointValues:(NSDictionary *)pointValues
|
||||
keyPath:(NSString *)keyPath
|
||||
frameRate:(NSNumber *)frameRate {
|
||||
- (instancetype)initWithPointValues:(NSDictionary *)pointValues {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_keyPath = [keyPath copy];
|
||||
NSArray *value = pointValues[@"k"];
|
||||
if ([value isKindOfClass:[NSArray class]] &&
|
||||
[[(NSArray *)value firstObject] isKindOfClass:[NSDictionary class]] &&
|
||||
[(NSDictionary *)[(NSArray *)value firstObject] objectForKey:@"t"]) {
|
||||
//Keframes
|
||||
[self _buildAnimationForKeyframes:value keyPath:keyPath frameRate:frameRate];
|
||||
[self _buildAnimationForKeyframes:value];
|
||||
} else {
|
||||
//Single Value, no animation
|
||||
_initialPoint = [self _pointFromValueArray:value];
|
||||
@@ -32,23 +27,19 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_buildAnimationForKeyframes:(NSArray<NSDictionary *> *)keyframes
|
||||
keyPath:(NSString *)keyPath
|
||||
frameRate:(NSNumber *)frameRate {
|
||||
- (void)_buildAnimationForKeyframes:(NSArray<NSDictionary *> *)keyframes {
|
||||
NSMutableArray *keyTimes = [NSMutableArray array];
|
||||
NSMutableArray *timingFunctions = [NSMutableArray array];
|
||||
UIBezierPath *motionPath = [UIBezierPath new];
|
||||
|
||||
NSNumber *startFrame = keyframes.firstObject[@"t"];
|
||||
_startFrame = keyframes.firstObject[@"t"];
|
||||
NSNumber *endFrame = keyframes.lastObject[@"t"];
|
||||
|
||||
NSAssert((startFrame && endFrame && startFrame.integerValue < endFrame.integerValue),
|
||||
NSAssert((_startFrame && endFrame && _startFrame.integerValue < endFrame.integerValue),
|
||||
@"Lotte: Keyframe animation has incorrect time values or invalid number of keyframes");
|
||||
|
||||
// Calculate time bounds
|
||||
NSTimeInterval beginTime = startFrame.floatValue / frameRate.floatValue;
|
||||
NSNumber *durationFrames = @(endFrame.floatValue - startFrame.floatValue);
|
||||
NSTimeInterval durationTime = durationFrames.floatValue / frameRate.floatValue;
|
||||
// Calculate time duration
|
||||
_durationFrames = @(endFrame.floatValue - _startFrame.floatValue);
|
||||
|
||||
BOOL addStartValue = YES;
|
||||
BOOL addTimePadding = NO;
|
||||
@@ -59,7 +50,7 @@
|
||||
NSNumber *frame = keyframe[@"t"];
|
||||
// Calculate percentage value for keyframe.
|
||||
//CA Animations accept time values of 0-1 as a percentage of animation completed.
|
||||
NSNumber *timePercentage = @((frame.floatValue - startFrame.floatValue) / durationFrames.floatValue);
|
||||
NSNumber *timePercentage = @((frame.floatValue - _startFrame.floatValue) / _durationFrames.floatValue);
|
||||
|
||||
if (outPoint) {
|
||||
//add out value
|
||||
@@ -138,13 +129,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
_animation = [CAKeyframeAnimation animationWithKeyPath:keyPath];
|
||||
_animation.path = motionPath.CGPath;
|
||||
_animation.keyTimes = keyTimes;
|
||||
_animation.timingFunctions = timingFunctions;
|
||||
_animation.beginTime = beginTime;
|
||||
_animation.duration = durationTime;
|
||||
_animation.fillMode = kCAFillModeForwards;
|
||||
_animationPath = motionPath;
|
||||
_keyTimes = keyTimes;
|
||||
_timingFunctions = timingFunctions;
|
||||
}
|
||||
|
||||
- (CGPoint)_pointFromValueArray:(NSArray<NSNumber *> *)values {
|
||||
|
||||
23
LotteAnimator/LAAnimatableRectValue.h
Normal file
23
LotteAnimator/LAAnimatableRectValue.h
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// LAAnimatableSizeValue.h
|
||||
// LotteAnimator
|
||||
//
|
||||
// Created by brandon_withrow on 7/11/16.
|
||||
// Copyright © 2016 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface LAAnimatableRectValue : NSObject
|
||||
|
||||
- (instancetype)initWithRectValues:(NSDictionary *)rectValues;
|
||||
|
||||
@property (nonatomic, readonly) CGRect initialRect;
|
||||
@property (nonatomic, readonly) NSArray *rectKeyframes;
|
||||
@property (nonatomic, readonly) NSArray<NSNumber *> *keyTimes;
|
||||
@property (nonatomic, readonly) NSArray<CAMediaTimingFunction *> *timingFunctions;
|
||||
@property (nonatomic, readonly) NSNumber *startFrame;
|
||||
@property (nonatomic, readonly) NSNumber *durationFrames;
|
||||
|
||||
|
||||
@end
|
||||
21
LotteAnimator/LAAnimatableRectValue.m
Normal file
21
LotteAnimator/LAAnimatableRectValue.m
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// LAAnimatableSizeValue.m
|
||||
// LotteAnimator
|
||||
//
|
||||
// Created by brandon_withrow on 7/11/16.
|
||||
// Copyright © 2016 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAAnimatableRectValue.h"
|
||||
|
||||
@implementation LAAnimatableRectValue
|
||||
|
||||
- (instancetype)initWithRectValues:(NSDictionary *)rectValues {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
15
LotteAnimator/LAAnimatableScaleValue.h
Normal file
15
LotteAnimator/LAAnimatableScaleValue.h
Normal file
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// LAAnimatableScaleValue.h
|
||||
// LotteAnimator
|
||||
//
|
||||
// Created by brandon_withrow on 7/11/16.
|
||||
// Copyright © 2016 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface LAAnimatableScaleValue : NSObject
|
||||
|
||||
- (instancetype)initWithScaleValues:(NSDictionary *)scaleValues;
|
||||
|
||||
@end
|
||||
21
LotteAnimator/LAAnimatableScaleValue.m
Normal file
21
LotteAnimator/LAAnimatableScaleValue.m
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// LAAnimatableScaleValue.m
|
||||
// LotteAnimator
|
||||
//
|
||||
// Created by brandon_withrow on 7/11/16.
|
||||
// Copyright © 2016 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAAnimatableScaleValue.h"
|
||||
|
||||
@implementation LAAnimatableScaleValue
|
||||
|
||||
- (instancetype)initWithScaleValues:(NSDictionary *)scaleValues {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -6,18 +6,18 @@
|
||||
// Copyright © 2016 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAAnimatableValue.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface LAAnimatableShapeValue : NSObject
|
||||
|
||||
- (instancetype)initWithShapeValues:(NSDictionary *)shapeValues
|
||||
keyPath:(NSString *)keyPath
|
||||
frameRate:(NSNumber *)frameRate
|
||||
closedPath:(BOOL)closedPath;
|
||||
- (instancetype)initWithShapeValues:(NSDictionary *)shapeValues closed:(BOOL)closed;
|
||||
|
||||
@property (nonatomic, readonly) UIBezierPath *initialShape;
|
||||
@property (nonatomic, readonly) NSString *keyPath;
|
||||
@property (nonatomic, readonly) CAKeyframeAnimation *animation;
|
||||
|
||||
@property (nonatomic, readonly) NSArray<UIBezierPath *> *shapeKeyframes;
|
||||
@property (nonatomic, readonly) NSArray<NSNumber *> *keyTimes;
|
||||
@property (nonatomic, readonly) NSArray<CAMediaTimingFunction *> *timingFunctions;
|
||||
@property (nonatomic, readonly) NSNumber *startFrame;
|
||||
@property (nonatomic, readonly) NSNumber *durationFrames;
|
||||
|
||||
@end
|
||||
|
||||
@@ -9,76 +9,65 @@
|
||||
#import "LAAnimatableShapeValue.h"
|
||||
|
||||
@implementation LAAnimatableShapeValue
|
||||
@synthesize animation = _animation;
|
||||
@synthesize keyPath = _keyPath;
|
||||
|
||||
- (instancetype)initWithShapeValues:(NSDictionary *)shapeValues
|
||||
keyPath:(NSString *)keyPath
|
||||
frameRate:(NSNumber *)frameRate
|
||||
closedPath:(BOOL)closedPath {
|
||||
- (instancetype)initWithShapeValues:(NSDictionary *)shapeValues closed:(BOOL)closed {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_keyPath = [keyPath copy];
|
||||
id value = shapeValues[@"k"];
|
||||
if ([value isKindOfClass:[NSArray class]] &&
|
||||
[[(NSArray *)value firstObject] isKindOfClass:[NSDictionary class]] &&
|
||||
[(NSDictionary *)[(NSArray *)value firstObject] objectForKey:@"t"]) {
|
||||
//Keframes
|
||||
[self _buildAnimationForKeyframes:value keyPath:keyPath frameRate:frameRate closedPath:closedPath];
|
||||
} else {
|
||||
[self _buildAnimationForKeyframes:value closed:closed];
|
||||
} else if ([value isKindOfClass:[NSDictionary class]]) {
|
||||
//Single Value, no animation
|
||||
_initialShape = [self _bezierShapeFromValue:value closedPath:closedPath];
|
||||
_initialShape = [self _bezierShapeFromValue:value closed:closed];
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_buildAnimationForKeyframes:(NSArray<NSDictionary *> *)keyframes
|
||||
keyPath:(NSString *)keyPath
|
||||
frameRate:(NSNumber *)frameRate
|
||||
closedPath:(BOOL)closedPath {
|
||||
- (void)_buildAnimationForKeyframes:(NSArray<NSDictionary *> *)keyframes closed:(BOOL)closed {
|
||||
NSMutableArray *keyTimes = [NSMutableArray array];
|
||||
NSMutableArray *timingFunctions = [NSMutableArray array];
|
||||
NSMutableArray *shapeValues = [NSMutableArray array];
|
||||
NSMutableArray<UIBezierPath *> *shapeValues = [NSMutableArray array];
|
||||
|
||||
NSNumber *startFrame = keyframes.firstObject[@"t"];
|
||||
_startFrame = keyframes.firstObject[@"t"];
|
||||
NSNumber *endFrame = keyframes.lastObject[@"t"];
|
||||
|
||||
NSAssert((startFrame && endFrame && startFrame.integerValue < endFrame.integerValue),
|
||||
NSAssert((_startFrame && endFrame && _startFrame.integerValue < endFrame.integerValue),
|
||||
@"Lotte: Keyframe animation has incorrect time values or invalid number of keyframes");
|
||||
|
||||
// Calculate time bounds
|
||||
NSTimeInterval beginTime = startFrame.floatValue / frameRate.floatValue;
|
||||
NSNumber *durationFrames = @(endFrame.floatValue - startFrame.floatValue);
|
||||
NSTimeInterval durationTime = durationFrames.floatValue / frameRate.floatValue;
|
||||
// Calculate time duration
|
||||
_durationFrames = @(endFrame.floatValue - _startFrame.floatValue);
|
||||
|
||||
BOOL addStartValue = YES;
|
||||
BOOL addTimePadding = NO;
|
||||
UIBezierPath *outShape = nil;
|
||||
NSDictionary *outShape = nil;
|
||||
|
||||
for (NSDictionary *keyframe in keyframes) {
|
||||
// Get keyframe time value
|
||||
NSNumber *frame = keyframe[@"t"];
|
||||
// Calculate percentage value for keyframe.
|
||||
//CA Animations accept time values of 0-1 as a percentage of animation completed.
|
||||
NSNumber *timePercentage = @((frame.floatValue - startFrame.floatValue) / durationFrames.floatValue);
|
||||
NSNumber *timePercentage = @((frame.floatValue - _startFrame.floatValue) / _durationFrames.floatValue);
|
||||
|
||||
if (outShape) {
|
||||
//add out value
|
||||
[shapeValues addObject:(id)[[outShape copy] CGPath]];
|
||||
[shapeValues addObject:[self _bezierShapeFromValue:outShape closed:closed]];
|
||||
[timingFunctions addObject:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
|
||||
outShape = nil;
|
||||
}
|
||||
|
||||
UIBezierPath *startShape = [self _bezierShapeFromValue:keyframe[@"s"] closedPath:closedPath];
|
||||
NSDictionary *startShape = keyframe[@"s"];
|
||||
if (addStartValue) {
|
||||
// Add start value
|
||||
if (startShape) {
|
||||
if (keyframe == keyframes.firstObject) {
|
||||
_initialShape = startShape;
|
||||
_initialShape = [self _bezierShapeFromValue:startShape closed:closed];
|
||||
}
|
||||
|
||||
[shapeValues addObject:(id)[[startShape copy] CGPath]];
|
||||
[shapeValues addObject:[self _bezierShapeFromValue:startShape closed:closed]];
|
||||
if (timingFunctions.count) {
|
||||
[timingFunctions addObject:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
|
||||
}
|
||||
@@ -94,9 +83,9 @@
|
||||
}
|
||||
|
||||
// add end value if present for keyframe
|
||||
UIBezierPath *endShape = [self _bezierShapeFromValue:keyframe[@"e"] closedPath:closedPath];
|
||||
NSDictionary *endShape = keyframe[@"e"];
|
||||
if (endShape) {
|
||||
[shapeValues addObject:(id)[[endShape copy] CGColor]];
|
||||
[shapeValues addObject:[self _bezierShapeFromValue:endShape closed:closed]];
|
||||
/*
|
||||
* Timing Function for time interpolations between keyframes
|
||||
* Should be n-1 where n is the number of keyframes
|
||||
@@ -128,17 +117,13 @@
|
||||
addTimePadding = YES;
|
||||
}
|
||||
}
|
||||
|
||||
_animation = [CAKeyframeAnimation animationWithKeyPath:keyPath];
|
||||
_animation.values = shapeValues;
|
||||
_animation.keyTimes = keyTimes;
|
||||
_animation.timingFunctions = timingFunctions;
|
||||
_animation.beginTime = beginTime;
|
||||
_animation.duration = durationTime;
|
||||
_animation.fillMode = kCAFillModeForwards;
|
||||
|
||||
_shapeKeyframes = shapeValues;
|
||||
_keyTimes = keyTimes;
|
||||
_timingFunctions = timingFunctions;
|
||||
}
|
||||
|
||||
- (UIBezierPath *)_bezierShapeFromValue:(id)value closedPath:(BOOL)closedPath {
|
||||
- (UIBezierPath *)_bezierShapeFromValue:(id)value closed:(BOOL)closedPath {
|
||||
NSDictionary *pointsData = nil;
|
||||
if ([value isKindOfClass:[NSArray class]] &&
|
||||
[[(NSArray *)value firstObject] isKindOfClass:[NSDictionary class]] &&
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
//
|
||||
// LAAnimatableProperty.h
|
||||
// LotteAnimator
|
||||
//
|
||||
// Created by brandon_withrow on 6/22/16.
|
||||
// Copyright © 2016 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol LAAnimatableValue <NSObject>
|
||||
|
||||
@property (nonatomic, readonly) NSString *keyPath;
|
||||
@property (nonatomic, readonly) CAKeyframeAnimation *animation;
|
||||
|
||||
@end
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
@interface LACompView : UIView
|
||||
|
||||
- (instancetype)initWithModel:(LAScene *)model;
|
||||
- (instancetype)initWithModel:(LAComposition *)model;
|
||||
|
||||
@property (nonatomic, strong) LAScene *sceneModel;
|
||||
@property (nonatomic, strong) LAComposition *sceneModel;
|
||||
@property (nonatomic, assign) BOOL debugModeOn;
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
@implementation LACompView
|
||||
|
||||
- (instancetype)initWithModel:(LAScene *)model {
|
||||
self = [super initWithFrame:CGRectMake(0, 0, model.compWidth.floatValue, model.compHeight.floatValue)];
|
||||
- (instancetype)initWithModel:(LAComposition *)model {
|
||||
self = [super initWithFrame:model.compBounds];
|
||||
if (self) {
|
||||
_sceneModel = model;
|
||||
for (LALayer *layer in model.layers) {
|
||||
|
||||
@@ -6,16 +6,18 @@
|
||||
// Copyright © 2015 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MTLModel.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class LALayer;
|
||||
@interface LAComposition : MTLModel <MTLJSONSerializing>
|
||||
@interface LAComposition : NSObject
|
||||
|
||||
@property (nonatomic, strong) NSArray <LALayer *> *layers;
|
||||
@property (nonatomic, strong) NSNumber *compWidth;
|
||||
@property (nonatomic, strong) NSNumber *compHeight;
|
||||
@property (nonatomic, strong) NSNumber *startFrame;
|
||||
@property (nonatomic, strong) NSNumber *endFrame;
|
||||
@property (nonatomic, strong) NSNumber *framerate;
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary;
|
||||
|
||||
@property (nonatomic, readonly) NSArray <LALayer *> *layers;
|
||||
@property (nonatomic, readonly) CGRect compBounds;
|
||||
@property (nonatomic, readonly) NSNumber *startFrame;
|
||||
@property (nonatomic, readonly) NSNumber *endFrame;
|
||||
@property (nonatomic, readonly) NSNumber *framerate;
|
||||
@property (nonatomic, readonly) NSTimeInterval timeDuration;
|
||||
|
||||
@end
|
||||
|
||||
@@ -11,18 +11,39 @@
|
||||
|
||||
@implementation LAComposition
|
||||
|
||||
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
|
||||
return @{@"compWidth" : @"w",
|
||||
@"compHeight" : @"h",
|
||||
@"framerate" : @"fr",
|
||||
@"startFrame" : @"ip",
|
||||
@"endFrame" : @"op",
|
||||
@"layers" : @"layers"};
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self _mapFromJSON:jsonDictionary];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (NSValueTransformer *)layersJSONTransformer {
|
||||
// tell Mantle to populate diaAttributes property with an array of MDAttribute objects
|
||||
return [MTLJSONAdapter arrayTransformerWithModelClass:[LALayer class]];
|
||||
- (void)_mapFromJSON:(NSDictionary *)jsonDictionary {
|
||||
NSNumber *width = jsonDictionary[@"w"];
|
||||
NSNumber *height = jsonDictionary[@"h"];
|
||||
if (width && height) {
|
||||
CGRect bounds = CGRectMake(0, 0, width.floatValue, height.floatValue);
|
||||
_compBounds = bounds;
|
||||
}
|
||||
|
||||
_startFrame = [jsonDictionary[@"ip"] copy];
|
||||
_endFrame = [jsonDictionary[@"op"] copy];
|
||||
_framerate = [jsonDictionary[@"fr"] copy];
|
||||
|
||||
if (_startFrame && _endFrame && _framerate) {
|
||||
NSInteger frameDuration = _endFrame.integerValue - _startFrame.integerValue;
|
||||
NSTimeInterval timeDuration = frameDuration / _framerate.floatValue;
|
||||
_timeDuration = timeDuration;
|
||||
}
|
||||
|
||||
NSArray *layersJSON = jsonDictionary[@"layers"];
|
||||
NSMutableArray *layers = [NSMutableArray array];
|
||||
for (NSDictionary *layerJSON in layersJSON) {
|
||||
LALayer *layer = [[LALayer alloc] initWithJSON:layerJSON frameRate:_framerate];
|
||||
[layers addObject:layer];
|
||||
}
|
||||
_layers = layers;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,17 +6,18 @@
|
||||
// Copyright © 2015 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MTLModel.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@class LALayerView;
|
||||
@class LAShape;
|
||||
@class LAShapeGroup;
|
||||
@class LAMask;
|
||||
@class LAAnimatableColorValue;
|
||||
@class LAAnimatablePointValue;
|
||||
@class LAAnimatableNumberValue;
|
||||
@class LAAnimatableRectValue;
|
||||
@class LAAnimatableScaleValue;
|
||||
|
||||
typedef enum : NSUInteger {
|
||||
typedef enum : NSInteger {
|
||||
LALayerTypeNone,
|
||||
LALayerTypeSolid,
|
||||
LALayerTypeUnknown,
|
||||
@@ -24,25 +25,27 @@ typedef enum : NSUInteger {
|
||||
LALayerTypeShape
|
||||
} LALayerType;
|
||||
|
||||
@interface LALayer : MTLModel <MTLJSONSerializing>
|
||||
@interface LALayer : NSObject
|
||||
|
||||
@property (nonatomic, copy) NSString *layerName;
|
||||
@property (nonatomic, copy) NSNumber *layerID;
|
||||
@property (nonatomic, assign) LALayerType layerType;
|
||||
@property (nonatomic, copy) NSNumber *parentID;
|
||||
@property (nonatomic, copy) NSNumber *inPoint;
|
||||
@property (nonatomic, copy) NSNumber *outPoint;
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;
|
||||
|
||||
@property (nonatomic, copy) NSArray<LAShape *> *shapes;
|
||||
@property (nonatomic, copy) NSArray<LAMask *> *masks;
|
||||
@property (nonatomic, copy) LAAnimatableNumberValue *solidWidth;
|
||||
@property (nonatomic, copy) LAAnimatableNumberValue *solidHeight;
|
||||
@property (nonatomic, copy) LAAnimatableColorValue *solidColor;
|
||||
@property (nonatomic, readonly) NSString *layerName;
|
||||
@property (nonatomic, readonly) NSNumber *layerID;
|
||||
@property (nonatomic, readonly) LALayerType layerType;
|
||||
@property (nonatomic, readonly) NSNumber *parentID;
|
||||
@property (nonatomic, readonly) NSNumber *inFrame;
|
||||
@property (nonatomic, readonly) NSNumber *outFrame;
|
||||
|
||||
@property (nonatomic, copy) LAAnimatableNumberValue *opacity;
|
||||
@property (nonatomic, copy) LAAnimatableNumberValue *rotation;
|
||||
@property (nonatomic, copy) LAAnimatablePointValue *position;
|
||||
@property (nonatomic, copy) LAAnimatablePointValue *anchor;
|
||||
//@property (nonatomic, copy) LAAnimatableProperty *scale; //TODO Make This
|
||||
@property (nonatomic, readonly) NSArray<LAShapeGroup *> *shapes;
|
||||
@property (nonatomic, readonly) NSArray<LAMask *> *masks;
|
||||
|
||||
@property (nonatomic, readonly) LAAnimatableRectValue *solidBounds;
|
||||
@property (nonatomic, readonly) LAAnimatableColorValue *solidColor;
|
||||
|
||||
@property (nonatomic, readonly) LAAnimatableNumberValue *opacity;
|
||||
@property (nonatomic, readonly) LAAnimatableNumberValue *rotation;
|
||||
@property (nonatomic, readonly) LAAnimatablePointValue *position;
|
||||
@property (nonatomic, readonly) LAAnimatablePointValue *anchor;
|
||||
@property (nonatomic, readonly) LAAnimatableScaleValue *scale;
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,143 +10,77 @@
|
||||
#import "LAAnimatableColorValue.h"
|
||||
#import "LAAnimatablePointValue.h"
|
||||
#import "LAAnimatableNumberValue.h"
|
||||
#import "LAAnimatableScaleValue.h"
|
||||
#import "LAShapeGroup.h"
|
||||
|
||||
@implementation LALayer
|
||||
|
||||
+ (NSDictionary *)JSONKeyPathsByPropertyKey
|
||||
{
|
||||
// model_property_name : json_field_name
|
||||
return @{
|
||||
@"layerName" : @"layerName",
|
||||
@"layerID" : @"ind",
|
||||
@"layerType" : @"ty",
|
||||
@"parentID" : @"parent",
|
||||
@"inPoint" : @"ip",
|
||||
@"outPoint" : @"op",
|
||||
|
||||
@"rotation" : @"ks.r",
|
||||
@"position" : @"ks.p",
|
||||
@"anchor" : @"ks.a",
|
||||
// @"scale" : @"ks.s",
|
||||
@"opacity" : @"ks.o",
|
||||
|
||||
@"solidWidth" : @"sw",
|
||||
@"solidHeight" : @"sh",
|
||||
@"solidColor" : @"sc",
|
||||
// @"masks" : @"masksProperties",
|
||||
// @"shapes" : @"shapes"
|
||||
};
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self _mapFromJSON:jsonDictionary frameRate:frameRate];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (NSValueTransformer *)shapesJSONTransformer {
|
||||
return [MTLJSONAdapter arrayTransformerWithModelClass:[LAShape class]];
|
||||
- (void)_mapFromJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
_layerName = [jsonDictionary[@"nm"] copy];
|
||||
_layerID = [jsonDictionary[@"ind"] copy];
|
||||
|
||||
NSNumber *layerType = jsonDictionary[@"ty"];
|
||||
if (layerType.integerValue <= LALayerTypeShape) {
|
||||
_layerType = layerType.integerValue;
|
||||
} else {
|
||||
_layerType = LALayerTypeUnknown;
|
||||
}
|
||||
|
||||
_parentID = [jsonDictionary[@"parent"] copy];
|
||||
_inFrame = [jsonDictionary[@"ip"] copy];
|
||||
_outFrame = [jsonDictionary[@"op"] copy];
|
||||
|
||||
if (_layerType == LALayerTypeSolid) {
|
||||
// TODO Solids.
|
||||
|
||||
}
|
||||
|
||||
NSDictionary *opacity = jsonDictionary[@"ks.o"];
|
||||
if (opacity) {
|
||||
_opacity = [[LAAnimatableNumberValue alloc] initWithNumberValues:opacity];
|
||||
}
|
||||
|
||||
NSDictionary *rotation = jsonDictionary[@"ks.r"];
|
||||
if (rotation) {
|
||||
_rotation = [[LAAnimatableNumberValue alloc] initWithNumberValues:rotation];
|
||||
}
|
||||
|
||||
NSDictionary *position = jsonDictionary[@"ks.p"];
|
||||
if (position) {
|
||||
_position = [[LAAnimatablePointValue alloc] initWithPointValues:position];
|
||||
}
|
||||
|
||||
NSDictionary *anchor = jsonDictionary[@"ks.a"];
|
||||
if (anchor) {
|
||||
_anchor = [[LAAnimatablePointValue alloc] initWithPointValues:anchor];
|
||||
}
|
||||
|
||||
NSDictionary *scale = jsonDictionary[@"ks.s"];
|
||||
if (scale) {
|
||||
_scale = [[LAAnimatableScaleValue alloc] initWithScaleValues:scale];
|
||||
}
|
||||
|
||||
NSMutableArray *masks = [NSMutableArray array];
|
||||
for (NSDictionary *maskJSON in jsonDictionary[@"masksProperties"]) {
|
||||
LAMask *mask = [[LAMask alloc] initWithJSON:maskJSON frameRate:frameRate];
|
||||
[masks addObject:mask];
|
||||
}
|
||||
_masks = masks;
|
||||
|
||||
NSMutableArray *shapes = [NSMutableArray array];
|
||||
for (NSDictionary *shapeJSON in jsonDictionary[@"shapes"]) {
|
||||
LAShapeGroup *group = [[LAShapeGroup alloc] initWithJSON:shapeJSON frameRate:frameRate];
|
||||
[shapes addObject:group];
|
||||
}
|
||||
_shapes = shapes;
|
||||
}
|
||||
|
||||
+ (NSValueTransformer *)masksJSONTransformer {
|
||||
return [MTLJSONAdapter arrayTransformerWithModelClass:[LAMask class]];
|
||||
}
|
||||
|
||||
+ (NSValueTransformer *)rotationJSONTransformer {
|
||||
return [MTLValueTransformer transformerUsingForwardBlock:^id(NSDictionary *value, BOOL *success, NSError *__autoreleasing *error) {
|
||||
if (value == nil) {
|
||||
return nil;
|
||||
}
|
||||
if (![value isKindOfClass:NSDictionary.class]) {
|
||||
if (error != NULL) {
|
||||
NSDictionary *userInfo = @{
|
||||
NSLocalizedDescriptionKey: NSLocalizedString(@"Could not convert JSON dictionary to model object", @""),
|
||||
NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected an NSDictionary, got: %@", @""), value],
|
||||
MTLTransformerErrorHandlingInputValueErrorKey : value
|
||||
};
|
||||
|
||||
*error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo];
|
||||
}
|
||||
*success = NO;
|
||||
return nil;
|
||||
}
|
||||
LAAnimatableNumberValue *numvalue = [[LAAnimatableNumberValue alloc] initWithNumberValues:<#(NSDictionary *)#> keyPath:<#(NSString *)#> frameRate:<#(NSNumber *)#>]
|
||||
}];
|
||||
}
|
||||
|
||||
//+ (NSValueTransformer *)rotationJSONTransformer {
|
||||
// return [LAAnimatableValue animatablePropertyValueTransformerForKey:@"rotation"];
|
||||
//}
|
||||
//
|
||||
//+ (NSValueTransformer *)positionJSONTransformer {
|
||||
// return [LAAnimatableValue animatablePropertyValueTransformerForKey:@"position"];
|
||||
//}
|
||||
//
|
||||
//+ (NSValueTransformer *)anchorJSONTransformer {
|
||||
// return [LAAnimatableValue animatablePropertyValueTransformerForKey:@"anchor"];
|
||||
//}
|
||||
//
|
||||
//+ (NSValueTransformer *)scaleJSONTransformer {
|
||||
// return [LAAnimatableValue animatablePropertyValueTransformerForKey:@"scale"];
|
||||
//}
|
||||
//
|
||||
//+ (NSValueTransformer *)opacityJSONTransformer {
|
||||
// return [LAAnimatableValue animatablePropertyValueTransformerForKey:@"opacity"];
|
||||
//}
|
||||
|
||||
//- (UIColor *)bgColor {
|
||||
// if (!self.color) {
|
||||
// return [UIColor clearColor];
|
||||
// }
|
||||
// NSString *hexString = [self.color copy];
|
||||
// hexString = [hexString stringByReplacingOccurrencesOfString:@"#" withString:@""];
|
||||
//
|
||||
// return [UIColor colorWithHexString:hexString];
|
||||
//}
|
||||
//
|
||||
//- (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);
|
||||
// return uikitAnchorPoint;
|
||||
//}
|
||||
//
|
||||
//- (CGSize)size {
|
||||
// if (!self.width && !self.height) {
|
||||
// return CGSizeZero;
|
||||
// }
|
||||
// return CGSizeMake(self.width.floatValue, self.height.floatValue);
|
||||
//}
|
||||
//
|
||||
//- (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;
|
||||
//}
|
||||
//
|
||||
//- (CGRect)frameRect {
|
||||
// return CGRectMake(self.position.x, self.position.y, self.size.width, self.size.height);
|
||||
//}
|
||||
//
|
||||
//- (CGAffineTransform)transform {
|
||||
// return CGAffineTransformRotate(CGAffineTransformMakeScale(self.scale.width, self.scale.height), DegreesToRadians(self.rotation ? self.rotation.floatValue : 0.f));
|
||||
//}
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,13 +6,25 @@
|
||||
// Copyright © 2015 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MTLModel.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
@class LAAnimatableShapeValue;
|
||||
@class LAAnimatableNumberValue;
|
||||
|
||||
@interface LAMask : MTLModel <MTLJSONSerializing>
|
||||
typedef enum : NSUInteger {
|
||||
LAMaskModeAdd,
|
||||
LAMaskModeSubtract,
|
||||
LAMaskModeIntersect,
|
||||
LAMaskModeUnknown
|
||||
} LAMaskMode;
|
||||
|
||||
@property (nonatomic, getter=isClosed) BOOL closed;
|
||||
@property (nonatomic, getter=isInverted) BOOL inverted;
|
||||
@property (nonatomic, strong) LAPath *maskPath;
|
||||
@property (nonatomic, copy) NSNumber *opacity;
|
||||
@interface LAMask : NSObject
|
||||
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;
|
||||
|
||||
@property (nonatomic, readonly) BOOL closed;
|
||||
@property (nonatomic, readonly) BOOL inverted;
|
||||
@property (nonatomic, readonly) LAMaskMode maskMode;
|
||||
@property (nonatomic, readonly) LAAnimatableShapeValue *maskPath;
|
||||
@property (nonatomic, readonly) LAAnimatableNumberValue *opacity;
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,27 +7,46 @@
|
||||
//
|
||||
|
||||
#import "LAMask.h"
|
||||
#import "LAAnimatableShapeValue.h"
|
||||
#import "LAAnimatableNumberValue.h"
|
||||
|
||||
@implementation LAMask
|
||||
|
||||
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
|
||||
return @{@"closed" : @"cl",
|
||||
@"inverted" : @"inv",
|
||||
@"maskPath" : @"pt",
|
||||
@"opacity" : @"o"};
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self _mapFromJSON:jsonDictionary frameRate:frameRate];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (NSValueTransformer *)maskPathJSONTransformer {
|
||||
// tell Mantle to populate diaAttributes property with an array of MDAttribute objects
|
||||
return [MTLJSONAdapter dictionaryTransformerWithModelClass:[LAPath class]];
|
||||
}
|
||||
|
||||
+ (NSValueTransformer *)closedJSONTransformer {
|
||||
return [NSValueTransformer valueTransformerForName:MTLBooleanValueTransformerName];
|
||||
}
|
||||
|
||||
+ (NSValueTransformer *)invertedJSONTransformer {
|
||||
return [NSValueTransformer valueTransformerForName:MTLBooleanValueTransformerName];
|
||||
- (void)_mapFromJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
NSNumber *closed = jsonDictionary[@"cl"];
|
||||
_closed = closed.boolValue;
|
||||
|
||||
NSNumber *inverted = jsonDictionary[@"inv"];
|
||||
_inverted = inverted.boolValue;
|
||||
|
||||
NSString *mode = jsonDictionary[@"mode"];
|
||||
if ([mode isEqualToString:@"a"]) {
|
||||
_maskMode = LAMaskModeAdd;
|
||||
} else if ([mode isEqualToString:@"s"]) {
|
||||
_maskMode = LAMaskModeSubtract;
|
||||
} else if ([mode isEqualToString:@"i"]) {
|
||||
_maskMode = LAMaskModeIntersect;
|
||||
} else {
|
||||
_maskMode = LAMaskModeUnknown;
|
||||
}
|
||||
|
||||
NSDictionary *maskshape = jsonDictionary[@"pt"];
|
||||
if (maskshape) {
|
||||
_maskPath = [[LAAnimatableShapeValue alloc] initWithShapeValues:maskshape closed:_closed];
|
||||
}
|
||||
|
||||
NSDictionary *opacity = jsonDictionary[@"o"];
|
||||
if (opacity) {
|
||||
_opacity = [[LAAnimatableNumberValue alloc] initWithNumberValues:opacity];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -9,12 +9,10 @@
|
||||
#ifndef LAModels_h
|
||||
#define LAModels_h
|
||||
|
||||
#import "LAPath.h"
|
||||
#import "LAMask.h"
|
||||
#import "LAComposition.h"
|
||||
#import "LALayer.h"
|
||||
#import "LAShape.h"
|
||||
#import "LAShapeItem.h"
|
||||
#import "LAShapeGroup.h"
|
||||
#import "LAShapePath.h"
|
||||
#import "LAShapeStroke.h"
|
||||
#import "LAShapeFill.h"
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
//
|
||||
// LABezierPath.h
|
||||
// LotteAnimator
|
||||
//
|
||||
// Created by Brandon Withrow on 12/14/15.
|
||||
// Copyright © 2015 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MTLModel.h"
|
||||
|
||||
@interface LAPath : MTLModel <MTLJSONSerializing>
|
||||
|
||||
@property (nonatomic, strong) NSArray *points;
|
||||
@property (nonatomic, strong) NSArray *inTangents;
|
||||
@property (nonatomic, strong) NSArray *outTangents;
|
||||
|
||||
- (UIBezierPath *)bezierPath:(BOOL)closedPath;
|
||||
|
||||
@end
|
||||
@@ -1,54 +0,0 @@
|
||||
//
|
||||
// LABezierPath.m
|
||||
// LotteAnimator
|
||||
//
|
||||
// Created by Brandon Withrow on 12/14/15.
|
||||
// Copyright © 2015 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAPath.h"
|
||||
|
||||
@implementation LAPath
|
||||
|
||||
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
|
||||
return @{@"points" : @"v",
|
||||
@"inTangents" : @"i",
|
||||
@"outTangents" : @"o"};
|
||||
}
|
||||
|
||||
- (UIBezierPath *)bezierPath:(BOOL)closedPath {
|
||||
if (!self.points.count) {
|
||||
return nil;
|
||||
}
|
||||
UIBezierPath *path = [UIBezierPath bezierPath];
|
||||
|
||||
[path moveToPoint:[self _vertexAtIndex:0]];
|
||||
for (int i = 1; i < self.points.count; i ++) {
|
||||
[path addCurveToPoint:[self _vertexAtIndex:i] controlPoint1:[self _outTangentAtIndex:i - 1] controlPoint2:[self _inTangentAtIndex:i]];
|
||||
}
|
||||
|
||||
if (closedPath) {
|
||||
[path addCurveToPoint:[self _vertexAtIndex:0] controlPoint1:[self _outTangentAtIndex:self.points.count - 1] controlPoint2:[self _inTangentAtIndex:0]];
|
||||
[path closePath];
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
- (CGPoint)_vertexAtIndex:(NSInteger)idx {
|
||||
NSArray *pointArray = self.points[idx];
|
||||
return CGPointMake([pointArray[0] floatValue], [pointArray[1] floatValue]);
|
||||
}
|
||||
|
||||
- (CGPoint)_outTangentAtIndex:(NSInteger)idx {
|
||||
NSArray *outArray = self.outTangents[idx];
|
||||
CGPoint vertex = [self _vertexAtIndex:idx];
|
||||
return CGPointMake([outArray[0] floatValue] + vertex.x, [outArray[1] floatValue] + vertex.y);
|
||||
}
|
||||
|
||||
- (CGPoint)_inTangentAtIndex:(NSInteger)idx {
|
||||
NSArray *inArray = self.inTangents[idx];
|
||||
CGPoint vertex = [self _vertexAtIndex:idx];
|
||||
return CGPointMake([inArray[0] floatValue] + vertex.x, [inArray[1] floatValue] + vertex.y);
|
||||
}
|
||||
@end
|
||||
@@ -1,21 +0,0 @@
|
||||
//
|
||||
// LAShape.h
|
||||
// LotteAnimator
|
||||
//
|
||||
// Created by Brandon Withrow on 12/14/15.
|
||||
// Copyright © 2015 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MTLModel.h"
|
||||
|
||||
@interface LAShape : MTLModel <MTLJSONSerializing>
|
||||
|
||||
@property (nonatomic, copy) NSArray *shapeItems;
|
||||
// TODO Map these items more efficiently for use in LALayerView
|
||||
// This is extremely inefficient and unsafe.
|
||||
@property (nonatomic, readonly) NSArray *paths;
|
||||
@property (nonatomic, readonly) NSArray *strokes;
|
||||
@property (nonatomic, readonly) NSArray *fills;
|
||||
@property (nonatomic, readonly) NSArray *transforms;
|
||||
|
||||
@end
|
||||
@@ -1,85 +0,0 @@
|
||||
//
|
||||
// LAShape.m
|
||||
// LotteAnimator
|
||||
//
|
||||
// Created by Brandon Withrow on 12/14/15.
|
||||
// Copyright © 2015 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#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] ||
|
||||
[item.itemType isEqualToString:LAShapeItemType.Circle] ||
|
||||
[item.itemType isEqualToString:LAShapeItemType.Rectangle]) {
|
||||
[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
|
||||
@@ -6,14 +6,10 @@
|
||||
// Copyright © 2015 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAShapeItem.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface LAShapeCircle : LAShapeItem
|
||||
@interface LAShapeCircle : NSObject
|
||||
|
||||
@property (nonatomic, copy) NSArray *positionArray;
|
||||
@property (nonatomic, copy) NSArray *sizeArray;
|
||||
|
||||
@property (nonatomic, readonly) CGPoint position;
|
||||
@property (nonatomic, readonly) CGSize size;
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,30 +10,16 @@
|
||||
|
||||
@implementation LAShapeCircle
|
||||
|
||||
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
|
||||
return @{@"itemType" : @"ty",
|
||||
@"positionArray" : @"p",
|
||||
@"sizeArray" : @"s"};
|
||||
}
|
||||
|
||||
- (CGPoint)position {
|
||||
if (!self.positionArray) {
|
||||
return CGPointZero;
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self _mapFromJSON:jsonDictionary frameRate:frameRate];
|
||||
}
|
||||
CGPoint aePosition = CGPointMake([self.positionArray[0] floatValue], [self.positionArray[1] floatValue]);
|
||||
|
||||
return aePosition;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (CGSize)size {
|
||||
if (!self.sizeArray) {
|
||||
return CGSizeZero;
|
||||
}
|
||||
return CGSizeMake([self.sizeArray[0] floatValue], [self.sizeArray[1] floatValue]);
|
||||
- (void)_mapFromJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
|
||||
}
|
||||
|
||||
- (UIBezierPath *)path {
|
||||
CGRect circleBounds = CGRectMake(self.size.width * -0.5, self.size.height * -0.5, self.size.width, self.size.height);
|
||||
return [UIBezierPath bezierPathWithOvalInRect:circleBounds];
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -6,14 +6,17 @@
|
||||
// Copyright © 2015 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAShapeItem.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface LAShapeFill : LAShapeItem
|
||||
@class LAAnimatableColorValue;
|
||||
@class LAAnimatableNumberValue;
|
||||
|
||||
@property (nonatomic, getter=isFillEnabled) BOOL fillEnabled;
|
||||
@property (nonatomic, copy) NSArray *colorElements;
|
||||
@property (nonatomic, copy) NSNumber *opacity;
|
||||
@interface LAShapeFill : NSObject
|
||||
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;
|
||||
|
||||
@property (nonatomic, readonly) BOOL fillEnabled;
|
||||
@property (nonatomic, readonly) LAAnimatableColorValue *color;
|
||||
@property (nonatomic, readonly) LAAnimatableNumberValue *opacity;
|
||||
|
||||
@property (nonatomic, readonly) UIColor *color;
|
||||
@property (nonatomic, readonly) CGFloat alpha;
|
||||
@end
|
||||
|
||||
@@ -7,35 +7,32 @@
|
||||
//
|
||||
|
||||
#import "LAShapeFill.h"
|
||||
#import "LAAnimatableNumberValue.h"
|
||||
#import "LAAnimatableColorValue.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;
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self _mapFromJSON:jsonDictionary frameRate:frameRate];
|
||||
}
|
||||
return self.opacity.floatValue / 100.f;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (UIColor *)color {
|
||||
if (!self.colorElements) {
|
||||
return [UIColor clearColor];
|
||||
- (void)_mapFromJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
NSDictionary *color = jsonDictionary[@"c"];
|
||||
if (color) {
|
||||
_color = [[LAAnimatableColorValue alloc] initWithColorValues:color];
|
||||
}
|
||||
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)];
|
||||
|
||||
NSDictionary *opacity = jsonDictionary[@"o"];
|
||||
if (opacity) {
|
||||
_opacity = [[LAAnimatableNumberValue alloc] initWithNumberValues:opacity];
|
||||
}
|
||||
|
||||
NSNumber *fillEnabled = jsonDictionary[@"fillEnabled"];
|
||||
_fillEnabled = fillEnabled.boolValue;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
17
LotteAnimator/LAShapeGroup.h
Normal file
17
LotteAnimator/LAShapeGroup.h
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// LAShape.h
|
||||
// LotteAnimator
|
||||
//
|
||||
// Created by Brandon Withrow on 12/14/15.
|
||||
// Copyright © 2015 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface LAShapeGroup : NSObject
|
||||
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;
|
||||
|
||||
@property (nonatomic, readonly) NSArray *items;
|
||||
|
||||
@end
|
||||
59
LotteAnimator/LAShapeGroup.m
Normal file
59
LotteAnimator/LAShapeGroup.m
Normal file
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// LAShape.m
|
||||
// LotteAnimator
|
||||
//
|
||||
// Created by Brandon Withrow on 12/14/15.
|
||||
// Copyright © 2015 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAShapeGroup.h"
|
||||
#import "LAShapeFill.h"
|
||||
#import "LAShapePath.h"
|
||||
#import "LAShapeCircle.h"
|
||||
#import "LAShapeStroke.h"
|
||||
#import "LAShapeTransform.h"
|
||||
#import "LAShapeRectangle.h"
|
||||
|
||||
@implementation LAShapeGroup
|
||||
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self _mapFromJSON:jsonDictionary frameRate:frameRate];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_mapFromJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
NSArray *itemsJSON = jsonDictionary[@"it"];
|
||||
NSMutableArray *items = [NSMutableArray array];
|
||||
for (NSDictionary *itemJSON in itemsJSON) {
|
||||
NSString *type = itemJSON[@"ty"];
|
||||
|
||||
if ([type isEqualToString:@"gr"]) {
|
||||
LAShapeGroup *group = [[LAShapeGroup alloc] initWithJSON:itemJSON frameRate:frameRate];
|
||||
[items addObject:group];
|
||||
} else if ([type isEqualToString:@"st"]) {
|
||||
LAShapeStroke *stroke = [[LAShapeStroke alloc] initWithJSON:itemJSON frameRate:frameRate];
|
||||
[items addObject:stroke];
|
||||
} else if ([type isEqualToString:@"fl"]) {
|
||||
LAShapeFill *fill = [[LAShapeFill alloc] initWithJSON:itemJSON frameRate:frameRate];
|
||||
[items addObject:fill];
|
||||
} else if ([type isEqualToString:@"tr"]) {
|
||||
LAShapeTransform *transform = [[LAShapeTransform alloc] initWithJSON:itemJSON frameRate:frameRate];
|
||||
[items addObject:transform];
|
||||
} else if ([type isEqualToString:@"sh"]) {
|
||||
LAShapePath *path = [[LAShapePath alloc] initWithJSON:itemJSON frameRate:frameRate];
|
||||
[items addObject:path];
|
||||
} else if ([type isEqualToString:@"el"]) {
|
||||
LAShapeCircle *circle = [[LAShapeCircle alloc] initWithJSON:itemJSON frameRate:frameRate];
|
||||
[items addObject:circle];
|
||||
} else if ([type isEqualToString:@"rc"]) {
|
||||
LAShapeRectangle *rectangle = [[LAShapeRectangle alloc] initWithJSON:itemJSON frameRate:frameRate];
|
||||
[items addObject:rectangle];
|
||||
}
|
||||
}
|
||||
_items = items;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,28 +0,0 @@
|
||||
//
|
||||
// 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;
|
||||
__unsafe_unretained NSString * const Circle;
|
||||
__unsafe_unretained NSString * const Rectangle;
|
||||
};
|
||||
|
||||
extern const struct LAShapeItemType LAShapeItemType;
|
||||
|
||||
@interface LAShapeItem : MTLModel <MTLJSONSerializing>
|
||||
|
||||
@property (nonatomic, copy) NSString *itemType;
|
||||
|
||||
@property (nonatomic, readonly) UIBezierPath *path;
|
||||
|
||||
@end
|
||||
@@ -1,54 +0,0 @@
|
||||
//
|
||||
// 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",
|
||||
.Circle = @"el",
|
||||
.Rectangle = @"rc"
|
||||
};
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
if ([JSONDictionary[@"ty"] isEqual:LAShapeItemType.Circle]) {
|
||||
return LAShapeCircle.class;
|
||||
}
|
||||
|
||||
if ([JSONDictionary[@"ty"] isEqual:LAShapeItemType.Rectangle]) {
|
||||
return LAShapeRectangle.class;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -6,11 +6,16 @@
|
||||
// Copyright © 2015 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAShapeItem.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface LAShapePath : LAShapeItem
|
||||
@class LAAnimatableShapeValue;
|
||||
|
||||
@property (nonatomic, getter=isClosed) BOOL closed;
|
||||
@property (nonatomic, strong) LAPath *shapePath;
|
||||
@interface LAShapePath : NSObject
|
||||
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;
|
||||
|
||||
@property (nonatomic, readonly) BOOL closed;
|
||||
@property (nonatomic, readonly) NSNumber *index;
|
||||
@property (nonatomic, readonly) LAAnimatableShapeValue *shapePath;
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,25 +7,25 @@
|
||||
//
|
||||
|
||||
#import "LAShapePath.h"
|
||||
#import "LAAnimatableShapeValue.h"
|
||||
|
||||
@implementation LAShapePath
|
||||
|
||||
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
|
||||
return @{@"itemType" : @"ty",
|
||||
@"closed" : @"closed",
|
||||
@"shapePath" : @"ks"};
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self _mapFromJSON:jsonDictionary frameRate:frameRate];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (NSValueTransformer *)shapePathJSONTransformer {
|
||||
// tell Mantle to populate diaAttributes property with an array of MDAttribute objects
|
||||
return [MTLJSONAdapter dictionaryTransformerWithModelClass:[LAPath class]];
|
||||
- (void)_mapFromJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
_index = jsonDictionary[@"ind"];
|
||||
_closed = [jsonDictionary[@"closed"] boolValue];
|
||||
NSDictionary *shape = jsonDictionary[@"ks"];
|
||||
if (shape) {
|
||||
_shapePath = [[LAAnimatableShapeValue alloc] initWithShapeValues:shape closed:_closed];
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSValueTransformer *)closedJSONTransformer {
|
||||
return [NSValueTransformer valueTransformerForName:MTLBooleanValueTransformerName];
|
||||
}
|
||||
|
||||
- (UIBezierPath *)path {
|
||||
return [self.shapePath bezierPath:self.isClosed];
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -6,15 +6,10 @@
|
||||
// Copyright © 2015 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAShapeItem.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface LAShapeRectangle : LAShapeItem
|
||||
@interface LAShapeRectangle : NSObject
|
||||
|
||||
@property (nonatomic, copy) NSArray *positionArray;
|
||||
@property (nonatomic, copy) NSArray *sizeArray;
|
||||
@property (nonatomic, copy) NSNumber *cornerRadius;
|
||||
|
||||
@property (nonatomic, readonly) CGPoint position;
|
||||
@property (nonatomic, readonly) CGSize size;
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,38 +10,16 @@
|
||||
|
||||
@implementation LAShapeRectangle
|
||||
|
||||
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
|
||||
return @{@"itemType" : @"ty",
|
||||
@"positionArray" : @"p",
|
||||
@"sizeArray" : @"s",
|
||||
@"cornerRadius" : @"r"};
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self _mapFromJSON:jsonDictionary frameRate:frameRate];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (CGPoint)position {
|
||||
if (!self.positionArray) {
|
||||
return CGPointZero;
|
||||
}
|
||||
CGPoint aePosition = CGPointMake([self.positionArray[0] floatValue], [self.positionArray[1] floatValue]);
|
||||
- (void)_mapFromJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
|
||||
return aePosition;
|
||||
}
|
||||
|
||||
- (CGSize)size {
|
||||
if (!self.sizeArray) {
|
||||
return CGSizeZero;
|
||||
}
|
||||
return CGSizeMake([self.sizeArray[0] floatValue], [self.sizeArray[1] floatValue]);
|
||||
}
|
||||
|
||||
- (UIBezierPath *)path {
|
||||
CGRect rectBounds = CGRectMake(self.size.width * -0.5, self.size.height * -0.5, self.size.width, self.size.height);
|
||||
UIBezierPath *path;
|
||||
if (self.cornerRadius && self.cornerRadius.floatValue > 0.0) {
|
||||
path = [UIBezierPath bezierPathWithRoundedRect:rectBounds cornerRadius:self.cornerRadius.floatValue];
|
||||
} else {
|
||||
path = [UIBezierPath bezierPathWithRect:rectBounds];
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,16 +6,18 @@
|
||||
// Copyright © 2015 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAShapeItem.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface LAShapeStroke : LAShapeItem
|
||||
@class LAAnimatableColorValue;
|
||||
@class LAAnimatableNumberValue;
|
||||
|
||||
@property (nonatomic, getter=isFillEnabled) BOOL fillEnabled;
|
||||
@property (nonatomic, copy) NSArray *colorElements;
|
||||
@property (nonatomic, copy) NSNumber *opacity;
|
||||
@property (nonatomic, copy) NSNumber *width;
|
||||
@interface LAShapeStroke : NSObject
|
||||
|
||||
@property (nonatomic, readonly) UIColor *color;
|
||||
@property (nonatomic, readonly) CGFloat alpha;
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;
|
||||
|
||||
@property (nonatomic, readonly) BOOL fillEnabled;
|
||||
@property (nonatomic, readonly) LAAnimatableColorValue *color;
|
||||
@property (nonatomic, readonly) LAAnimatableNumberValue *opacity;
|
||||
@property (nonatomic, readonly) LAAnimatableNumberValue *width;
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,36 +7,37 @@
|
||||
//
|
||||
|
||||
#import "LAShapeStroke.h"
|
||||
#import "LAAnimatableNumberValue.h"
|
||||
#import "LAAnimatableColorValue.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;
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self _mapFromJSON:jsonDictionary frameRate:frameRate];
|
||||
}
|
||||
return self.opacity.floatValue / 100.f;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (UIColor *)color {
|
||||
if (!self.colorElements) {
|
||||
return [UIColor clearColor];
|
||||
- (void)_mapFromJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
NSDictionary *color = jsonDictionary[@"c"];
|
||||
if (color) {
|
||||
_color = [[LAAnimatableColorValue alloc] initWithColorValues:color];
|
||||
}
|
||||
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)];
|
||||
|
||||
NSDictionary *width = jsonDictionary[@"w"];
|
||||
if (width) {
|
||||
_width = [[LAAnimatableNumberValue alloc] initWithNumberValues:width];
|
||||
}
|
||||
|
||||
NSDictionary *opacity = jsonDictionary[@"o"];
|
||||
if (opacity) {
|
||||
_opacity = [[LAAnimatableNumberValue alloc] initWithNumberValues:opacity];
|
||||
}
|
||||
|
||||
NSNumber *fillEnabled = jsonDictionary[@"fillEnabled"];
|
||||
_fillEnabled = fillEnabled.boolValue;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -6,20 +6,20 @@
|
||||
// Copyright © 2015 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAShapeItem.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface LAShapeTransform : LAShapeItem
|
||||
@class LAAnimatableNumberValue;
|
||||
@class LAAnimatablePointValue;
|
||||
@class LAAnimatableScaleValue;
|
||||
|
||||
@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;
|
||||
@interface LAShapeTransform : NSObject
|
||||
|
||||
@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;
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;
|
||||
|
||||
@property (nonatomic, readonly) LAAnimatablePointValue *position;
|
||||
@property (nonatomic, readonly) LAAnimatablePointValue *anchor;
|
||||
@property (nonatomic, readonly) LAAnimatableScaleValue *scale;
|
||||
@property (nonatomic, readonly) LAAnimatableNumberValue *rotation;
|
||||
@property (nonatomic, readonly) LAAnimatableNumberValue *opacity;
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,61 +7,45 @@
|
||||
//
|
||||
|
||||
#import "LAShapeTransform.h"
|
||||
#import "LAAnimatableNumberValue.h"
|
||||
#import "LAAnimatablePointValue.h"
|
||||
#import "LAAnimatableScaleValue.h"
|
||||
|
||||
@implementation LAShapeTransform
|
||||
|
||||
+ (NSDictionary *)JSONKeyPathsByPropertyKey {
|
||||
return @{@"itemType" : @"ty",
|
||||
@"positionArray" : @"p",
|
||||
@"anchorPointArray" : @"a",
|
||||
@"scaleArray" : @"s",
|
||||
@"rotation" : @"r",
|
||||
@"opacity" : @"o"};
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self _mapFromJSON:jsonDictionary frameRate:frameRate];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (CGPoint)position {
|
||||
if (!self.positionArray) {
|
||||
return CGPointZero;
|
||||
- (void)_mapFromJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
NSDictionary *position = jsonDictionary[@"p"];
|
||||
if (position) {
|
||||
_position = [[LAAnimatablePointValue alloc] initWithPointValues:position];
|
||||
}
|
||||
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];
|
||||
|
||||
NSDictionary *anchor = jsonDictionary[@"a"];
|
||||
if (anchor) {
|
||||
_anchor = [[LAAnimatablePointValue alloc] initWithPointValues:anchor];
|
||||
}
|
||||
return aePosition;
|
||||
}
|
||||
|
||||
- (CGPoint)anchorPoint {
|
||||
if (!self.anchorPointArray) {
|
||||
return CGPointZero;
|
||||
|
||||
NSDictionary *scale = jsonDictionary[@"s"];
|
||||
if (scale) {
|
||||
_scale = [[LAAnimatableScaleValue alloc] initWithScaleValues:scale];
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
// TODO Permanently Unwrap these arrays for efficency
|
||||
- (CGSize)scale {
|
||||
if (!self.scaleArray) {
|
||||
return CGSizeZero;
|
||||
|
||||
NSDictionary *rotation = jsonDictionary[@"r"];
|
||||
if (rotation) {
|
||||
_rotation = [[LAAnimatableNumberValue alloc] initWithNumberValues:rotation];
|
||||
}
|
||||
return CGSizeMake([self.scaleArray[0] floatValue] / 100.f, [self.scaleArray[1] floatValue] / 100.f);
|
||||
}
|
||||
|
||||
- (CGFloat)alpha {
|
||||
if (!self.opacity) {
|
||||
return 1;
|
||||
|
||||
NSDictionary *opacity = jsonDictionary[@"o"];
|
||||
if (opacity) {
|
||||
_opacity = [[LAAnimatableNumberValue alloc] initWithNumberValues:opacity];
|
||||
}
|
||||
return self.opacity.floatValue / 100.f;
|
||||
}
|
||||
|
||||
- (CGAffineTransform)transform {
|
||||
CGAffineTransform translate = CGAffineTransformMakeTranslation(self.position.x, self.position.y);
|
||||
CGAffineTransform scale = CGAffineTransformScale(translate, self.scale.width, self.scale.height);
|
||||
CGAffineTransform rotate = CGAffineTransformRotate(scale, DegreesToRadians(self.rotation ? self.rotation.floatValue : 0.f));
|
||||
return rotate;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
NSData *jsonData = [[NSData alloc] initWithContentsOfFile:filePath];
|
||||
NSDictionary *JSONObject = [NSJSONSerialization JSONObjectWithData:jsonData
|
||||
options:0 error:&error];
|
||||
LAComposition *laScene = [MTLJSONAdapter modelOfClass:[LAComposition class] fromJSONDictionary:JSONObject error:&error];
|
||||
LAComposition *laScene = [[LAComposition alloc] initWithJSON:JSONObject];
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user