From 188c1b34c98375a67c7f2b4f64707650efdffdee Mon Sep 17 00:00:00 2001 From: errnull Date: Sun, 7 Apr 2019 17:35:25 +0800 Subject: [PATCH] feat: support muti mask. --- SVGAPlayer.xcodeproj/project.pbxproj | 5 +++ SVGAPlayer/Samples/mutiMask.svga | Bin 0 -> 4289 bytes SVGAPlayer/ViewController.m | 9 ++++- Source/SVGAPlayer.m | 47 ++++++++++++++++++++------- Source/SVGAVideoSpriteEntity.h | 1 + Source/SVGAVideoSpriteEntity.m | 2 ++ 6 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 SVGAPlayer/Samples/mutiMask.svga diff --git a/SVGAPlayer.xcodeproj/project.pbxproj b/SVGAPlayer.xcodeproj/project.pbxproj index b60eb04..ee3d6ab 100644 --- a/SVGAPlayer.xcodeproj/project.pbxproj +++ b/SVGAPlayer.xcodeproj/project.pbxproj @@ -11,6 +11,7 @@ 63712E6521787950001AE014 /* heartbeat.svga in Resources */ = {isa = PBXBuildFile; fileRef = 63712E6421787950001AE014 /* heartbeat.svga */; }; 63712E6821787A45001AE014 /* SVGAAudioEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 63712E6721787A45001AE014 /* SVGAAudioEntity.m */; }; 63E817012178809D001D2D62 /* SVGAAudioLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E817002178809D001D2D62 /* SVGAAudioLayer.m */; }; + 71418C712259FAA30029C69E /* mutiMask.svga in Resources */ = {isa = PBXBuildFile; fileRef = 71418C702259FAA30029C69E /* mutiMask.svga */; }; 80D4C7254846B96B9C6EED83 /* libPods-SVGAPlayer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DDA5FF396660C7C932DF9B8 /* libPods-SVGAPlayer.a */; }; 904D41F81D223DD20085A21A /* SVGABezierPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 904D41F71D223DD20085A21A /* SVGABezierPath.m */; }; 9052FC631E6EB8D4007BC925 /* SVGAExporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 9052FC621E6EB8D4007BC925 /* SVGAExporter.m */; }; @@ -63,6 +64,7 @@ 63712E6721787A45001AE014 /* SVGAAudioEntity.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SVGAAudioEntity.m; sourceTree = ""; }; 63E816FF2178809D001D2D62 /* SVGAAudioLayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SVGAAudioLayer.h; sourceTree = ""; }; 63E817002178809D001D2D62 /* SVGAAudioLayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SVGAAudioLayer.m; sourceTree = ""; }; + 71418C702259FAA30029C69E /* mutiMask.svga */ = {isa = PBXFileReference; lastKnownFileType = file; path = mutiMask.svga; sourceTree = ""; }; 8AD65028FA2D122A34DC4A63 /* Pods-SVGAPlayer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SVGAPlayer.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SVGAPlayer/Pods-SVGAPlayer.debug.xcconfig"; sourceTree = ""; }; 904D41F61D223DD20085A21A /* SVGABezierPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGABezierPath.h; sourceTree = ""; }; 904D41F71D223DD20085A21A /* SVGABezierPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SVGABezierPath.m; sourceTree = ""; }; @@ -239,6 +241,7 @@ 90D7C9FA1F7E2AA3006E74F0 /* Samples */ = { isa = PBXGroup; children = ( + 71418C702259FAA30029C69E /* mutiMask.svga */, 63712E6421787950001AE014 /* heartbeat.svga */, 90D7CA1A1F7FB114006E74F0 /* rose_1.5.0.svga */, 90D7CA191F7FB114006E74F0 /* rose_2.0.0.svga */, @@ -327,6 +330,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); @@ -350,6 +354,7 @@ 90A676ED1D13A6DF008A69F3 /* Assets.xcassets in Resources */, 63712E6521787950001AE014 /* heartbeat.svga in Resources */, 90A676EB1D13A6DF008A69F3 /* Main.storyboard in Resources */, + 71418C712259FAA30029C69E /* mutiMask.svga in Resources */, 90CB64F91EF297E800DAA382 /* SVGAPlayer React-Info.plist in Resources */, 90D7CA1C1F7FB114006E74F0 /* rose_1.5.0.svga in Resources */, 90D7CA1B1F7FB114006E74F0 /* rose_2.0.0.svga in Resources */, diff --git a/SVGAPlayer/Samples/mutiMask.svga b/SVGAPlayer/Samples/mutiMask.svga new file mode 100644 index 0000000000000000000000000000000000000000..9f6b0c1f28bb7c877d714608592f430ea7e35c46 GIT binary patch literal 4289 zcmeHLL66cv6dpu9aPsJJGTFq7Oxi+$H6|uzF9uNdDw0^CKqJ_u?XnU=f{Do<_TnG% zU-&ot56*kj(rK3#ys=~_fth~qn>X{`yndAS+U3WUG7;_9?alku&&lr>&j^7}MPPGx z;n+Oz?BS|HMPm!wXRj#Jxz08AQesFFsH8}mV_&~@zo$SnTsxz1D&V@N$=QHHV^iCi zOhaixzkse25*vGguo}udHukN#4XBPYA~tj8)&${Ij0B$Vgb4MwzLV|Z`Z%d=FNHT& z<8v$c8pQ`zXvu1c4{4!F=rMvbteH2pV0%dzDf`S?x>pc$dM_ysBvFZ3wc#4D;UasS z@gmMP_u4i)>N?6Ps4xqC>sv5({dsW&1sT8yzU+x$xW_&c_M8l({}57W=ms};AA=-8 z9u2L<8~>GpU}|}px>8dFt4I`=uJ8Ag~A!UXAq5UHb0lzlc$nXBA>+IgLp|n$Up9yzWo3I literal 0 HcmV?d00001 diff --git a/SVGAPlayer/ViewController.m b/SVGAPlayer/ViewController.m index 3ee166d..7aa6932 100644 --- a/SVGAPlayer/ViewController.m +++ b/SVGAPlayer/ViewController.m @@ -29,7 +29,14 @@ - (void)viewDidLoad { self.aPlayer.loops = 0; self.aPlayer.clearsAfterStop = YES; parser = [[SVGAParser alloc] init]; - [self onChange:nil]; + [parser parseWithNamed:@"mutiMask" + inBundle:[NSBundle mainBundle] completionBlock:^(SVGAVideoEntity * _Nonnull videoItem) { + if (videoItem != nil) { + self.aPlayer.videoItem = videoItem; + [self.aPlayer startAnimation]; + } + } failureBlock:^(NSError * _Nonnull error) { + }]; } - (void)viewWillLayoutSubviews { diff --git a/Source/SVGAPlayer.m b/Source/SVGAPlayer.m index 0a1001e..ac46fb5 100644 --- a/Source/SVGAPlayer.m +++ b/Source/SVGAPlayer.m @@ -35,6 +35,8 @@ @interface SVGAPlayer () @implementation SVGAPlayer +static NSArray *_contentLayers; + - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; @@ -55,6 +57,7 @@ - (void)startAnimation { [self stopAnimation:NO]; self.loopCount = 0; self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(next)]; + self.displayLink.frameInterval = 60 / self.videoItem.FPS; [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; self.forwardAnimating = !self.reversing; @@ -93,6 +96,7 @@ - (void)stopAnimation:(BOOL)clear { } - (void)clear { + _contentLayers = nil; [self.drawLayer removeFromSuperlayer]; } @@ -128,7 +132,9 @@ - (void)draw { self.drawLayer = [[CALayer alloc] init]; self.drawLayer.frame = CGRectMake(0, 0, self.videoItem.videoSize.width, self.videoItem.videoSize.height); self.drawLayer.masksToBounds = true; - [self.videoItem.sprites enumerateObjectsUsingBlock:^(SVGAVideoSpriteEntity * _Nonnull sprite, NSUInteger idx, BOOL * _Nonnull stop) { + NSMutableDictionary *tempHostLayers = [NSMutableDictionary dictionary]; + NSMutableDictionary *tempContentLayers = [NSMutableDictionary dictionary]; + for (SVGAVideoSpriteEntity * sprite in self.videoItem.sprites) { UIImage *bitmap; if (sprite.imageKey != nil) { if (self.dynamicObjects[sprite.imageKey] != nil) { @@ -140,7 +146,20 @@ - (void)draw { } SVGAContentLayer *contentLayer = [sprite requestLayerWithBitmap:bitmap]; contentLayer.imageKey = sprite.imageKey; - [self.drawLayer addSublayer:contentLayer]; + tempContentLayers[sprite.imageKey] = contentLayer; + if ([sprite.imageKey containsString:@".mask"]) { + CALayer *hostLayer = [[CALayer alloc] init]; + hostLayer.mask = contentLayer; + [self.drawLayer addSublayer:hostLayer]; + tempHostLayers[sprite.imageKey] = hostLayer; + } else { + if (sprite.maskImageKey) { + CALayer *hostLayer = tempHostLayers[sprite.maskImageKey]; + [hostLayer addSublayer:contentLayer]; + } else { + [self.drawLayer addSublayer:contentLayer]; + } + } if (sprite.imageKey != nil) { if (self.dynamicTexts[sprite.imageKey] != nil) { NSAttributedString *text = self.dynamicTexts[sprite.imageKey]; @@ -160,7 +179,11 @@ - (void)draw { contentLayer.dynamicDrawingBlock = self.dynamicDrawings[sprite.imageKey]; } } - }]; + } + _contentLayers = tempContentLayers.allValues; +// [self.videoItem.sprites enumerateObjectsUsingBlock:^(SVGAVideoSpriteEntity * _Nonnull sprite, NSUInteger idx, BOOL * _Nonnull stop) { + +// }]; [self.layer addSublayer:self.drawLayer]; NSMutableArray *audioLayers = [NSMutableArray array]; [self.videoItem.audios enumerateObjectsUsingBlock:^(SVGAAudioEntity * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { @@ -252,7 +275,7 @@ - (void)layoutSubviews { - (void)update { [CATransaction setDisableActions:YES]; - for (SVGAContentLayer *layer in self.drawLayer.sublayers) { + for (SVGAContentLayer *layer in _contentLayers) { if ([layer isKindOfClass:[SVGAContentLayer class]]) { [layer stepToFrame:self.currentFrame]; } @@ -331,8 +354,8 @@ - (void)setImage:(UIImage *)image forKey:(NSString *)aKey { NSMutableDictionary *mutableDynamicObjects = [self.dynamicObjects mutableCopy]; [mutableDynamicObjects setObject:image forKey:aKey]; self.dynamicObjects = mutableDynamicObjects; - if (self.drawLayer.sublayers.count > 0) { - for (SVGAContentLayer *layer in self.drawLayer.sublayers) { + if (_contentLayers.count > 0) { + for (SVGAContentLayer *layer in _contentLayers) { if ([layer isKindOfClass:[SVGAContentLayer class]] && [layer.imageKey isEqualToString:aKey]) { layer.bitmapLayer.contents = (__bridge id _Nullable)([image CGImage]); } @@ -364,10 +387,10 @@ - (void)setAttributedText:(NSAttributedString *)attributedText forKey:(NSString NSMutableDictionary *mutableDynamicTexts = [self.dynamicTexts mutableCopy]; [mutableDynamicTexts setObject:attributedText forKey:aKey]; self.dynamicTexts = mutableDynamicTexts; - if (self.drawLayer.sublayers.count > 0) { + if (_contentLayers.count > 0) { CGSize size = [attributedText boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:NULL].size; CATextLayer *textLayer; - for (SVGAContentLayer *layer in self.drawLayer.sublayers) { + for (SVGAContentLayer *layer in _contentLayers) { if ([layer isKindOfClass:[SVGAContentLayer class]] && [layer.imageKey isEqualToString:aKey]) { textLayer = layer.textLayer; if (textLayer == nil) { @@ -389,8 +412,8 @@ - (void)setDrawingBlock:(SVGAPlayerDynamicDrawingBlock)drawingBlock forKey:(NSSt NSMutableDictionary *mutableDynamicDrawings = [self.dynamicDrawings mutableCopy]; [mutableDynamicDrawings setObject:drawingBlock forKey:aKey]; self.dynamicDrawings = mutableDynamicDrawings; - if (self.drawLayer.sublayers.count > 0) { - for (SVGAContentLayer *layer in self.drawLayer.sublayers) { + if (_contentLayers.count > 0) { + for (SVGAContentLayer *layer in _contentLayers) { if ([layer isKindOfClass:[SVGAContentLayer class]] && [layer.imageKey isEqualToString:aKey]) { layer.dynamicDrawingBlock = drawingBlock; @@ -403,8 +426,8 @@ - (void)setHidden:(BOOL)hidden forKey:(NSString *)aKey { NSMutableDictionary *mutableDynamicHiddens = [self.dynamicHiddens mutableCopy]; [mutableDynamicHiddens setObject:@(hidden) forKey:aKey]; self.dynamicHiddens = mutableDynamicHiddens; - if (self.drawLayer.sublayers.count > 0) { - for (SVGAContentLayer *layer in self.drawLayer.sublayers) { + if (_contentLayers.count > 0) { + for (SVGAContentLayer *layer in _contentLayers) { if ([layer isKindOfClass:[SVGAContentLayer class]] && [layer.imageKey isEqualToString:aKey]) { layer.dynamicHidden = hidden; diff --git a/Source/SVGAVideoSpriteEntity.h b/Source/SVGAVideoSpriteEntity.h index dd9e7d7..c16c275 100644 --- a/Source/SVGAVideoSpriteEntity.h +++ b/Source/SVGAVideoSpriteEntity.h @@ -15,6 +15,7 @@ @interface SVGAVideoSpriteEntity : NSObject @property (nonatomic, readonly) NSString *imageKey; +@property (nonatomic, readonly) NSString *maskImageKey; @property (nonatomic, readonly) NSArray *frames; - (instancetype)initWithJSONObject:(NSDictionary *)JSONObject; diff --git a/Source/SVGAVideoSpriteEntity.m b/Source/SVGAVideoSpriteEntity.m index ecb0c45..c63121b 100644 --- a/Source/SVGAVideoSpriteEntity.m +++ b/Source/SVGAVideoSpriteEntity.m @@ -20,6 +20,7 @@ - (instancetype)initWithJSONObject:(NSDictionary *)JSONObject { if (self) { if ([JSONObject isKindOfClass:[NSDictionary class]]) { NSString *imageKey = JSONObject[@"imageKey"]; + NSString *maskImageKey = JSONObject[@"maskImageKey"]; NSArray *JSONFrames = JSONObject[@"frames"]; if ([imageKey isKindOfClass:[NSString class]] && [JSONFrames isKindOfClass:[NSArray class]]) { NSMutableArray *frames = [[NSMutableArray alloc] init]; @@ -28,6 +29,7 @@ - (instancetype)initWithJSONObject:(NSDictionary *)JSONObject { [frames addObject:[[SVGAVideoSpriteFrameEntity alloc] initWithJSONObject:obj]]; } }]; + _maskImageKey = maskImageKey; _imageKey = imageKey; _frames = frames; }