mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-17 02:49:57 +00:00
107 lines
2.9 KiB
Objective-C
107 lines
2.9 KiB
Objective-C
//
|
|
// LOTMaskContainer.m
|
|
// Lottie
|
|
//
|
|
// Created by brandon_withrow on 7/19/17.
|
|
// Copyright © 2017 Airbnb. All rights reserved.
|
|
//
|
|
|
|
#import "LOTMaskContainer.h"
|
|
#import "LOTPathInterpolator.h"
|
|
#import "LOTNumberInterpolator.h"
|
|
|
|
@interface LOTMaskNodeLayer : CAShapeLayer
|
|
|
|
@property (nonatomic, readonly) LOTMask *maskNode;
|
|
|
|
- (instancetype)initWithMask:(LOTMask *)maskNode;
|
|
- (BOOL)hasUpdateForFrame:(NSNumber *)frame;
|
|
|
|
@end
|
|
|
|
@implementation LOTMaskNodeLayer {
|
|
LOTPathInterpolator *_pathInterpolator;
|
|
LOTNumberInterpolator *_opacityInterpolator;
|
|
LOTNumberInterpolator *_expansionInterpolator;
|
|
}
|
|
|
|
- (instancetype)initWithMask:(LOTMask *)maskNode {
|
|
self = [super init];
|
|
if (self) {
|
|
_pathInterpolator = [[LOTPathInterpolator alloc] initWithKeyframes:maskNode.maskPath.keyframes];
|
|
_opacityInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:maskNode.opacity.keyframes];
|
|
_expansionInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:maskNode.expansion.keyframes];
|
|
_maskNode = maskNode;
|
|
self.fillColor = [UIColor blueColor].CGColor;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)updateForFrame:(NSNumber *)frame withViewBounds:(CGRect)viewBounds {
|
|
if ([self hasUpdateForFrame:frame]) {
|
|
LOTBezierPath *path = [_pathInterpolator pathForFrame:frame cacheLengths:NO];
|
|
|
|
if (self.maskNode.maskMode == LOTMaskModeSubtract) {
|
|
CGMutablePathRef pathRef = CGPathCreateMutable();
|
|
CGPathAddRect(pathRef, NULL, viewBounds);
|
|
CGPathAddPath(pathRef, NULL, path.CGPath);
|
|
self.path = pathRef;
|
|
self.fillRule = @"even-odd";
|
|
} else {
|
|
self.path = path.CGPath;
|
|
}
|
|
|
|
self.opacity = [_opacityInterpolator floatValueForFrame:frame];
|
|
}
|
|
}
|
|
|
|
- (BOOL)hasUpdateForFrame:(NSNumber *)frame {
|
|
return ([_pathInterpolator hasUpdateForFrame:frame] ||
|
|
[_opacityInterpolator hasUpdateForFrame:frame]);
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation LOTMaskContainer {
|
|
NSArray<LOTMaskNodeLayer *> *_masks;
|
|
}
|
|
|
|
- (instancetype)initWithMasks:(NSArray<LOTMask *> *)masks {
|
|
self = [super init];
|
|
if (self) {
|
|
NSMutableArray *maskNodes = [NSMutableArray array];
|
|
CALayer *containerLayer = [CALayer layer];
|
|
|
|
for (LOTMask *mask in masks) {
|
|
LOTMaskNodeLayer *node = [[LOTMaskNodeLayer alloc] initWithMask:mask];
|
|
[maskNodes addObject:node];
|
|
if (mask.maskMode == LOTMaskModeAdd ||
|
|
mask == masks.firstObject) {
|
|
[containerLayer addSublayer:node];
|
|
} else {
|
|
containerLayer.mask = node;
|
|
CALayer *newContainer = [CALayer layer];
|
|
[newContainer addSublayer:containerLayer];
|
|
containerLayer = newContainer;
|
|
}
|
|
}
|
|
[self addSublayer:containerLayer];
|
|
_masks = maskNodes;
|
|
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)setCurrentFrame:(NSNumber *)currentFrame {
|
|
if (_currentFrame == currentFrame) {
|
|
return;
|
|
}
|
|
_currentFrame = currentFrame;
|
|
|
|
for (LOTMaskNodeLayer *nodeLayer in _masks) {
|
|
[nodeLayer updateForFrame:currentFrame withViewBounds:self.bounds];
|
|
}
|
|
}
|
|
|
|
@end
|