LOTCompositionContainer.m 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. //
  2. // LOTCompositionContainer.m
  3. // Lottie
  4. //
  5. // Created by brandon_withrow on 7/18/17.
  6. // Copyright © 2017 Airbnb. All rights reserved.
  7. //
  8. #import "LOTCompositionContainer.h"
  9. #import "LOTAsset.h"
  10. #import "CGGeometry+LOTAdditions.h"
  11. #import "LOTHelpers.h"
  12. #import "LOTValueInterpolator.h"
  13. #import "LOTAnimatorNode.h"
  14. #import "LOTRenderNode.h"
  15. #import "LOTRenderGroup.h"
  16. #import "LOTNumberInterpolator.h"
  17. @implementation LOTCompositionContainer {
  18. NSNumber *_frameOffset;
  19. CALayer *DEBUG_Center;
  20. NSMutableDictionary *_keypathCache;
  21. LOTNumberInterpolator *_timeInterpolator;
  22. }
  23. - (instancetype)initWithModel:(LOTLayer *)layer
  24. inLayerGroup:(LOTLayerGroup *)layerGroup
  25. withLayerGroup:(LOTLayerGroup *)childLayerGroup
  26. withAssestGroup:(LOTAssetGroup *)assetGroup {
  27. self = [super initWithModel:layer inLayerGroup:layerGroup];
  28. if (self) {
  29. DEBUG_Center = [CALayer layer];
  30. DEBUG_Center.bounds = CGRectMake(0, 0, 20, 20);
  31. DEBUG_Center.borderColor = [UIColor orangeColor].CGColor;
  32. DEBUG_Center.borderWidth = 2;
  33. DEBUG_Center.masksToBounds = YES;
  34. if (ENABLE_DEBUG_SHAPES) {
  35. [self.wrapperLayer addSublayer:DEBUG_Center];
  36. }
  37. if (layer.startFrame != nil) {
  38. _frameOffset = layer.startFrame;
  39. } else {
  40. _frameOffset = @0;
  41. }
  42. if (layer.timeRemapping) {
  43. _timeInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:layer.timeRemapping.keyframes];
  44. }
  45. [self initializeWithChildGroup:childLayerGroup withAssetGroup:assetGroup];
  46. }
  47. return self;
  48. }
  49. - (void)initializeWithChildGroup:(LOTLayerGroup *)childGroup
  50. withAssetGroup:(LOTAssetGroup *)assetGroup {
  51. NSMutableDictionary *childMap = [NSMutableDictionary dictionary];
  52. NSMutableArray *children = [NSMutableArray array];
  53. NSArray *reversedItems = [[childGroup.layers reverseObjectEnumerator] allObjects];
  54. CALayer *maskedLayer = nil;
  55. for (LOTLayer *layer in reversedItems) {
  56. LOTAsset *asset;
  57. if (layer.referenceID) {
  58. // Get relevant Asset
  59. asset = [assetGroup assetModelForID:layer.referenceID];
  60. }
  61. LOTLayerContainer *child = nil;
  62. if (asset.layerGroup) {
  63. // Layer is a precomp
  64. LOTCompositionContainer *compLayer = [[LOTCompositionContainer alloc] initWithModel:layer inLayerGroup:childGroup withLayerGroup:asset.layerGroup withAssestGroup:assetGroup];
  65. child = compLayer;
  66. } else {
  67. child = [[LOTLayerContainer alloc] initWithModel:layer inLayerGroup:childGroup];
  68. }
  69. if (maskedLayer) {
  70. maskedLayer.mask = child;
  71. maskedLayer = nil;
  72. } else {
  73. if (layer.matteType == LOTMatteTypeAdd) {
  74. maskedLayer = child;
  75. }
  76. [self.wrapperLayer addSublayer:child];
  77. }
  78. [children addObject:child];
  79. if (child.layerName) {
  80. [childMap setObject:child forKey:child.layerName];
  81. }
  82. }
  83. _childMap = childMap;
  84. _childLayers = children;
  85. }
  86. - (void)displayWithFrame:(NSNumber *)frame forceUpdate:(BOOL)forceUpdate {
  87. if (ENABLE_DEBUG_LOGGING) NSLog(@"-------------------- Composition Displaying Frame %@ --------------------", frame);
  88. [super displayWithFrame:frame forceUpdate:forceUpdate];
  89. NSNumber *newFrame = @((frame.floatValue - _frameOffset.floatValue) / self.timeStretchFactor.floatValue);
  90. if (_timeInterpolator) {
  91. newFrame = @([_timeInterpolator floatValueForFrame:newFrame]);
  92. }
  93. for (LOTLayerContainer *child in _childLayers) {
  94. [child displayWithFrame:newFrame forceUpdate:forceUpdate];
  95. }
  96. if (ENABLE_DEBUG_LOGGING) NSLog(@"-------------------- ------------------------------- --------------------");
  97. if (ENABLE_DEBUG_LOGGING) NSLog(@"-------------------- ------------------------------- --------------------");
  98. }
  99. - (void)setViewportBounds:(CGRect)viewportBounds {
  100. [super setViewportBounds:viewportBounds];
  101. for (LOTLayerContainer *layer in _childLayers) {
  102. layer.viewportBounds = viewportBounds;
  103. }
  104. }
  105. - (void)searchNodesForKeypath:(LOTKeypath * _Nonnull)keypath {
  106. if (self.layerName != nil) {
  107. [super searchNodesForKeypath:keypath];
  108. }
  109. if (self.layerName == nil ||
  110. [keypath pushKey:self.layerName]) {
  111. for (LOTLayerContainer *child in _childLayers) {
  112. [child searchNodesForKeypath:keypath];
  113. }
  114. if (self.layerName != nil) {
  115. [keypath popKey];
  116. }
  117. }
  118. }
  119. - (void)setValueDelegate:(id<LOTValueDelegate> _Nonnull)delegate
  120. forKeypath:(LOTKeypath * _Nonnull)keypath {
  121. if (self.layerName != nil) {
  122. [super setValueDelegate:delegate forKeypath:keypath];
  123. }
  124. if (self.layerName == nil ||
  125. [keypath pushKey:self.layerName]) {
  126. for (LOTLayerContainer *child in _childLayers) {
  127. [child setValueDelegate:delegate forKeypath:keypath];
  128. }
  129. if (self.layerName != nil) {
  130. [keypath popKey];
  131. }
  132. }
  133. }
  134. - (nullable NSArray *)keysForKeyPath:(nonnull LOTKeypath *)keypath {
  135. if (_keypathCache == nil) {
  136. _keypathCache = [NSMutableDictionary dictionary];
  137. }
  138. [self searchNodesForKeypath:keypath];
  139. [_keypathCache addEntriesFromDictionary:keypath.searchResults];
  140. return keypath.searchResults.allKeys;
  141. }
  142. - (CALayer *)_layerForKeypath:(nonnull LOTKeypath *)keypath {
  143. id node = _keypathCache[keypath.absoluteKeypath];
  144. if (node == nil) {
  145. [self keysForKeyPath:keypath];
  146. node = _keypathCache[keypath.absoluteKeypath];
  147. }
  148. if (node == nil) {
  149. NSLog(@"LOTComposition could not find layer for keypath:%@", keypath.absoluteKeypath);
  150. return nil;
  151. }
  152. if ([node isKindOfClass:[CALayer class]]) {
  153. return (CALayer *)node;
  154. }
  155. if (![node isKindOfClass:[LOTRenderNode class]]) {
  156. NSLog(@"LOTComposition: Keypath return non-layer node:%@ ", keypath.absoluteKeypath);
  157. return nil;
  158. }
  159. if ([node isKindOfClass:[LOTRenderGroup class]]) {
  160. return [(LOTRenderGroup *)node containerLayer];
  161. }
  162. LOTRenderNode *renderNode = (LOTRenderNode *)node;
  163. return renderNode.outputLayer;
  164. }
  165. - (CGPoint)convertPoint:(CGPoint)point
  166. toKeypathLayer:(nonnull LOTKeypath *)keypath
  167. withParentLayer:(CALayer *_Nonnull)parent{
  168. CALayer *layer = [self _layerForKeypath:keypath];
  169. if (!layer) {
  170. return CGPointZero;
  171. }
  172. return [parent convertPoint:point toLayer:layer];
  173. }
  174. - (CGRect)convertRect:(CGRect)rect
  175. toKeypathLayer:(nonnull LOTKeypath *)keypath
  176. withParentLayer:(CALayer *_Nonnull)parent{
  177. CALayer *layer = [self _layerForKeypath:keypath];
  178. if (!layer) {
  179. return CGRectZero;
  180. }
  181. return [parent convertRect:rect toLayer:layer];
  182. }
  183. - (CGPoint)convertPoint:(CGPoint)point
  184. fromKeypathLayer:(nonnull LOTKeypath *)keypath
  185. withParentLayer:(CALayer *_Nonnull)parent{
  186. CALayer *layer = [self _layerForKeypath:keypath];
  187. if (!layer) {
  188. return CGPointZero;
  189. }
  190. return [parent convertPoint:point fromLayer:layer];
  191. }
  192. - (CGRect)convertRect:(CGRect)rect
  193. fromKeypathLayer:(nonnull LOTKeypath *)keypath
  194. withParentLayer:(CALayer *_Nonnull)parent{
  195. CALayer *layer = [self _layerForKeypath:keypath];
  196. if (!layer) {
  197. return CGRectZero;
  198. }
  199. return [parent convertRect:rect fromLayer:layer];
  200. }
  201. - (void)addSublayer:(nonnull CALayer *)subLayer
  202. toKeypathLayer:(nonnull LOTKeypath *)keypath {
  203. CALayer *layer = [self _layerForKeypath:keypath];
  204. if (layer) {
  205. [layer addSublayer:subLayer];
  206. }
  207. }
  208. - (void)maskSublayer:(nonnull CALayer *)subLayer
  209. toKeypathLayer:(nonnull LOTKeypath *)keypath {
  210. CALayer *layer = [self _layerForKeypath:keypath];
  211. if (layer) {
  212. [layer.superlayer addSublayer:subLayer];
  213. [layer removeFromSuperlayer];
  214. subLayer.mask = layer;
  215. }
  216. }
  217. @end