12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- //
- // LOTTrimPathNode.m
- // Lottie
- //
- // Created by brandon_withrow on 7/21/17.
- // Copyright © 2017 Airbnb. All rights reserved.
- //
- #import "LOTTrimPathNode.h"
- #import "LOTNumberInterpolator.h"
- #import "LOTPathAnimator.h"
- #import "LOTCircleAnimator.h"
- #import "LOTRoundedRectAnimator.h"
- #import "LOTRenderGroup.h"
- @implementation LOTTrimPathNode {
- LOTNumberInterpolator *_startInterpolator;
- LOTNumberInterpolator *_endInterpolator;
- LOTNumberInterpolator *_offsetInterpolator;
-
- CGFloat _startT;
- CGFloat _endT;
- CGFloat _offsetT;
- }
- - (instancetype _Nonnull)initWithInputNode:(LOTAnimatorNode *_Nullable)inputNode
- trimPath:(LOTShapeTrimPath *_Nonnull)trimPath {
- self = [super initWithInputNode:inputNode keyName:trimPath.keyname];
- if (self) {
- inputNode.pathShouldCacheLengths = YES;
- _startInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:trimPath.start.keyframes];
- _endInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:trimPath.end.keyframes];
- _offsetInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:trimPath.offset.keyframes];
- }
- return self;
- }
- - (NSDictionary *)valueInterpolators {
- return @{@"Start" : _startInterpolator,
- @"End" : _endInterpolator,
- @"Offset" : _offsetInterpolator};
- }
- - (BOOL)needsUpdateForFrame:(NSNumber *)frame {
- return ([_startInterpolator hasUpdateForFrame:frame] ||
- [_endInterpolator hasUpdateForFrame:frame] ||
- [_offsetInterpolator hasUpdateForFrame:frame]);
- }
- - (BOOL)updateWithFrame:(NSNumber *)frame
- withModifierBlock:(void (^ _Nullable)(LOTAnimatorNode * _Nonnull))modifier
- forceLocalUpdate:(BOOL)forceUpdate {
- BOOL localUpdate = [self needsUpdateForFrame:frame];
- [self forceSetCurrentFrame:frame];
- if (localUpdate) {
- [self performLocalUpdate];
- }
- if (self.inputNode == nil) {
- return localUpdate;
- }
-
- BOOL inputUpdated = [self.inputNode updateWithFrame:frame withModifierBlock:^(LOTAnimatorNode * _Nonnull inputNode) {
- if ([inputNode isKindOfClass:[LOTPathAnimator class]] ||
- [inputNode isKindOfClass:[LOTCircleAnimator class]] ||
- [inputNode isKindOfClass:[LOTRoundedRectAnimator class]]) {
- [inputNode.localPath trimPathFromT:self->_startT toT:self->_endT offset:self->_offsetT];
- }
- if (modifier) {
- modifier(inputNode);
- }
-
- } forceLocalUpdate:(localUpdate || forceUpdate)];
-
- return inputUpdated;
- }
- - (void)performLocalUpdate {
- _startT = [_startInterpolator floatValueForFrame:self.currentFrame] / 100;
- _endT = [_endInterpolator floatValueForFrame:self.currentFrame] / 100;
- _offsetT = [_offsetInterpolator floatValueForFrame:self.currentFrame] / 360;
- }
- - (void)rebuildOutputs {
- // Skip this step.
- }
- - (LOTBezierPath *)localPath {
- return self.inputNode.localPath;
- }
- /// Forwards its input node's output path forwards downstream
- - (LOTBezierPath *)outputPath {
- return self.inputNode.outputPath;
- }
- @end
|