Skip to content

Commit

Permalink
Merge pull request #347 from airbnb/btw/setAnimation
Browse files Browse the repository at this point in the history
Add support for setting animation after init
  • Loading branch information
buba447 committed Aug 4, 2017
2 parents 54fa86a + fe00994 commit a45b806
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 18 deletions.
19 changes: 10 additions & 9 deletions Example/Example for lottie-macos/LAMainView.m
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,17 @@ - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
}

- (void)_openAnimationFile:(NSString *)file {
[self.lottieLogo removeFromSuperview];
self.lottieLogo = nil;

self.lottieLogo = [LOTAnimationView animationWithFilePath:file];
self.lottieLogo.contentMode = LOTViewContentModeScaleAspectFit;
self.lottieLogo.frame = self.bounds;
self.lottieLogo.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;

[self addSubview:self.lottieLogo positioned:NSWindowBelow relativeTo:nil];
[self.lottieLogo play];
NSError *error;
NSData *jsonData = [[NSData alloc] initWithContentsOfFile:file];
NSDictionary *JSONObject = jsonData ? [NSJSONSerialization JSONObjectWithData:jsonData
options:0 error:&error] : nil;
if (JSONObject && !error) {
LOTComposition *laScene = [[LOTComposition alloc] initWithJSON:JSONObject withAssetBundle:[NSBundle mainBundle]];
laScene.rootDirectory = [file stringByDeletingLastPathComponent];
self.lottieLogo.sceneModel = laScene;
[self.lottieLogo play];
}
}

