mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-01-24 04:58:59 +00:00
Added mask, matte, line dash, trim support
This commit is contained in:
@@ -35,7 +35,6 @@
|
||||
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 */; };
|
||||
620CD7E51D38180800055AD1 /* LAGroupLayerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 620CD7E41D38180800055AD1 /* LAGroupLayerView.m */; };
|
||||
62FE408D1D3EC81C00CA389D /* CAAnimationGroup+LAAnimatableGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FE408C1D3EC81C00CA389D /* CAAnimationGroup+LAAnimatableGroup.m */; };
|
||||
@@ -90,6 +89,11 @@
|
||||
62FE41C21D46886600CA389D /* goftldalt.json in Resources */ = {isa = PBXBuildFile; fileRef = 62FE41BE1D46886600CA389D /* goftldalt.json */; };
|
||||
62FE41C31D46886600CA389D /* govtid.json in Resources */ = {isa = PBXBuildFile; fileRef = 62FE41BF1D46886600CA389D /* govtid.json */; };
|
||||
62FE41C41D46886600CA389D /* selfie.json in Resources */ = {isa = PBXBuildFile; fileRef = 62FE41C01D46886600CA389D /* selfie.json */; };
|
||||
62FE41C61D46D5C900CA389D /* masktest.json in Resources */ = {isa = PBXBuildFile; fileRef = 62FE41C51D46D5C900CA389D /* masktest.json */; };
|
||||
62FE41C81D47D92E00CA389D /* masksAndSolids.json in Resources */ = {isa = PBXBuildFile; fileRef = 62FE41C71D47D92E00CA389D /* masksAndSolids.json */; };
|
||||
62FE41CB1D48004A00CA389D /* LAEllipseShapeLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FE41CA1D48004A00CA389D /* LAEllipseShapeLayer.m */; };
|
||||
62FE41CD1D4804E400CA389D /* circleTest.json in Resources */ = {isa = PBXBuildFile; fileRef = 62FE41CC1D4804E400CA389D /* circleTest.json */; };
|
||||
62FE41D31D4829E100CA389D /* LAShapeTrimPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 62FE41D21D4829E100CA389D /* LAShapeTrimPath.m */; };
|
||||
F5B4E946F7B28B4594824641 /* libPods-LotteAnimator.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BC68632413866F85CEACB7EA /* libPods-LotteAnimator.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -150,8 +154,6 @@
|
||||
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>"; };
|
||||
620CD7E31D38180800055AD1 /* LAGroupLayerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAGroupLayerView.h; sourceTree = "<group>"; };
|
||||
@@ -214,6 +216,13 @@
|
||||
62FE41BE1D46886600CA389D /* goftldalt.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = goftldalt.json; sourceTree = "<group>"; };
|
||||
62FE41BF1D46886600CA389D /* govtid.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = govtid.json; sourceTree = "<group>"; };
|
||||
62FE41C01D46886600CA389D /* selfie.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = selfie.json; sourceTree = "<group>"; };
|
||||
62FE41C51D46D5C900CA389D /* masktest.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = masktest.json; sourceTree = "<group>"; };
|
||||
62FE41C71D47D92E00CA389D /* masksAndSolids.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = masksAndSolids.json; sourceTree = "<group>"; };
|
||||
62FE41C91D48004A00CA389D /* LAEllipseShapeLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAEllipseShapeLayer.h; sourceTree = "<group>"; };
|
||||
62FE41CA1D48004A00CA389D /* LAEllipseShapeLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAEllipseShapeLayer.m; sourceTree = "<group>"; };
|
||||
62FE41CC1D4804E400CA389D /* circleTest.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = circleTest.json; sourceTree = "<group>"; };
|
||||
62FE41D11D4829E100CA389D /* LAShapeTrimPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LAShapeTrimPath.h; sourceTree = "<group>"; };
|
||||
62FE41D21D4829E100CA389D /* LAShapeTrimPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LAShapeTrimPath.m; sourceTree = "<group>"; };
|
||||
AEE1A33E4CE2F6024DE7793E /* 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 = "<group>"; };
|
||||
BC68632413866F85CEACB7EA /* libPods-LotteAnimator.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-LotteAnimator.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
@@ -277,6 +286,8 @@
|
||||
486BE04D1D36F1BE00CD14A0 /* LAShapeLayerView.m */,
|
||||
62FE40E61D3FFBB400CA389D /* LARectShapeLayer.h */,
|
||||
62FE40E71D3FFBB400CA389D /* LARectShapeLayer.m */,
|
||||
62FE41C91D48004A00CA389D /* LAEllipseShapeLayer.h */,
|
||||
62FE41CA1D48004A00CA389D /* LAEllipseShapeLayer.m */,
|
||||
4804B2FD1C1F55E600DA8AF7 /* ViewController.h */,
|
||||
4804B2FE1C1F55E600DA8AF7 /* ViewController.m */,
|
||||
48372A621C20A91C00AD0293 /* LAJSONExplorerViewController.h */,
|
||||
@@ -315,6 +326,8 @@
|
||||
48372A4E1C1F99C600AD0293 /* LAShapeGroup.m */,
|
||||
48372A561C209A6C00AD0293 /* LAShapeStroke.h */,
|
||||
48372A571C209A6C00AD0293 /* LAShapeStroke.m */,
|
||||
62FE41D11D4829E100CA389D /* LAShapeTrimPath.h */,
|
||||
62FE41D21D4829E100CA389D /* LAShapeTrimPath.m */,
|
||||
48372A591C209A7A00AD0293 /* LAShapeFill.h */,
|
||||
48372A5A1C209A7A00AD0293 /* LAShapeFill.m */,
|
||||
48372A5C1C209A8900AD0293 /* LAShapeTransform.h */,
|
||||
@@ -345,6 +358,9 @@
|
||||
48372A651C20B04300AD0293 /* JSONExamples */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
62FE41CC1D4804E400CA389D /* circleTest.json */,
|
||||
62FE41C71D47D92E00CA389D /* masksAndSolids.json */,
|
||||
62FE41C51D46D5C900CA389D /* masktest.json */,
|
||||
62FE41BD1D46886600CA389D /* allset.json */,
|
||||
62FE41BE1D46886600CA389D /* goftldalt.json */,
|
||||
62FE41BF1D46886600CA389D /* govtid.json */,
|
||||
@@ -413,8 +429,6 @@
|
||||
62FE40E41D3FF78800CA389D /* LAAnimatableBoundsValue.m */,
|
||||
620CD7CE1D343A2500055AD1 /* LAAnimatableScaleValue.h */,
|
||||
620CD7CF1D343A2500055AD1 /* LAAnimatableScaleValue.m */,
|
||||
620CD7CB1D3415F000055AD1 /* LAAnimatableRectValue.h */,
|
||||
620CD7CC1D3415F000055AD1 /* LAAnimatableRectValue.m */,
|
||||
62FE408B1D3EC81C00CA389D /* CAAnimationGroup+LAAnimatableGroup.h */,
|
||||
62FE408C1D3EC81C00CA389D /* CAAnimationGroup+LAAnimatableGroup.m */,
|
||||
);
|
||||
@@ -505,6 +519,7 @@
|
||||
4804B3041C1F55E600DA8AF7 /* Assets.xcassets in Resources */,
|
||||
62FE40D11D3EDC7400CA389D /* 062_AnimateTransformParented.json in Resources */,
|
||||
62FE40D71D3EDC7400CA389D /* 100_House_AnimateInAndOut.json in Resources */,
|
||||
62FE41CD1D4804E400CA389D /* circleTest.json in Resources */,
|
||||
62FE40D41D3EDC7400CA389D /* 071_AnimatePathShape.json in Resources */,
|
||||
62FE40CE1D3EDC7400CA389D /* 058_AnimateTransformPositionHoldKeyframe.json in Resources */,
|
||||
62FE40CC1D3EDC7400CA389D /* 056_AnimateTransformPositionCustomEaseIn.json in Resources */,
|
||||
@@ -522,6 +537,7 @@
|
||||
62FE40CA1D3EDC7400CA389D /* 054_AnimateTransformPositionEaseOut.json in Resources */,
|
||||
62FE40B51D3EDC7400CA389D /* 002_ShapeLayerLine_01.json in Resources */,
|
||||
62FE40DD1D3FF0D900CA389D /* Heart58OnOff.json in Resources */,
|
||||
62FE41C81D47D92E00CA389D /* masksAndSolids.json in Resources */,
|
||||
62FE40B81D3EDC7400CA389D /* 005_TwoShapeLayerSquaresDifferent_01.json in Resources */,
|
||||
62FE40C01D3EDC7400CA389D /* 013_ShapeMasked_01.json in Resources */,
|
||||
486BE04B1D36E06C00CD14A0 /* newMoovin.json in Resources */,
|
||||
@@ -539,6 +555,7 @@
|
||||
62FE40EA1D401C0700CA389D /* scaleTest.json in Resources */,
|
||||
62FE40BE1D3EDC7400CA389D /* 011_MergePaths_01.json in Resources */,
|
||||
62FE40BC1D3EDC7400CA389D /* 009_ShapeLayerRepeater_01.json in Resources */,
|
||||
62FE41C61D46D5C900CA389D /* masktest.json in Resources */,
|
||||
62FE40C21D3EDC7400CA389D /* 015_DottedLine_01.json in Resources */,
|
||||
62FE40CD1D3EDC7400CA389D /* 057_AnimateTransformPositionCustomEaseInout.json in Resources */,
|
||||
);
|
||||
@@ -602,9 +619,11 @@
|
||||
4804B31E1C1F757600DA8AF7 /* UIColor+Expanded.m in Sources */,
|
||||
4804B2FF1C1F55E600DA8AF7 /* ViewController.m in Sources */,
|
||||
48372A641C20A91C00AD0293 /* LAJSONExplorerViewController.m in Sources */,
|
||||
62FE41D31D4829E100CA389D /* LAShapeTrimPath.m in Sources */,
|
||||
62FE41431D41862200CA389D /* LAAnimatableLayer.m in Sources */,
|
||||
620A56651D1C81930030EBFB /* LAAnimatableShapeValue.m in Sources */,
|
||||
4804B3191C1F6DEA00DA8AF7 /* LAComposition.m in Sources */,
|
||||
62FE41CB1D48004A00CA389D /* LAEllipseShapeLayer.m in Sources */,
|
||||
4804B2FC1C1F55E600DA8AF7 /* AppDelegate.m in Sources */,
|
||||
4804B3211C1F761800DA8AF7 /* BWMath.m in Sources */,
|
||||
62FE40E51D3FF78800CA389D /* LAAnimatableBoundsValue.m in Sources */,
|
||||
@@ -626,7 +645,6 @@
|
||||
48372A551C209A5F00AD0293 /* LAShapePath.m in Sources */,
|
||||
620CD7E51D38180800055AD1 /* LAGroupLayerView.m in Sources */,
|
||||
48372AB71C20D97200AD0293 /* LAShapeCircle.m in Sources */,
|
||||
620CD7CD1D3415F000055AD1 /* LAAnimatableRectValue.m in Sources */,
|
||||
620A565C1D1C81610030EBFB /* LAAnimatableColorValue.m in Sources */,
|
||||
48372A5E1C209A8900AD0293 /* LAShapeTransform.m in Sources */,
|
||||
62FE41BC1D42DD8500CA389D /* LAMaskLayer.m in Sources */,
|
||||
|
||||
Binary file not shown.
@@ -67,13 +67,13 @@
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LotteAnimator/LAShapeCircle.m"
|
||||
timestampString = "490729764.635343"
|
||||
filePath = "LotteAnimator/LAMaskLayer.m"
|
||||
timestampString = "491264085.840767"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "14"
|
||||
endingLineNumber = "14"
|
||||
landmarkName = "-initWithJSON:frameRate:"
|
||||
startingLineNumber = "54"
|
||||
endingLineNumber = "54"
|
||||
landmarkName = "-renderInContext:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
@@ -83,13 +83,13 @@
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LotteAnimator/LAAnimatableScaleValue.m"
|
||||
timestampString = "490740783.490737"
|
||||
filePath = "LotteAnimator/LAMaskLayer.m"
|
||||
timestampString = "491264087.213296"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "82"
|
||||
endingLineNumber = "82"
|
||||
landmarkName = "-_buildAnimationForKeyframes:"
|
||||
startingLineNumber = "50"
|
||||
endingLineNumber = "50"
|
||||
landmarkName = "-drawInContext:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
@@ -100,7 +100,7 @@
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LotteAnimator/LAAnimatableLayer.m"
|
||||
timestampString = "490920717.958644"
|
||||
timestampString = "491266116.833188"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "56"
|
||||
@@ -109,53 +109,5 @@
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LotteAnimator/LALayerView.m"
|
||||
timestampString = "490921111.145475"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "128"
|
||||
endingLineNumber = "128"
|
||||
landmarkName = "-_setupViewFromModel"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LotteAnimator/CAAnimationGroup+LAAnimatableGroup.m"
|
||||
timestampString = "490920346.033008"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "14"
|
||||
endingLineNumber = "14"
|
||||
landmarkName = "+animationGroupForAnimatablePropertiesWithKeyPaths:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "LotteAnimator/CAAnimationGroup+LAAnimatableGroup.m"
|
||||
timestampString = "490920366.856974"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "29"
|
||||
endingLineNumber = "29"
|
||||
landmarkName = "+animationGroupForAnimatablePropertiesWithKeyPaths:"
|
||||
landmarkType = "5">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
||||
|
||||
@@ -93,5 +93,4 @@
|
||||
layer.beginTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
//
|
||||
// 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 frameRate:(NSNumber *)frameRate;
|
||||
|
||||
@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) NSTimeInterval delay;
|
||||
@property (nonatomic, readonly) NSTimeInterval duration;
|
||||
@property (nonatomic, readonly) BOOL hasAnimation;
|
||||
@property (nonatomic, readonly) NSNumber *startFrame;
|
||||
@property (nonatomic, readonly) NSNumber *durationFrames;
|
||||
@property (nonatomic, readonly) NSNumber *frameRate;
|
||||
|
||||
- (CAKeyframeAnimation *)animationForKeyPath:(NSString *)keypath;
|
||||
|
||||
@end
|
||||
@@ -1,22 +0,0 @@
|
||||
//
|
||||
// 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 frameRate:(NSNumber *)frameRate {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_frameRate = frameRate;
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -28,11 +28,20 @@
|
||||
NSMutableDictionary *layerMap = [NSMutableDictionary dictionary];
|
||||
|
||||
NSArray *reversedItems = [[_sceneModel.layers reverseObjectEnumerator] allObjects];
|
||||
|
||||
|
||||
LALayerView *maskedLayer = nil;
|
||||
for (LALayer *layer in reversedItems) {
|
||||
LALayerView *layerView = [[LALayerView alloc] initWithModel:layer inComposition:_sceneModel];
|
||||
layerMap[layer.layerID] = layerView;
|
||||
[self.layer addSublayer:layerView];
|
||||
if (maskedLayer) {
|
||||
maskedLayer.mask = layerView;
|
||||
maskedLayer = nil;
|
||||
} else {
|
||||
if (layer.matteType == LAMatteTypeAdd) {
|
||||
maskedLayer = layerView;
|
||||
}
|
||||
[self.layer addSublayer:layerView];
|
||||
}
|
||||
}
|
||||
_layerMap = layerMap;
|
||||
}
|
||||
|
||||
20
LotteAnimator/LAEllipseShapeLayer.h
Normal file
20
LotteAnimator/LAEllipseShapeLayer.h
Normal file
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// LAEllipseShapeLayer.h
|
||||
// LotteAnimator
|
||||
//
|
||||
// Created by brandon_withrow on 7/26/16.
|
||||
// Copyright © 2016 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAAnimatableLayer.h"
|
||||
|
||||
@interface LAEllipseShapeLayer : LAAnimatableLayer
|
||||
|
||||
- (instancetype)initWithEllipseShape:(LAShapeCircle *)circleShape
|
||||
fill:(LAShapeFill *)fill
|
||||
stroke:(LAShapeStroke *)stroke
|
||||
trim:(LAShapeTrimPath *)trim
|
||||
transform:(LAShapeTransform *)transform
|
||||
withDuration:(NSTimeInterval)duration;
|
||||
|
||||
@end
|
||||
121
LotteAnimator/LAEllipseShapeLayer.m
Normal file
121
LotteAnimator/LAEllipseShapeLayer.m
Normal file
@@ -0,0 +1,121 @@
|
||||
//
|
||||
// LAEllipseShapeLayer.m
|
||||
// LotteAnimator
|
||||
//
|
||||
// Created by brandon_withrow on 7/26/16.
|
||||
// Copyright © 2016 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAEllipseShapeLayer.h"
|
||||
#import "CAAnimationGroup+LAAnimatableGroup.h"
|
||||
|
||||
@implementation LAEllipseShapeLayer {
|
||||
LAShapeTransform *_transform;
|
||||
LAShapeStroke *_stroke;
|
||||
LAShapeFill *_fill;
|
||||
LAShapeCircle *_circle;
|
||||
LAShapeTrimPath *_trim;
|
||||
|
||||
CAShapeLayer *_fillLayer;
|
||||
CAShapeLayer *_strokeLayer;
|
||||
|
||||
CAAnimationGroup *_animation;
|
||||
CAAnimationGroup *_strokeAnimation;
|
||||
CAAnimationGroup *_fillAnimation;
|
||||
}
|
||||
|
||||
- (instancetype)initWithEllipseShape:(LAShapeCircle *)circleShape
|
||||
fill:(LAShapeFill *)fill
|
||||
stroke:(LAShapeStroke *)stroke
|
||||
trim:(LAShapeTrimPath *)trim
|
||||
transform:(LAShapeTransform *)transform
|
||||
withDuration:(NSTimeInterval)duration {
|
||||
self = [super initWithDuration:duration];
|
||||
if (self) {
|
||||
_circle = circleShape;
|
||||
_stroke = stroke;
|
||||
_fill = fill;
|
||||
_transform = transform;
|
||||
_trim = trim;
|
||||
|
||||
self.allowsEdgeAntialiasing = YES;
|
||||
self.frame = _transform.compBounds;
|
||||
self.anchorPoint = _transform.anchor.initialPoint;
|
||||
self.opacity = _transform.opacity.initialValue.floatValue;
|
||||
self.position = _transform.position.initialPoint;
|
||||
self.transform = _transform.scale.initialScale;
|
||||
self.sublayerTransform = CATransform3DMakeRotation(_transform.rotation.initialValue.floatValue, 0, 0, 1);
|
||||
|
||||
if (fill) {
|
||||
_fillLayer = [CAShapeLayer new];
|
||||
_fillLayer.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-50, -50, 100, 100)].CGPath;
|
||||
_fillLayer.allowsEdgeAntialiasing = YES;
|
||||
_fillLayer.position = circleShape.position.initialPoint;
|
||||
_fillLayer.transform = circleShape.scale.initialScale;
|
||||
_fillLayer.fillColor = _fill.color.initialColor.CGColor;
|
||||
_fillLayer.opacity = _fill.opacity.initialValue.floatValue;
|
||||
[self addSublayer:_fillLayer];
|
||||
}
|
||||
|
||||
if (stroke) {
|
||||
_strokeLayer = [CAShapeLayer new];
|
||||
_strokeLayer.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-50, -50, 100, 100)].CGPath;
|
||||
_strokeLayer.allowsEdgeAntialiasing = YES;
|
||||
_strokeLayer.position = circleShape.position.initialPoint;
|
||||
_strokeLayer.transform = circleShape.scale.initialScale;
|
||||
_strokeLayer.strokeColor = _stroke.color.initialColor.CGColor;
|
||||
_strokeLayer.opacity = _stroke.opacity.initialValue.floatValue;
|
||||
_strokeLayer.lineWidth = _stroke.width.initialValue.floatValue;
|
||||
_strokeLayer.fillColor = nil;
|
||||
_strokeLayer.backgroundColor = nil;
|
||||
_strokeLayer.lineDashPattern = _stroke.lineDashPattern;
|
||||
if (trim) {
|
||||
_strokeLayer.strokeStart = _trim.start.initialValue.floatValue;
|
||||
_strokeLayer.strokeEnd = _trim.end.initialValue.floatValue;
|
||||
}
|
||||
[self addSublayer:_strokeLayer];
|
||||
}
|
||||
self.animationSublayers = [NSArray arrayWithArray:self.sublayers];
|
||||
|
||||
[self _buildAnimation];
|
||||
[self pause];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_buildAnimation {
|
||||
if (_transform) {
|
||||
_animation = [CAAnimationGroup animationGroupForAnimatablePropertiesWithKeyPaths:@{@"opacity" : _transform.opacity,
|
||||
@"position" : _transform.position,
|
||||
@"anchorPoint" : _transform.anchor,
|
||||
@"transform" : _transform.scale,
|
||||
@"sublayerTransform.rotation" : _transform.rotation}];
|
||||
[self addAnimation:_animation forKey:@"LotteAnimation"];
|
||||
}
|
||||
|
||||
if (_stroke) {
|
||||
NSMutableDictionary *properties = [NSMutableDictionary dictionaryWithDictionary:@{@"strokeColor" : _stroke.color,
|
||||
@"opacity" : _stroke.opacity,
|
||||
@"lineWidth" : _stroke.width,
|
||||
@"position" : _circle.position,
|
||||
@"transform" : _circle.scale}];
|
||||
if (_trim) {
|
||||
properties[@"strokeStart"] = _trim.start;
|
||||
properties[@"strokeEnd"] = _trim.end;
|
||||
}
|
||||
_strokeAnimation = [CAAnimationGroup animationGroupForAnimatablePropertiesWithKeyPaths:properties];
|
||||
[_strokeLayer addAnimation:_strokeAnimation forKey:@""];
|
||||
|
||||
}
|
||||
|
||||
if (_fill) {
|
||||
_fillAnimation = [CAAnimationGroup animationGroupForAnimatablePropertiesWithKeyPaths:@{@"backgroundColor" : _fill.color,
|
||||
@"opacity" : _fill.opacity,
|
||||
@"position" : _circle.position,
|
||||
@"transform" : _circle.scale}];
|
||||
[_fillLayer addAnimation:_fillAnimation forKey:@""];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -9,6 +9,8 @@
|
||||
#import "LAGroupLayerView.h"
|
||||
#import "LAShapeLayerView.h"
|
||||
#import "LARectShapeLayer.h"
|
||||
#import "LAEllipseShapeLayer.h"
|
||||
|
||||
#import "CAAnimationGroup+LAAnimatableGroup.h"
|
||||
|
||||
@implementation LAGroupLayerView {
|
||||
@@ -45,6 +47,7 @@
|
||||
LAShapeFill *currentFill;
|
||||
LAShapeStroke *currentStroke;
|
||||
LAShapeTransform *currentTransform;
|
||||
LAShapeTrimPath *currentTrim;
|
||||
|
||||
NSMutableArray *shapeLayers = [NSMutableArray array];
|
||||
NSMutableArray *groupLayers = [NSMutableArray array];
|
||||
@@ -56,11 +59,14 @@
|
||||
currentStroke = item;
|
||||
} else if ([item isKindOfClass:[LAShapeFill class]]) {
|
||||
currentFill = item;
|
||||
} else if ([item isKindOfClass:[LAShapeTrimPath class]]) {
|
||||
currentTrim = item;
|
||||
} else if ([item isKindOfClass:[LAShapePath class]]) {
|
||||
LAShapePath *shapePath = (LAShapePath *)item;
|
||||
LAShapeLayerView *shapeLayer = [[LAShapeLayerView alloc] initWithShape:shapePath
|
||||
fill:currentFill
|
||||
stroke:currentStroke
|
||||
trim:currentTrim
|
||||
transform:currentTransform
|
||||
withDuration:self.laAnimationDuration];
|
||||
[shapeLayers addObject:shapeLayer];
|
||||
@@ -74,6 +80,16 @@
|
||||
withDuration:self.laAnimationDuration];
|
||||
[shapeLayers addObject:shapeLayer];
|
||||
[self addSublayer:shapeLayer];
|
||||
} else if ([item isKindOfClass:[LAShapeCircle class]]) {
|
||||
LAShapeCircle *shapeCircle = (LAShapeCircle *)item;
|
||||
LAEllipseShapeLayer *shapeLayer = [[LAEllipseShapeLayer alloc] initWithEllipseShape:shapeCircle
|
||||
fill:currentFill
|
||||
stroke:currentStroke
|
||||
trim:currentTrim
|
||||
transform:currentTransform
|
||||
withDuration:self.laAnimationDuration];
|
||||
[shapeLayers addObject:shapeLayer];
|
||||
[self addSublayer:shapeLayer];
|
||||
} else if ([item isKindOfClass:[LAShapeGroup class]]) {
|
||||
LAShapeGroup *shapeGroup = (LAShapeGroup *)item;
|
||||
LAGroupLayerView *groupLayer = [[LAGroupLayerView alloc] initWithShapeGroup:shapeGroup
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
@class LAAnimatableColorValue;
|
||||
@class LAAnimatablePointValue;
|
||||
@class LAAnimatableNumberValue;
|
||||
@class LAAnimatableRectValue;
|
||||
@class LAAnimatableScaleValue;
|
||||
@class LAComposition;
|
||||
|
||||
@@ -26,6 +25,13 @@ typedef enum : NSInteger {
|
||||
LALayerTypeShape
|
||||
} LALayerType;
|
||||
|
||||
typedef enum : NSInteger {
|
||||
LAMatteTypeNone,
|
||||
LAMatteTypeAdd,
|
||||
LAMatteTypeInvert,
|
||||
LALayerTypeUknown
|
||||
} LAMatteType;
|
||||
|
||||
@interface LALayer : NSObject
|
||||
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary fromComposition:(LAComposition *)composition;
|
||||
@@ -42,8 +48,9 @@ typedef enum : NSInteger {
|
||||
@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) NSNumber *solidWidth;
|
||||
@property (nonatomic, readonly) NSNumber *solidHeight;
|
||||
@property (nonatomic, readonly) UIColor *solidColor;
|
||||
|
||||
@property (nonatomic, readonly) LAAnimatableNumberValue *opacity;
|
||||
@property (nonatomic, readonly) LAAnimatableNumberValue *rotation;
|
||||
@@ -59,4 +66,6 @@ typedef enum : NSInteger {
|
||||
@property (nonatomic, readonly) NSArray *inOutKeyTimes;
|
||||
@property (nonatomic, readonly) NSTimeInterval compDuration;
|
||||
|
||||
@property (nonatomic, readonly) LAMatteType matteType;
|
||||
|
||||
@end
|
||||
|
||||
@@ -42,8 +42,10 @@
|
||||
_outFrame = [jsonDictionary[@"op"] copy];
|
||||
|
||||
if (_layerType == LALayerTypeSolid) {
|
||||
// TODO Solids.
|
||||
|
||||
_solidWidth = jsonDictionary[@"sw"];
|
||||
_solidHeight = jsonDictionary[@"sh"];
|
||||
NSString *solidColor = jsonDictionary[@"sc"];
|
||||
_solidColor = [UIColor colorWithHexString:solidColor];
|
||||
}
|
||||
NSDictionary *ks = jsonDictionary[@"ks"];
|
||||
|
||||
@@ -78,6 +80,9 @@
|
||||
_scale = [[LAAnimatableScaleValue alloc] initWithScaleValues:scale frameRate:_framerate];
|
||||
}
|
||||
|
||||
_matteType = [jsonDictionary[@"tt"] integerValue];
|
||||
|
||||
|
||||
NSMutableArray *masks = [NSMutableArray array];
|
||||
for (NSDictionary *maskJSON in jsonDictionary[@"masksProperties"]) {
|
||||
LAMask *mask = [[LAMask alloc] initWithJSON:maskJSON frameRate:_framerate];
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#import "LAShapeLayerView.h"
|
||||
#import "LAGroupLayerView.h"
|
||||
#import "CAAnimationGroup+LAAnimatableGroup.h"
|
||||
#import "LAMaskLayer.h"
|
||||
|
||||
@interface LAParentLayer : LAAnimatableLayer
|
||||
|
||||
@@ -59,7 +60,7 @@
|
||||
CAKeyframeAnimation *_inOutAnimation;
|
||||
NSArray<LAParentLayer *> *_parentLayers;
|
||||
LAComposition *_composition;
|
||||
|
||||
LAMaskLayer *_maskLayer;
|
||||
}
|
||||
|
||||
- (instancetype)initWithModel:(LALayer *)model inComposition:(LAComposition *)comp {
|
||||
@@ -73,9 +74,18 @@
|
||||
}
|
||||
|
||||
- (void)_setupViewFromModel {
|
||||
self.bounds = _composition.compBounds;
|
||||
self.backgroundColor = nil;
|
||||
if (_layerModel.layerType == LALayerTypeSolid) {
|
||||
self.bounds = CGRectMake(0, 0, _layerModel.solidWidth.floatValue, _layerModel.solidHeight.floatValue);
|
||||
} else {
|
||||
self.bounds = _composition.compBounds;
|
||||
}
|
||||
|
||||
self.anchorPoint = CGPointZero;
|
||||
|
||||
_childContainerLayer = [CALayer new];
|
||||
_childContainerLayer.bounds = self.bounds;
|
||||
_childContainerLayer.backgroundColor = _layerModel.solidColor.CGColor;
|
||||
self.animationSublayers = @[_childContainerLayer];
|
||||
|
||||
NSNumber *parentID = _layerModel.parentID;
|
||||
@@ -121,9 +131,29 @@
|
||||
|
||||
_shapeLayers = shapeLayers;
|
||||
|
||||
// CALayer *anchorLayer = [CALayer new];
|
||||
// anchorLayer.bounds = CGRectMake(0, 0, 20, 20);
|
||||
// anchorLayer.backgroundColor = [UIColor redColor].CGColor;
|
||||
// anchorLayer.anchorPoint = CGPointMake(0.5, 0.5);
|
||||
// anchorLayer.position = CGPointZero;
|
||||
// anchorLayer.opacity = 0.25;
|
||||
// _childContainerLayer.borderWidth = 6;
|
||||
// _childContainerLayer.backgroundColor = [UIColor greenColor].CGColor;
|
||||
// _childContainerLayer.borderColor = [UIColor redColor].CGColor;
|
||||
// [_childContainerLayer addSublayer:anchorLayer];
|
||||
|
||||
if (_layerModel.masks) {
|
||||
_maskLayer = [[LAMaskLayer alloc] initWithMasks:_layerModel.masks inComposition:_composition];
|
||||
_maskLayer.opacity = 0.5;
|
||||
[_childContainerLayer addSublayer:_maskLayer];
|
||||
}
|
||||
|
||||
NSMutableArray *childLayers = [NSMutableArray array];
|
||||
[childLayers addObjectsFromArray:_parentLayers];
|
||||
[childLayers addObjectsFromArray:_shapeLayers];
|
||||
if (_maskLayer) {
|
||||
[childLayers addObject:_maskLayer];
|
||||
}
|
||||
self.childLayers = childLayers;
|
||||
|
||||
[self _buildAnimations];
|
||||
|
||||
@@ -7,14 +7,17 @@
|
||||
//
|
||||
|
||||
#import "LAMaskLayer.h"
|
||||
#import "CAAnimationGroup+LAAnimatableGroup.h"
|
||||
|
||||
@implementation LAMaskLayer {
|
||||
LAComposition *_composition;
|
||||
NSArray *_maskLayers;
|
||||
}
|
||||
|
||||
- (instancetype)initWithMasks:(NSArray<LAMask *> *)masks inComposition:(LAComposition *)comp {
|
||||
self = [super initWithDuration:comp.timeDuration];
|
||||
if (self) {
|
||||
// self.bounds = comp.compBounds;
|
||||
_masks = masks;
|
||||
_composition = comp;
|
||||
[self _setupViewFromModel];
|
||||
@@ -23,6 +26,31 @@
|
||||
}
|
||||
|
||||
- (void)_setupViewFromModel {
|
||||
NSMutableArray *maskLayers = [NSMutableArray array];
|
||||
|
||||
for (LAMask *mask in _masks) {
|
||||
CAShapeLayer *maskLayer = [CAShapeLayer new];
|
||||
maskLayer.path = mask.maskPath.initialShape.CGPath;
|
||||
maskLayer.fillColor = [UIColor whiteColor].CGColor;
|
||||
maskLayer.opacity = mask.opacity.initialValue.floatValue;
|
||||
[self addSublayer:maskLayer];
|
||||
CAAnimationGroup *animGroup = [CAAnimationGroup animationGroupForAnimatablePropertiesWithKeyPaths:@{@"opacity" : mask.opacity,
|
||||
@"path" : mask.maskPath}];
|
||||
if (animGroup) {
|
||||
[maskLayer addAnimation:animGroup forKey:@""];
|
||||
}
|
||||
[maskLayers addObject:maskLayer];
|
||||
}
|
||||
_maskLayers = maskLayers;
|
||||
self.animationSublayers = maskLayers;
|
||||
[self pause];
|
||||
}
|
||||
|
||||
- (void)drawInContext:(CGContextRef)ctx {
|
||||
|
||||
}
|
||||
|
||||
-(void)renderInContext:(CGContextRef)ctx {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
#import "LAAnimatableColorValue.h"
|
||||
#import "LAAnimatableNumberValue.h"
|
||||
#import "LAAnimatablePointValue.h"
|
||||
#import "LAAnimatableRectValue.h"
|
||||
#import "LAAnimatableScaleValue.h"
|
||||
#import "LAAnimatableShapeValue.h"
|
||||
#import "LAShapeTrimPath.h"
|
||||
|
||||
#endif /* LAModels_h */
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
@interface LARectShapeLayer : LAAnimatableLayer
|
||||
|
||||
- (instancetype)initWithRectShape:(LAShapeRectangle *)rectShape
|
||||
fill:(LAShapeFill *)fill
|
||||
stroke:(LAShapeStroke *)stroke
|
||||
transform:(LAShapeTransform *)transform
|
||||
fill:(LAShapeFill *)fill
|
||||
stroke:(LAShapeStroke *)stroke
|
||||
transform:(LAShapeTransform *)transform
|
||||
withDuration:(NSTimeInterval)duration;
|
||||
|
||||
@end
|
||||
|
||||
@@ -43,24 +43,30 @@
|
||||
self.transform = _transform.scale.initialScale;
|
||||
self.sublayerTransform = CATransform3DMakeRotation(_transform.rotation.initialValue.floatValue, 0, 0, 1);
|
||||
|
||||
_fillLayer = [CALayer layer];
|
||||
_fillLayer.allowsEdgeAntialiasing = YES;
|
||||
_fillLayer.bounds = rectShape.bounds.initialBounds;
|
||||
_fillLayer.position = rectShape.position.initialPoint;
|
||||
_fillLayer.cornerRadius = rectShape.cornerRadius.initialValue.floatValue;
|
||||
_fillLayer.backgroundColor = _fill.color.initialColor.CGColor;
|
||||
_fillLayer.opacity = _fill.opacity.initialValue.floatValue;
|
||||
[self addSublayer:_fillLayer];
|
||||
if (fill) {
|
||||
_fillLayer = [CALayer layer];
|
||||
_fillLayer.allowsEdgeAntialiasing = YES;
|
||||
_fillLayer.bounds = rectShape.bounds.initialBounds;
|
||||
_fillLayer.position = rectShape.position.initialPoint;
|
||||
_fillLayer.cornerRadius = rectShape.cornerRadius.initialValue.floatValue;
|
||||
_fillLayer.backgroundColor = _fill.color.initialColor.CGColor;
|
||||
_fillLayer.opacity = _fill.opacity.initialValue.floatValue;
|
||||
[self addSublayer:_fillLayer];
|
||||
}
|
||||
|
||||
if (stroke) {
|
||||
_strokeLayer = [CALayer layer];
|
||||
_strokeLayer.allowsEdgeAntialiasing = YES;
|
||||
_strokeLayer.bounds = rectShape.bounds.initialBounds;
|
||||
_strokeLayer.position = rectShape.position.initialPoint;
|
||||
_strokeLayer.cornerRadius = rectShape.cornerRadius.initialValue.floatValue;
|
||||
_strokeLayer.borderColor = _stroke.color.initialColor.CGColor;
|
||||
_strokeLayer.opacity = _stroke.opacity.initialValue.floatValue;
|
||||
_strokeLayer.borderWidth = _stroke.width.initialValue.floatValue;
|
||||
_strokeLayer.backgroundColor = nil;
|
||||
}
|
||||
self.animationSublayers = [NSArray arrayWithArray:self.sublayers];
|
||||
|
||||
_strokeLayer = [CALayer layer];
|
||||
_strokeLayer.allowsEdgeAntialiasing = YES;
|
||||
_strokeLayer.bounds = rectShape.bounds.initialBounds;
|
||||
_strokeLayer.position = rectShape.position.initialPoint;
|
||||
_strokeLayer.cornerRadius = rectShape.cornerRadius.initialValue.floatValue;
|
||||
_strokeLayer.borderColor = _stroke.color.initialColor.CGColor;
|
||||
_strokeLayer.opacity = _stroke.opacity.initialValue.floatValue;
|
||||
_strokeLayer.borderWidth = _stroke.width.initialValue.floatValue;
|
||||
_strokeLayer.backgroundColor = nil;
|
||||
[self addSublayer:_strokeLayer];
|
||||
[self _buildAnimation];
|
||||
[self pause];
|
||||
|
||||
@@ -12,4 +12,7 @@
|
||||
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;
|
||||
|
||||
@property (nonatomic, readonly) LAAnimatablePointValue *position;
|
||||
@property (nonatomic, readonly) LAAnimatableScaleValue *scale;
|
||||
|
||||
@end
|
||||
|
||||
@@ -19,7 +19,16 @@
|
||||
}
|
||||
|
||||
- (void)_mapFromJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate {
|
||||
NSDictionary *position = jsonDictionary[@"p"];
|
||||
if (position) {
|
||||
_position = [[LAAnimatablePointValue alloc] initWithPointValues:position frameRate:frameRate];
|
||||
_position.usePathAnimation = NO;
|
||||
}
|
||||
|
||||
NSDictionary *scale = jsonDictionary[@"s"];
|
||||
if (scale) {
|
||||
_scale = [[LAAnimatableScaleValue alloc] initWithScaleValues:scale frameRate:frameRate];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#import "LAShapeStroke.h"
|
||||
#import "LAShapeTransform.h"
|
||||
#import "LAShapeRectangle.h"
|
||||
#import "LAShapeTrimPath.h"
|
||||
|
||||
@implementation LAShapeGroup
|
||||
|
||||
@@ -51,6 +52,9 @@
|
||||
} else if ([type isEqualToString:@"rc"]) {
|
||||
LAShapeRectangle *rectangle = [[LAShapeRectangle alloc] initWithJSON:itemJSON frameRate:frameRate];
|
||||
[items addObject:rectangle];
|
||||
} else if ([type isEqualToString:@"tm"]) {
|
||||
LAShapeTrimPath *trim = [[LAShapeTrimPath alloc] initWithJSON:itemJSON frameRate:frameRate];
|
||||
[items addObject:trim];
|
||||
}
|
||||
}
|
||||
_items = items;
|
||||
|
||||
@@ -14,9 +14,8 @@
|
||||
- (instancetype)initWithShape:(LAShapePath *)shape
|
||||
fill:(LAShapeFill *)fill
|
||||
stroke:(LAShapeStroke *)stroke
|
||||
trim:(LAShapeTrimPath *)trim
|
||||
transform:(LAShapeTransform *)transform
|
||||
withDuration:(NSTimeInterval)duration;
|
||||
|
||||
- (void)startAnimation;
|
||||
|
||||
@end
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
LAShapeStroke *_stroke;
|
||||
LAShapeFill *_fill;
|
||||
LAShapePath *_path;
|
||||
LAShapeTrimPath *_trim;
|
||||
|
||||
CAShapeLayer *_fillLayer;
|
||||
CAShapeLayer *_strokeLayer;
|
||||
@@ -26,6 +27,7 @@
|
||||
- (instancetype)initWithShape:(LAShapePath *)shape
|
||||
fill:(LAShapeFill *)fill
|
||||
stroke:(LAShapeStroke *)stroke
|
||||
trim:(LAShapeTrimPath *)trim
|
||||
transform:(LAShapeTransform *)transform
|
||||
withDuration:(NSTimeInterval)duration {
|
||||
self = [super initWithDuration:duration];
|
||||
@@ -34,6 +36,7 @@
|
||||
_stroke = stroke;
|
||||
_fill = fill;
|
||||
_transform = transform;
|
||||
_trim = trim;
|
||||
|
||||
self.allowsEdgeAntialiasing = YES;
|
||||
self.frame = _transform.compBounds;
|
||||
@@ -43,26 +46,43 @@
|
||||
self.transform = _transform.scale.initialScale;
|
||||
self.sublayerTransform = CATransform3DMakeRotation(_transform.rotation.initialValue.floatValue, 0, 0, 1);
|
||||
|
||||
_fillLayer = [CAShapeLayer layer];
|
||||
_fillLayer.allowsEdgeAntialiasing = YES;
|
||||
_fillLayer.path = _path.shapePath.initialShape.CGPath;
|
||||
_fillLayer.fillColor = _fill.color.initialColor.CGColor;
|
||||
_fillLayer.opacity = _fill.opacity.initialValue.floatValue;
|
||||
[self addSublayer:_fillLayer];
|
||||
if (fill) {
|
||||
_fillLayer = [CAShapeLayer layer];
|
||||
_fillLayer.allowsEdgeAntialiasing = YES;
|
||||
_fillLayer.path = _path.shapePath.initialShape.CGPath;
|
||||
_fillLayer.fillColor = _fill.color.initialColor.CGColor;
|
||||
_fillLayer.opacity = _fill.opacity.initialValue.floatValue;
|
||||
[self addSublayer:_fillLayer];
|
||||
}
|
||||
|
||||
_strokeLayer = [CAShapeLayer layer];
|
||||
_strokeLayer.allowsEdgeAntialiasing = YES;
|
||||
_strokeLayer.path = _path.shapePath.initialShape.CGPath;
|
||||
_strokeLayer.strokeColor = _stroke.color.initialColor.CGColor;
|
||||
_strokeLayer.opacity = _stroke.opacity.initialValue.floatValue;
|
||||
_strokeLayer.lineWidth = _stroke.width.initialValue.floatValue;
|
||||
_strokeLayer.fillColor = nil;
|
||||
self.animationSublayers = @[_fillLayer, _strokeLayer];
|
||||
if (stroke) {
|
||||
_strokeLayer = [CAShapeLayer layer];
|
||||
_strokeLayer.allowsEdgeAntialiasing = YES;
|
||||
_strokeLayer.path = _path.shapePath.initialShape.CGPath;
|
||||
_strokeLayer.strokeColor = _stroke.color.initialColor.CGColor;
|
||||
_strokeLayer.opacity = _stroke.opacity.initialValue.floatValue;
|
||||
_strokeLayer.lineWidth = _stroke.width.initialValue.floatValue;
|
||||
_strokeLayer.lineDashPattern = _stroke.lineDashPattern;
|
||||
if (trim) {
|
||||
_strokeLayer.strokeStart = _trim.start.initialValue.floatValue;
|
||||
_strokeLayer.strokeEnd = _trim.end.initialValue.floatValue;
|
||||
}
|
||||
_strokeLayer.fillColor = nil;
|
||||
}
|
||||
|
||||
self.animationSublayers = [NSArray arrayWithArray:self.sublayers];
|
||||
[self addSublayer:_strokeLayer];
|
||||
[self _buildAnimation];
|
||||
[self pause];
|
||||
|
||||
|
||||
// CALayer *anchorLayer = [CALayer new];
|
||||
// anchorLayer.bounds = CGRectMake(0, 0, 10, 10);
|
||||
// anchorLayer.backgroundColor = [UIColor blueColor].CGColor;
|
||||
// anchorLayer.anchorPoint = CGPointMake(0.5, 0.5);
|
||||
// anchorLayer.position = CGPointZero;
|
||||
// self.borderColor = [UIColor blueColor].CGColor;
|
||||
// self.borderWidth = 2;
|
||||
// [self addSublayer:anchorLayer];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -78,10 +98,15 @@
|
||||
}
|
||||
|
||||
if (_stroke) {
|
||||
_strokeAnimation = [CAAnimationGroup animationGroupForAnimatablePropertiesWithKeyPaths:@{@"strokeColor" : _stroke.color,
|
||||
@"opacity" : _stroke.opacity,
|
||||
@"lineWidth" : _stroke.width,
|
||||
@"path" : _path.shapePath}];
|
||||
NSMutableDictionary *properties = [NSMutableDictionary dictionaryWithDictionary:@{@"strokeColor" : _stroke.color,
|
||||
@"opacity" : _stroke.opacity,
|
||||
@"lineWidth" : _stroke.width,
|
||||
@"path" : _path.shapePath}];
|
||||
if (_trim) {
|
||||
properties[@"strokeStart"] = _trim.start;
|
||||
properties[@"strokeEnd"] = _trim.end;
|
||||
}
|
||||
_strokeAnimation = [CAAnimationGroup animationGroupForAnimatablePropertiesWithKeyPaths:properties];
|
||||
[_strokeLayer addAnimation:_strokeAnimation forKey:@""];
|
||||
}
|
||||
|
||||
|
||||
@@ -19,5 +19,6 @@
|
||||
@property (nonatomic, readonly) LAAnimatableColorValue *color;
|
||||
@property (nonatomic, readonly) LAAnimatableNumberValue *opacity;
|
||||
@property (nonatomic, readonly) LAAnimatableNumberValue *width;
|
||||
@property (nonatomic, readonly) NSArray *lineDashPattern;
|
||||
|
||||
@end
|
||||
|
||||
@@ -39,6 +39,20 @@
|
||||
|
||||
NSNumber *fillEnabled = jsonDictionary[@"fillEnabled"];
|
||||
_fillEnabled = fillEnabled.boolValue;
|
||||
|
||||
NSArray *dashes = jsonDictionary[@"d"];
|
||||
if (dashes) {
|
||||
NSMutableArray *dashPattern = [NSMutableArray array];
|
||||
for (NSDictionary *dash in dashes) {
|
||||
if ([dash[@"n"] isEqualToString:@"o"]) {
|
||||
continue;
|
||||
}
|
||||
NSDictionary *value = dash[@"v"];
|
||||
LAAnimatableNumberValue *numberValue = [[LAAnimatableNumberValue alloc] initWithNumberValues:value frameRate:frameRate];
|
||||
[dashPattern addObject:[numberValue.initialValue copy]];
|
||||
}
|
||||
_lineDashPattern = dashPattern;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
19
LotteAnimator/LAShapeTrimPath.h
Normal file
19
LotteAnimator/LAShapeTrimPath.h
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// LAShapeTrimPath.h
|
||||
// LotteAnimator
|
||||
//
|
||||
// Created by brandon_withrow on 7/26/16.
|
||||
// Copyright © 2016 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
@class LAAnimatableNumberValue;
|
||||
|
||||
@interface LAShapeTrimPath : NSObject
|
||||
|
||||
- (instancetype)initWithJSON:(NSDictionary *)jsonDictionary frameRate:(NSNumber *)frameRate;
|
||||
|
||||
@property (nonatomic, readonly) LAAnimatableNumberValue *start;
|
||||
@property (nonatomic, readonly) LAAnimatableNumberValue *end;
|
||||
|
||||
@end
|
||||
35
LotteAnimator/LAShapeTrimPath.m
Normal file
35
LotteAnimator/LAShapeTrimPath.m
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// LAShapeTrimPath.m
|
||||
// LotteAnimator
|
||||
//
|
||||
// Created by brandon_withrow on 7/26/16.
|
||||
// Copyright © 2016 Brandon Withrow. All rights reserved.
|
||||
//
|
||||
|
||||
#import "LAShapeTrimPath.h"
|
||||
|
||||
@implementation LAShapeTrimPath
|
||||
|
||||
- (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 {
|
||||
NSDictionary *start = jsonDictionary[@"s"];
|
||||
if (start) {
|
||||
_start = [[LAAnimatableNumberValue alloc] initWithNumberValues:start frameRate:frameRate];
|
||||
[_start remapValuesFromMin:@0 fromMax:@100 toMin:@0 toMax:@1];
|
||||
}
|
||||
|
||||
NSDictionary *end = jsonDictionary[@"e"];
|
||||
if (end) {
|
||||
_end = [[LAAnimatableNumberValue alloc] initWithNumberValues:end frameRate:frameRate];
|
||||
[_end remapValuesFromMin:@0 fromMax:@100 toMin:@0 toMax:@1];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -359,7 +359,8 @@ static NSMutableDictionary *colorNameCache = nil;
|
||||
// Returns a UIColor by scanning the string for a hex number and passing that to +[UIColor colorWithRGBHex:]
|
||||
// Skips any leading whitespace and ignores any trailing characters
|
||||
+ (UIColor *)colorWithHexString:(NSString *)stringToConvert {
|
||||
NSScanner *scanner = [NSScanner scannerWithString:stringToConvert];
|
||||
NSString *strippedString = [stringToConvert stringByReplacingOccurrencesOfString:@"#" withString:@""];
|
||||
NSScanner *scanner = [NSScanner scannerWithString:strippedString];
|
||||
unsigned hexNum;
|
||||
if (![scanner scanHexInt:&hexNum]) return nil;
|
||||
return [UIColor colorWithRGBHex:hexNum];
|
||||
|
||||
1
LotteAnimator/circleTest.json
Normal file
1
LotteAnimator/circleTest.json
Normal file
@@ -0,0 +1 @@
|
||||
{"assets":[],"v":"4.1.7","ddd":0,"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"Shape Layer 2","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[300,300,0]},"a":{"k":[0,0,0]},"s":{"k":[100,247.571,100]}},"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[140.039,147.461],"e":[28.039,29.525],"__fnct":[null,null]},{"t":98}]},"p":{"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[0,0],"e":[-87,69],"to":[-14.5,11.5],"ti":[14.5,-11.5]},{"t":98}]},"nm":"Ellipse Path 1","closed":true},{"d":1,"ty":"el","s":{"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[140.039,147.461],"e":[28.039,29.525],"__fnct":[null,null]},{"t":98}]},"p":{"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[0,0],"e":[-87,69],"to":[-14.5,11.5],"ti":[14.5,-11.5]},{"t":98}]},"nm":"Ellipse Path 1","closed":true},{"ty":"st","fillEnabled":true,"c":{"k":[255,255,255,255]},"o":{"k":100},"w":{"k":2},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1"},{"ty":"fl","fillEnabled":true,"c":{"k":[255,255,255,255]},"o":{"k":100},"nm":"Fill 1"},{"ty":"tr","p":{"k":[48.98,-45.27]},"a":{"k":[0,0]},"s":{"k":[100,100]},"r":{"k":0},"o":{"k":100},"sk":{"k":0},"sa":{"k":0}}],"nm":"Ellipse 1"}],"bounds":{"l":-121,"t":-147,"b":95,"r":146},"ip":0,"op":180,"st":0},{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[300,300,0]},"a":{"k":[0,0,0]},"s":{"k":[100,100,100]}},"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[200,200]},"p":{"k":[0,0]},"nm":"Ellipse Path 1","closed":true},{"d":1,"ty":"el","s":{"k":[200,200]},"p":{"k":[0,0]},"nm":"Ellipse Path 1","closed":true},{"ty":"st","fillEnabled":true,"c":{"k":[255,255,255,255]},"o":{"k":100},"w":{"k":2},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1"},{"ty":"fl","fillEnabled":true,"c":{"k":[201,26,26,255]},"o":{"k":100},"nm":"Fill 1"},{"ty":"tr","p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"r":{"k":0},"o":{"k":100},"sk":{"k":0},"sa":{"k":0}}],"nm":"Ellipse 1"}],"bounds":{"l":-137,"t":-137,"b":137,"r":137},"ip":0,"op":180,"st":0}],"ip":0,"op":180,"fr":60,"w":600,"h":600}
|
||||
1
LotteAnimator/masksAndSolids.json
Normal file
1
LotteAnimator/masksAndSolids.json
Normal file
@@ -0,0 +1 @@
|
||||
{"assets":[],"v":"4.1.7","ddd":0,"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"Shape Layer 1","td":1,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[306,300,0]},"a":{"k":[0,0,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[51.741,51.741,100],"e":[122.667,122.667,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":90,"s":[122.667,122.667,100],"e":[70.07,70.07,100]},{"t":174}]}},"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"k":[275.75,275.75]},"p":{"k":[0,0]},"nm":"Ellipse Path 1","closed":true},{"d":1,"ty":"el","s":{"k":[275.75,275.75]},"p":{"k":[0,0]},"nm":"Ellipse Path 1","closed":true},{"ty":"st","fillEnabled":true,"c":{"k":[255,255,255,255]},"o":{"k":100},"w":{"k":2},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1"},{"ty":"fl","fillEnabled":true,"c":{"k":[255,255,255,255]},"o":{"k":100},"nm":"Fill 1"},{"ty":"tr","p":{"k":[-4.789,-1.113]},"a":{"k":[0,0]},"s":{"k":[100,100]},"r":{"k":0},"o":{"k":100},"sk":{"k":0},"sa":{"k":0}}],"nm":"Ellipse 1"}],"bounds":{"l":-193,"t":-189,"b":187,"r":183},"ip":0,"op":180,"st":0},{"ddd":0,"ind":1,"ty":1,"nm":"Cyan Solid 1","tt":2,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[300,300,0]},"a":{"k":[300,300,0]},"s":{"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":0,"s":[100,100,100],"e":[59,59,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"n":["0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167","0p833_0p833_0p167_0p167"],"t":90,"s":[59,59,100],"e":[108,108,100]},{"t":174}]}},"sw":600,"sh":600,"sc":"#00ffc7","ip":0,"op":180,"st":0},{"ddd":0,"ind":2,"ty":1,"nm":"Medium Purple Solid 2","td":1,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[300,300,0]},"a":{"k":[300,300,0]},"s":{"k":[100,100,100]}},"sw":600,"sh":600,"sc":"#9f5eff","ip":0,"op":180,"st":0},{"ddd":0,"ind":3,"ty":1,"nm":"Medium Purple Solid 1","tt":1,"ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[300,300,0]},"a":{"k":[300,300,0]},"s":{"k":[100,100,100]}},"sw":600,"sh":600,"sc":"#9f5eff","ip":0,"op":180,"st":0}],"ip":0,"op":180,"fr":60,"w":600,"h":600}
|
||||
1
LotteAnimator/masktest.json
Normal file
1
LotteAnimator/masktest.json
Normal file
@@ -0,0 +1 @@
|
||||
{"assets":[],"v":"4.1.7","ddd":0,"layers":[{"ddd":0,"ind":0,"ty":4,"nm":"Shape Layer 1","ks":{"o":{"k":100},"r":{"k":0},"p":{"k":[300,300,0]},"a":{"k":[0,0,0]},"s":{"k":[100,100,100]}},"hasMask":true,"masksProperties":[{"cl":true,"inv":false,"mode":"a","pt":{"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-276,-245],[-201,111.355],[-208.645,-140.645],[30.355,-120]]}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-276,-245],[-253,177.355],[147.355,192.355],[64.355,-153]]}]},{"t":72}]},"o":{"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[0],"e":[100]},{"t":30}]},"x":{"k":0},"nm":"Mask 1"},{"cl":true,"inv":false,"mode":"a","pt":{"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-152,-76],[-149,49.355],[-47.645,42.355],[-46.645,-72]]}},"o":{"k":100},"x":{"k":0},"nm":"Mask 2"}],"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"k":[231.355,231.355]},"p":{"k":[0,0]},"r":{"k":20},"nm":"Rectangle Path 1","closed":true},{"ty":"st","fillEnabled":true,"c":{"k":[255,255,255,255]},"o":{"k":100},"w":{"k":2},"lc":1,"lj":1,"ml":4,"nm":"Stroke 1"},{"ty":"fl","fillEnabled":true,"c":{"k":[255,255,255,255]},"o":{"k":100},"nm":"Fill 1"},{"ty":"tr","p":{"k":[-85.322,-4.322]},"a":{"k":[0,0]},"s":{"k":[100,100]},"r":{"k":0},"o":{"k":100},"sk":{"k":0},"sa":{"k":0}}],"nm":"Rectangle 1"}],"bounds":{"l":-277,"t":-196,"b":187,"r":106},"ip":0,"op":180,"st":0}],"ip":0,"op":180,"fr":60,"w":600,"h":600}
|
||||
Reference in New Issue
Block a user