diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj index 99f327e284..40700d44c4 100644 --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -109,7 +109,7 @@ 1C236B19E4FFE960ECFDD34836883DD7 /* LAMask.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LAMask.m; sourceTree = ""; }; 1CCA5FDF7C65573AE79C4F072417CFDC /* LAShapeGroup.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LAShapeGroup.h; sourceTree = ""; }; 1E93382328AAEDDFF2CCA4D3A9BAEBBF /* LAShapeTrimPath.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LAShapeTrimPath.m; sourceTree = ""; }; - 23F6708733ECBC2C3A04347EBA5837B0 /* Pods_Lottie_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_Lottie_Example.framework; path = "Pods-Lottie-Example.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 23F6708733ECBC2C3A04347EBA5837B0 /* Pods_Lottie_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Lottie_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 2D9CFD668AB15AD6B7CFE597BA9790E5 /* LAShapeStroke.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LAShapeStroke.h; sourceTree = ""; }; 2DC01D5F7B5EBC356E0FB20DC94C658C /* Pods-lottie-ios_Tests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-lottie-ios_Tests-resources.sh"; sourceTree = ""; }; 3168398BDCECCBDC1C7E675FD0F865BE /* LAShapeTransform.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LAShapeTransform.h; sourceTree = ""; }; @@ -137,7 +137,7 @@ 67AF90A5097C29BC3A2C9D0EEA1B8965 /* LAComposition.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LAComposition.h; sourceTree = ""; }; 6810DA145A9F737648B2F7EBE001C879 /* LAAnimatableValue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LAAnimatableValue.h; sourceTree = ""; }; 6854FA93BA0760E539699367915E0AE1 /* LAEllipseShapeLayer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LAEllipseShapeLayer.h; sourceTree = ""; }; - 68A56E0FC68E08FCDABB5196B8B15F57 /* Pods_lottie_ios_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_lottie_ios_Tests.framework; path = "Pods-lottie-ios_Tests.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 68A56E0FC68E08FCDABB5196B8B15F57 /* Pods_lottie_ios_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_lottie_ios_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 69F2F9742D08E2243309184475E202B5 /* lottie-ios-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "lottie-ios-umbrella.h"; sourceTree = ""; }; 6A009F7BB3956DE25B7D98FAAFD9D45C /* LAAnimatableColorValue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LAAnimatableColorValue.h; sourceTree = ""; }; 6E28C846F470114A8720585787867606 /* LAAnimationTransitionController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LAAnimationTransitionController.h; sourceTree = ""; }; @@ -152,12 +152,12 @@ 862D27A5FB1217BE2C4202A609CC9351 /* lottie-ios.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "lottie-ios.xcconfig"; sourceTree = ""; }; 88478EAF17F9D43306DE97A46B4840B3 /* Pods-lottie-ios_Tests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-lottie-ios_Tests-umbrella.h"; sourceTree = ""; }; 897D5AC8BD2547BA2A4D03AF42836005 /* LAShapeGroup.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LAShapeGroup.m; sourceTree = ""; }; - 89C152F786653980BD89744C6E227DE9 /* lottie-ios.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "lottie-ios.modulemap"; sourceTree = ""; }; + 89C152F786653980BD89744C6E227DE9 /* lottie-ios.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "lottie-ios.modulemap"; sourceTree = ""; }; 8B91706714C29EACB9EAA3E6D83F61A7 /* LAModels.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LAModels.h; sourceTree = ""; }; - 8C084E31ED23F75F9BD506F2FB789544 /* Lottie.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Lottie.framework; path = "lottie-ios.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 8C084E31ED23F75F9BD506F2FB789544 /* Lottie.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Lottie.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 8CADA9940CFF80BB8DDD5D016413EBC6 /* LALayer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LALayer.h; sourceTree = ""; }; 915428D3FEC4E1ABADF7768CEBED641A /* Pods-Lottie-Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Lottie-Example-acknowledgements.plist"; sourceTree = ""; }; - 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 95D9A6B420F03D243766ECAEA51BD46E /* LAAnimationView_Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = LAAnimationView_Internal.h; sourceTree = ""; }; 962AF50D4A08AC872FADF0DDD8957A07 /* Pods-lottie-ios_Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-lottie-ios_Tests-acknowledgements.markdown"; sourceTree = ""; }; 9AC54C5E8FDA605DE83310670E321B13 /* CAAnimationGroup+LAAnimatableGroup.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CAAnimationGroup+LAAnimatableGroup.h"; sourceTree = ""; }; @@ -190,8 +190,8 @@ EC8D42FA867193B8064E88A63BF9C091 /* LAShapeLayerView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LAShapeLayerView.m; sourceTree = ""; }; F092DF71F80A4A52929733B0E1293CFF /* LAAnimationView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = LAAnimationView.m; sourceTree = ""; }; F13888D8746B98E5E1C6EF6F81062423 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - F7E393464B8276C00839E29FC416F46F /* Pods-lottie-ios_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "Pods-lottie-ios_Tests.modulemap"; sourceTree = ""; }; - FD338AFDCC777CB0ECD39ED365C90FFE /* Pods-Lottie-Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; path = "Pods-Lottie-Example.modulemap"; sourceTree = ""; }; + F7E393464B8276C00839E29FC416F46F /* Pods-lottie-ios_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-lottie-ios_Tests.modulemap"; sourceTree = ""; }; + FD338AFDCC777CB0ECD39ED365C90FFE /* Pods-Lottie-Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-Lottie-Example.modulemap"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -281,7 +281,6 @@ AD88BCA17AA9E910DA8BD8365D735147 /* LAAnimationView.h */, 7122D191949595366C457D09628D899B /* Lottie.h */, ); - name = PublicHeaders; path = PublicHeaders; sourceTree = ""; }; @@ -327,7 +326,6 @@ children = ( DEFBD51A8FD5AF27519B91304E0F37D6 /* Classes */, ); - name = "lottie-ios"; path = "lottie-ios"; sourceTree = ""; }; @@ -398,7 +396,6 @@ DEEE2366360412C30D658F231D791FE2 /* UIColor+Expanded.m */, 6C8E859BED3150A6861E5B8B9776F764 /* PublicHeaders */, ); - name = Classes; path = Classes; sourceTree = ""; }; diff --git a/Example/lottie-ios.xcodeproj/project.pbxproj b/Example/lottie-ios.xcodeproj/project.pbxproj index e28474221c..7bff3baeed 100644 --- a/Example/lottie-ios.xcodeproj/project.pbxproj +++ b/Example/lottie-ios.xcodeproj/project.pbxproj @@ -267,6 +267,7 @@ 6003F594195388D20070C39A /* Supporting Files */ = { isa = PBXGroup; children = ( + 6003F5B6195388D20070C39A /* Supporting Files */, 48A852301E3A9E71000AD155 /* lottie_logo.png */, 6003F595195388D20070C39A /* lottie-ios-Info.plist */, 6003F596195388D20070C39A /* InfoPlist.strings */, @@ -280,7 +281,6 @@ isa = PBXGroup; children = ( 6003F5BB195388D20070C39A /* Tests.m */, - 6003F5B6195388D20070C39A /* Supporting Files */, ); path = Tests; sourceTree = ""; @@ -306,6 +306,7 @@ 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */, ); name = "Supporting Files"; + path = ../Tests; sourceTree = ""; }; 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */ = { diff --git a/Example/lottie-ios/AnimationExplorerViewController.m b/Example/lottie-ios/AnimationExplorerViewController.m index 5809a99831..eed65a9f51 100644 --- a/Example/lottie-ios/AnimationExplorerViewController.m +++ b/Example/lottie-ios/AnimationExplorerViewController.m @@ -10,8 +10,16 @@ #import "JSONExplorerViewController.h" #import +typedef enum : NSUInteger { + ViewBackgroundColorWhite, + ViewBackgroundColorBlack, + ViewBackgroundColorGreen, + ViewBackgroundColorNone +} ViewBackgroundColor; + @interface AnimationExplorerViewController () +@property (nonatomic, assign) ViewBackgroundColor currentBGColor; @property (nonatomic, strong) UIToolbar *toolbar; @property (nonatomic, strong) UISlider *slider; @property (nonatomic, strong) LAAnimationView *laAnimation; @@ -20,21 +28,49 @@ @implementation AnimationExplorerViewController +- (void)setCurrentBGColor:(ViewBackgroundColor)currentBGColor { + _currentBGColor = currentBGColor; + switch (currentBGColor) { + case ViewBackgroundColorWhite: + self.view.backgroundColor = [UIColor whiteColor]; + break; + case ViewBackgroundColorBlack: + self.view.backgroundColor = [UIColor blackColor]; + break; + case ViewBackgroundColorGreen: + self.view.backgroundColor = [UIColor colorWithRed:50.f/255.f + green:207.f/255.f + blue:193.f/255.f + alpha:1.f]; + break; + case ViewBackgroundColorNone: + self.view.backgroundColor = nil; + break; + default: + break; + } +} + - (void)viewDidLoad { [super viewDidLoad]; - self.view.backgroundColor = [UIColor whiteColor]; + + self.currentBGColor = ViewBackgroundColorWhite; self.toolbar = [[UIToolbar alloc] initWithFrame:CGRectZero]; UIBarButtonItem *open = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks target:self action:@selector(_open:)]; UIBarButtonItem *flx1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; - UIBarButtonItem *rewind = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRewind target:self action:@selector(_rewind:)]; + UIBarButtonItem *openWeb = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(_showURLInput)]; UIBarButtonItem *flx2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; UIBarButtonItem *play = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay target:self action:@selector(_play:)]; UIBarButtonItem *flx3 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; UIBarButtonItem *loop = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(_loop:)]; UIBarButtonItem *flx4 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; + UIBarButtonItem *zoom = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(_setZoom:)]; + UIBarButtonItem *flx5 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; + UIBarButtonItem *bgcolor = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:self action:@selector(_setBGColor:)]; + UIBarButtonItem *flx6 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; UIBarButtonItem *close = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:self action:@selector(_close:)]; - self.toolbar.items = @[open, flx1, rewind, flx2, play, flx3, loop, flx4, close]; + self.toolbar.items = @[open, flx1, openWeb, flx2, loop, flx3, play, flx4, zoom, flx5, bgcolor, flx6, close]; [self.view addSubview:self.toolbar]; [self resetAllButtons]; @@ -74,25 +110,37 @@ } - (void)_open:(UIBarButtonItem *)button { - UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Open Animation" - message:NULL - preferredStyle:UIAlertControllerStyleActionSheet]; - - UIAlertAction *browseAction = [UIAlertAction actionWithTitle:@"Browse" style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { - [self _showJSONExplorer]; - }]; - - [alert addAction:browseAction]; - - UIAlertAction *fromURLAction = [UIAlertAction actionWithTitle:@"Load from URL" style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { - [self _showURLInput]; - }]; - - [alert addAction:fromURLAction]; - - [self presentViewController:alert animated:YES completion:nil]; + [self _showJSONExplorer]; +} + +- (void)_setZoom:(UIBarButtonItem *)button { + switch (self.laAnimation.contentMode) { + case UIViewContentModeScaleAspectFit: { + self.laAnimation.contentMode = UIViewContentModeScaleAspectFill; + [self showMessage:@"Aspect Fill"]; + } break; + case UIViewContentModeScaleAspectFill:{ + self.laAnimation.contentMode = UIViewContentModeScaleToFill; + [self showMessage:@"Scale Fill"]; + } + break; + case UIViewContentModeScaleToFill: { + self.laAnimation.contentMode = UIViewContentModeScaleAspectFit; + [self showMessage:@"Aspect Fit"]; + } + break; + default: + break; + } +} + +- (void)_setBGColor:(UIBarButtonItem *)button { + ViewBackgroundColor current = self.currentBGColor; + current += 1; + if (current == ViewBackgroundColorNone) { + current = ViewBackgroundColorWhite; + } + self.currentBGColor = current; } - (void)_showURLInput { @@ -113,7 +161,7 @@ UIAlertAction *close = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { - [self dismissViewControllerAnimated:YES completion:NULL]; + }]; [alert addAction:close]; @@ -139,7 +187,7 @@ [self resetAllButtons]; self.laAnimation = [[LAAnimationView alloc] initWithContentsOfURL:[NSURL URLWithString:URL]]; - self.laAnimation.contentMode = UIViewContentModeScaleAspectFill; + self.laAnimation.contentMode = UIViewContentModeScaleAspectFit; [self.view addSubview:self.laAnimation]; [self.view setNeedsLayout]; } @@ -150,7 +198,7 @@ [self resetAllButtons]; self.laAnimation = [LAAnimationView animationNamed:named]; - self.laAnimation.contentMode = UIViewContentModeScaleAspectFill; + self.laAnimation.contentMode = UIViewContentModeScaleAspectFit; [self.view addSubview:self.laAnimation]; [self.view setNeedsLayout]; } @@ -175,11 +223,37 @@ - (void)_loop:(UIBarButtonItem *)button { self.laAnimation.loopAnimation = !self.laAnimation.loopAnimation; [self resetButton:button highlighted:self.laAnimation.loopAnimation]; + [self showMessage:self.laAnimation.loopAnimation ? @"Loop Enabled" : @"Loop Disabled"]; } - (void)_close:(UIBarButtonItem *)button { [self.presentingViewController dismissViewControllerAnimated:YES completion:NULL]; } +- (void)showMessage:(NSString *)message { + UILabel *messageLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + messageLabel.textAlignment = NSTextAlignmentCenter; + messageLabel.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5]; + messageLabel.textColor = [UIColor whiteColor]; + messageLabel.text = message; + + CGSize messageSize = [messageLabel sizeThatFits:self.view.bounds.size]; + messageSize.width += 14; + messageSize.height += 14; + messageLabel.frame = CGRectMake(10, 30, messageSize.width, messageSize.height); + messageLabel.alpha = 0; + [self.view addSubview:messageLabel]; + + [UIView animateWithDuration:0.3 animations:^{ + messageLabel.alpha = 1; + } completion:^(BOOL finished) { + [UIView animateWithDuration:0.3 delay:1 options:UIViewAnimationOptionCurveEaseInOut animations:^{ + messageLabel.alpha = 0; + } completion:^(BOOL finished) { + [messageLabel removeFromSuperview]; + }]; + }]; +} + @end diff --git a/lottie-ios/Classes/CGGeometryAdditions.h b/lottie-ios/Classes/CGGeometryAdditions.h index ce76b1c29f..d6d9f930c5 100644 --- a/lottie-ios/Classes/CGGeometryAdditions.h +++ b/lottie-ios/Classes/CGGeometryAdditions.h @@ -102,3 +102,4 @@ CATransform3D CATransform3DSlerpToTransform(CATransform3D fromXorm, CATransform3 CGFloat DegreesToRadians(CGFloat degrees); CGFloat RemapValue(CGFloat value, CGFloat low1, CGFloat high1, CGFloat low2, CGFloat high2 ); +CGPoint CGPointByLerpingPoints(CGPoint point1, CGPoint point2, CGFloat value); diff --git a/lottie-ios/Classes/CGGeometryAdditions.m b/lottie-ios/Classes/CGGeometryAdditions.m index f2587e7d8a..9771b36df9 100644 --- a/lottie-ios/Classes/CGGeometryAdditions.m +++ b/lottie-ios/Classes/CGGeometryAdditions.m @@ -420,3 +420,22 @@ CGFloat DegreesToRadians(CGFloat degrees) { CGFloat RemapValue(CGFloat value, CGFloat low1, CGFloat high1, CGFloat low2, CGFloat high2 ) { return low2 + (value - low1) * (high2 - low2) / (high1 - low1); } + +CGPoint CGPointByLerpingPoints(CGPoint point1, CGPoint point2, CGFloat value) { + CGFloat xDiff = point2.x - point1.x; + CGFloat yDiff = point2.y - point1.y; + CGPoint transposed = CGPointMake(fabs(xDiff), fabs(yDiff)); + CGPoint returnPoint; + if (xDiff == 0 || yDiff == 0) { + returnPoint.x = xDiff == 0 ? point1.x : RemapValue(value, 0, 1, point1.x, point2.x); + returnPoint.y = yDiff == 0 ? point1.y : RemapValue(value, 0, 1, point1.y, point2.y); + } else { + CGFloat rx = transposed.x / transposed.y; + CGFloat yLerp = RemapValue(value, 0, 1, 0, transposed.y); + CGFloat xLerp = yLerp * rx; + CGPoint interpolatedPoint = CGPointMake(point2.x < point1.x ? xLerp * -1 : xLerp, + point2.y < point1.y ? yLerp * -1 : yLerp); + returnPoint = CGPointAddedToPoint(point1, interpolatedPoint); + } + return returnPoint; +} diff --git a/lottie-ios/Classes/LAAnimatableShapeValue.m b/lottie-ios/Classes/LAAnimatableShapeValue.m index 7c82e5f3f4..9b265e439a 100644 --- a/lottie-ios/Classes/LAAnimatableShapeValue.m +++ b/lottie-ios/Classes/LAAnimatableShapeValue.m @@ -179,22 +179,56 @@ for (int i = 1; i < pointsArray.count; i ++) { CGPoint vertex = [self _vertexAtIndex:i inArray:pointsArray]; CGPoint previousVertex = [self _vertexAtIndex:i - 1 inArray:pointsArray]; - CGPoint cp1 = [self _vertexAtIndex:i - 1 inArray:outTangents]; - CGPoint cp2 = [self _vertexAtIndex:i inArray:inTangents]; + CGPoint cp1 = CGPointAddedToPoint(previousVertex, [self _vertexAtIndex:i - 1 inArray:outTangents]); + CGPoint cp2 = CGPointAddedToPoint(vertex, [self _vertexAtIndex:i inArray:inTangents]); + + if (CGPointEqualToPoint(previousVertex, cp1) && + CGPointEqualToPoint(vertex, cp2)) { + // Straight Line + cp1 = CGPointByLerpingPoints(previousVertex, vertex, 0.01); + cp2 = CGPointByLerpingPoints(previousVertex, vertex, 0.99); + } else { + if (CGPointEqualToPoint(previousVertex, cp1)) { + // Missing out tan + cp1 = CGPointByLerpingPoints(previousVertex, cp2, 0.01); + } + + if (CGPointEqualToPoint(vertex, cp2)) { + // Missing in tan + cp2 = CGPointByLerpingPoints(cp1, vertex, 0.99); + } + } [shape addCurveToPoint:vertex - controlPoint1:CGPointAddedToPoint(previousVertex, cp1) - controlPoint2:CGPointAddedToPoint(vertex, cp2)]; + controlPoint1:cp1 + controlPoint2:cp2]; } if (closedPath) { CGPoint vertex = [self _vertexAtIndex:0 inArray:pointsArray]; CGPoint previousVertex = [self _vertexAtIndex:pointsArray.count - 1 inArray:pointsArray]; - CGPoint cp1 = [self _vertexAtIndex:pointsArray.count - 1 inArray:outTangents]; - CGPoint cp2 = [self _vertexAtIndex:0 inArray:inTangents]; + CGPoint cp1 = CGPointAddedToPoint(previousVertex, [self _vertexAtIndex:pointsArray.count - 1 inArray:outTangents]); + CGPoint cp2 = CGPointAddedToPoint(vertex, [self _vertexAtIndex:0 inArray:inTangents]); + if (CGPointEqualToPoint(previousVertex, cp1) && + CGPointEqualToPoint(vertex, cp2)) { + // Straight Line + cp1 = CGPointByLerpingPoints(previousVertex, vertex, 0.01); + cp2 = CGPointByLerpingPoints(previousVertex, vertex, 0.99); + } else { + if (CGPointEqualToPoint(previousVertex, cp1)) { + // Missing out tan + cp1 = CGPointByLerpingPoints(previousVertex, cp2, 0.01); + } + + if (CGPointEqualToPoint(vertex, cp2)) { + // Missing in tan + cp2 = CGPointByLerpingPoints(cp1, vertex, 0.99); + } + } + [shape addCurveToPoint:vertex - controlPoint1:CGPointAddedToPoint(previousVertex, cp1) - controlPoint2:CGPointAddedToPoint(vertex, cp2)]; + controlPoint1:cp1 + controlPoint2:cp2]; [shape closePath]; } diff --git a/lottie-ios/Classes/LAAnimationView.m b/lottie-ios/Classes/LAAnimationView.m index 24ec8902b4..55aec9f9de 100644 --- a/lottie-ios/Classes/LAAnimationView.m +++ b/lottie-ios/Classes/LAAnimationView.m @@ -486,6 +486,11 @@ const NSTimeInterval singleFrameTimeValue = 1.0 / 60.0; [super removeFromSuperview]; } +- (void)setContentMode:(UIViewContentMode)contentMode { + [super setContentMode:contentMode]; + [self setNeedsLayout]; +} + - (void)layoutSubviews { [super layoutSubviews];