- (void)setAnimationProgress:(CGFloat)progress {
Expand Down
80 changes: 72 additions & 8 deletions lottie-ios/Classes/Private/LOTAnimationView.m
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ + (nonnull instancetype)animationWithFilePath:(nonnull NSString *)filePath {
- (instancetype)initWithContentsOfURL:(NSURL *)url {
self = [super initWithFrame:CGRectZero];
if (self) {
[self _commonInit];
LOTComposition *laScene = [[LOTAnimationCache sharedCache] animationForKey:url.absoluteString];
if (laScene) {
self.cacheKey = url.absoluteString;
Expand Down Expand Up @@ -123,6 +124,7 @@ - (instancetype)initWithModel:(LOTComposition *)model inBundle:(NSBundle *)bundl
self = [super initWithFrame:model.compBounds];
if (self) {
_bundle = bundle;
[self _commonInit];
[self _initializeAnimationContainer];
[self _setupWithSceneModel:model];
}
Expand All @@ -145,19 +147,45 @@ - (void)_initializeAnimationContainer {

#endif

- (void)_setupWithSceneModel:(LOTComposition *)model {
_cacheEnable = YES;
- (void)_commonInit {
_animationSpeed = 1;
_animationProgress = 0;
_loopAnimation = NO;
_autoReverseAnimation = NO;
}

- (void)setSceneModel:(LOTComposition *)sceneModel {
_sceneModel = sceneModel;
[self _setupWithSceneModel:sceneModel];
}

- (void)_setupWithSceneModel:(LOTComposition *)model {
if (_sceneModel) {
[self _removeCurrentAnimationIfNecessary];
[self _callCompletionIfNecessary:NO];
[_compContainer removeFromSuperlayer];
_compContainer = nil;
_sceneModel = nil;
[self _commonInit];
}

_sceneModel = model;
[CATransaction begin];
[CATransaction setDisableActions:YES];
_compContainer = [[LOTCompositionContainer alloc] initWithModel:nil inLayerGroup:nil withLayerGroup:_sceneModel.layerGroup withAssestGroup:_sceneModel.assetGroup];
[self.layer addSublayer:_compContainer];
_compContainer.currentFrame = @0;
[CATransaction commit];
if (ENABLE_DEBUG_LOGGING) {
[self logHierarchyKeypaths];
}
[self _restoreState];
[self setNeedsLayout];
}

- (void)_restoreState {
if (_isAnimationPlaying) {
_isAnimationPlaying = NO;
[self playWithCompletion:self.completionBlock];
} else {
self.animationProgress = _animationProgress;
}
}

# pragma mark - External Methods
Expand Down Expand Up @@ -193,6 +221,10 @@ - (void)playFromFrame:(nonnull NSNumber *)fromStartFrame
if (_isAnimationPlaying) {
return;
}
if (!_sceneModel) {
_isAnimationPlaying = YES;
return;
}
if (_animationProgress == 1) {
self.animationProgress = 0;
}
Expand Down Expand Up @@ -222,6 +254,10 @@ - (void)stop {
}

- (void)pause {
if (!_sceneModel) {
_isAnimationPlaying = NO;
return;
}
_playAnimation.delegate = nil;
_playAnimation.speed = 0;
NSNumber *frame = [_compContainer.presentationLayer.currentFrame copy];
Expand All @@ -237,7 +273,7 @@ - (void)pause {

- (void)setLoopAnimation:(BOOL)loopAnimation {
_loopAnimation = loopAnimation;
if (_isAnimationPlaying) {
if (_isAnimationPlaying && _sceneModel) {

NSNumber *frame = [(LOTCompositionContainer *)_compContainer.presentationLayer currentFrame];
NSNumber *start = _playAnimation.fromValue;
Expand All @@ -251,6 +287,9 @@ - (void)setLoopAnimation:(BOOL)loopAnimation {
}

- (void)setProgressWithFrame:(nonnull NSNumber *)currentFrame {
if (!_sceneModel) {
return;
}
[self _removeCurrentAnimationIfNecessary];
[self _callCompletionIfNecessary:NO];
_animationProgress = currentFrame.floatValue / (_sceneModel.endFrame.floatValue - _sceneModel.startFrame.floatValue);
Expand All @@ -273,6 +312,13 @@ - (void)setCacheEnable:(BOOL)cacheEnable{
}
}

- (void)setCacheKey:(NSString *)cacheKey {
_cacheKey = cacheKey;
if (cacheKey) {
_cacheEnable = YES;
}
}

#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR

- (void)addSubview:(nonnull LOTView *)view
Expand Down Expand Up @@ -343,6 +389,10 @@ - (void)_callCompletionIfNecessary:(BOOL)complete {
# pragma mark - Getters and Setters

- (void)setAnimationProgress:(CGFloat)animationProgress {
if (!_sceneModel) {
_animationProgress = animationProgress;
return;
}
[self _removeCurrentAnimationIfNecessary];
[self _callCompletionIfNecessary:NO];
CGFloat duration = _sceneModel.endFrame.floatValue - _sceneModel.startFrame.floatValue;
Expand All @@ -356,8 +406,22 @@ - (void)setAnimationProgress:(CGFloat)animationProgress {
}

-(void)setAnimationSpeed:(CGFloat)animationSpeed {
if (!_sceneModel) {
_animationSpeed = animationSpeed;
return;
}
_animationSpeed = animationSpeed;
_playAnimation.speed = animationSpeed;
if (_isAnimationPlaying) {

NSNumber *frame = [(LOTCompositionContainer *)_compContainer.presentationLayer currentFrame];
NSNumber *start = _playAnimation.fromValue;
NSNumber *end = _playAnimation.toValue;
[self _removeCurrentAnimationIfNecessary];

_compContainer.currentFrame = frame;
_animationProgress = frame.floatValue / (_sceneModel.endFrame.floatValue - _sceneModel.startFrame.floatValue);
[self playFromFrame:start toFrame:end withCompletion:self.completionBlock];
}
}

# pragma mark - Overrides
Expand Down
1 change: 0 additions & 1 deletion lottie-ios/Classes/Private/LOTAnimationView_Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ typedef enum : NSUInteger {

@interface LOTAnimationView () <CAAnimationDelegate>

@property (nonatomic, readonly) LOTComposition * _Nonnull sceneModel;
@property (nonatomic, copy, nullable) NSString *cacheKey;

@end
3 changes: 3 additions & 0 deletions lottie-ios/Classes/PublicHeaders/LOTAnimationView.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ typedef void (^LOTAnimationCompletionBlock)(BOOL animationFinished);
/// Sets a completion block to call when the animation has completed
@property (nonatomic, copy, nullable) LOTAnimationCompletionBlock completionBlock;

/// Set the amimation data
@property (nonatomic, strong, nonnull) LOTComposition *sceneModel;

/*
* Plays the animation from its current position to a specific progress.
* The animation will start from its current position.
Expand Down

0 comments on commit a45b806

Please sign in to comment.