LOTRepeaterRenderer.m 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. //
  2. // LOTRepeaterRenderer.m
  3. // Lottie
  4. //
  5. // Created by brandon_withrow on 7/28/17.
  6. // Copyright © 2017 Airbnb. All rights reserved.
  7. //
  8. #import "LOTRepeaterRenderer.h"
  9. #import "LOTTransformInterpolator.h"
  10. #import "LOTNumberInterpolator.h"
  11. #import "LOTHelpers.h"
  12. @implementation LOTRepeaterRenderer {
  13. LOTTransformInterpolator *_transformInterpolator;
  14. LOTNumberInterpolator *_copiesInterpolator;
  15. LOTNumberInterpolator *_offsetInterpolator;
  16. LOTNumberInterpolator *_startOpacityInterpolator;
  17. LOTNumberInterpolator *_endOpacityInterpolator;
  18. CALayer *_instanceLayer;
  19. CAReplicatorLayer *_replicatorLayer;
  20. CALayer *centerPoint_DEBUG;
  21. }
  22. - (instancetype)initWithInputNode:(LOTAnimatorNode *)inputNode
  23. shapeRepeater:(LOTShapeRepeater *)repeater {
  24. self = [super initWithInputNode:inputNode keyName:repeater.keyname];
  25. if (self) {
  26. _transformInterpolator = [[LOTTransformInterpolator alloc] initWithPosition:repeater.position.keyframes
  27. rotation:repeater.rotation.keyframes
  28. anchor:repeater.anchorPoint.keyframes
  29. scale:repeater.scale.keyframes];
  30. _copiesInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:repeater.copies.keyframes];
  31. _offsetInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:repeater.offset.keyframes];
  32. _startOpacityInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:repeater.startOpacity.keyframes];
  33. _endOpacityInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:repeater.endOpacity.keyframes];
  34. _instanceLayer = [CALayer layer];
  35. [self recursivelyAddChildLayers:inputNode];
  36. _replicatorLayer = [CAReplicatorLayer layer];
  37. _replicatorLayer.actions = @{@"instanceCount" : [NSNull null],
  38. @"instanceTransform" : [NSNull null],
  39. @"instanceAlphaOffset" : [NSNull null]};
  40. [_replicatorLayer addSublayer:_instanceLayer];
  41. [self.outputLayer addSublayer:_replicatorLayer];
  42. centerPoint_DEBUG = [CALayer layer];
  43. centerPoint_DEBUG.bounds = CGRectMake(0, 0, 20, 20);
  44. if (ENABLE_DEBUG_SHAPES) {
  45. [self.outputLayer addSublayer:centerPoint_DEBUG];
  46. }
  47. }
  48. return self;
  49. }
  50. - (NSDictionary *)valueInterpolators {
  51. return @{@"Copies" : _copiesInterpolator,
  52. @"Offset" : _offsetInterpolator,
  53. @"Transform.Anchor Point" : _transformInterpolator.anchorInterpolator,
  54. @"Transform.Position" : _transformInterpolator.positionInterpolator,
  55. @"Transform.Scale" : _transformInterpolator.scaleInterpolator,
  56. @"Transform.Rotation" : _transformInterpolator.rotationInterpolator,
  57. @"Transform.Start Opacity" : _startOpacityInterpolator,
  58. @"Transform.End Opacity" : _endOpacityInterpolator};
  59. }
  60. - (void)recursivelyAddChildLayers:(LOTAnimatorNode *)node {
  61. if ([node isKindOfClass:[LOTRenderNode class]]) {
  62. [_instanceLayer addSublayer:[(LOTRenderNode *)node outputLayer]];
  63. }
  64. if (![node isKindOfClass:[LOTRepeaterRenderer class]] &&
  65. node.inputNode) {
  66. [self recursivelyAddChildLayers:node.inputNode];
  67. }
  68. }
  69. - (BOOL)needsUpdateForFrame:(NSNumber *)frame {
  70. // TODO BW Add offset ability
  71. return ([_transformInterpolator hasUpdateForFrame:frame] ||
  72. [_copiesInterpolator hasUpdateForFrame:frame] ||
  73. [_startOpacityInterpolator hasUpdateForFrame:frame] ||
  74. [_endOpacityInterpolator hasUpdateForFrame:frame]);
  75. }
  76. - (void)performLocalUpdate {
  77. centerPoint_DEBUG.backgroundColor = [UIColor greenColor].CGColor;
  78. centerPoint_DEBUG.borderColor = [UIColor lightGrayColor].CGColor;
  79. centerPoint_DEBUG.borderWidth = 2.f;
  80. CGFloat copies = ceilf([_copiesInterpolator floatValueForFrame:self.currentFrame]);
  81. _replicatorLayer.instanceCount = (NSInteger)copies;
  82. _replicatorLayer.instanceTransform = [_transformInterpolator transformForFrame:self.currentFrame];
  83. CGFloat startOpacity = [_startOpacityInterpolator floatValueForFrame:self.currentFrame];
  84. CGFloat endOpacity = [_endOpacityInterpolator floatValueForFrame:self.currentFrame];
  85. CGFloat opacityStep = (endOpacity - startOpacity) / copies;
  86. _instanceLayer.opacity = startOpacity;
  87. _replicatorLayer.instanceAlphaOffset = opacityStep;
  88. }
  89. @end