123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- //
- // LOTStrokeRenderer.m
- // Lottie
- //
- // Created by brandon_withrow on 7/17/17.
- // Copyright © 2017 Airbnb. All rights reserved.
- //
- #import "LOTStrokeRenderer.h"
- #import "LOTColorInterpolator.h"
- #import "LOTNumberInterpolator.h"
- @implementation LOTStrokeRenderer {
- LOTColorInterpolator *_colorInterpolator;
- LOTNumberInterpolator *_opacityInterpolator;
- LOTNumberInterpolator *_widthInterpolator;
- LOTNumberInterpolator *_dashOffsetInterpolator;
- NSArray *_dashPatternInterpolators;
- }
- - (instancetype)initWithInputNode:(LOTAnimatorNode *)inputNode
- shapeStroke:(LOTShapeStroke *)stroke {
- self = [super initWithInputNode:inputNode keyName:stroke.keyname];
- if (self) {
- _colorInterpolator = [[LOTColorInterpolator alloc] initWithKeyframes:stroke.color.keyframes];
- _opacityInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:stroke.opacity.keyframes];
- _widthInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:stroke.width.keyframes];
-
- NSMutableArray *dashPatternIntpolators = [NSMutableArray array];
- NSMutableArray *dashPatterns = [NSMutableArray array];
- for (LOTKeyframeGroup *keyframegroup in stroke.lineDashPattern) {
- LOTNumberInterpolator *interpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:keyframegroup.keyframes];
- [dashPatternIntpolators addObject:interpolator];
- if (dashPatterns && keyframegroup.keyframes.count == 1) {
- LOTKeyframe *first = keyframegroup.keyframes.firstObject;
- [dashPatterns addObject:@(first.floatValue)];
- }
- if (keyframegroup.keyframes.count > 1) {
- dashPatterns = nil;
- }
- }
-
- if (dashPatterns.count) {
- self.outputLayer.lineDashPattern = dashPatterns;
- } else {
- _dashPatternInterpolators = dashPatternIntpolators;
- }
-
- if (stroke.dashOffset) {
- _dashOffsetInterpolator = [[LOTNumberInterpolator alloc] initWithKeyframes:stroke.dashOffset.keyframes];
- }
-
- self.outputLayer.fillColor = nil;
- self.outputLayer.lineCap = stroke.capType == LOTLineCapTypeRound ? kCALineCapRound : kCALineCapButt;
- switch (stroke.joinType) {
- case LOTLineJoinTypeBevel:
- self.outputLayer.lineJoin = kCALineJoinBevel;
- break;
- case LOTLineJoinTypeMiter:
- self.outputLayer.lineJoin = kCALineJoinMiter;
- break;
- case LOTLineJoinTypeRound:
- self.outputLayer.lineJoin = kCALineJoinRound;
- break;
- default:
- break;
- }
- }
- return self;
- }
- - (NSDictionary *)valueInterpolators {
- return @{@"Color" : _colorInterpolator,
- @"Opacity" : _opacityInterpolator,
- @"Stroke Width" : _widthInterpolator};
- }
- - (void)_updateLineDashPatternsForFrame:(NSNumber *)frame {
- if (_dashPatternInterpolators.count) {
- NSMutableArray *lineDashPatterns = [NSMutableArray array];
- CGFloat dashTotal = 0;
- for (LOTNumberInterpolator *interpolator in _dashPatternInterpolators) {
- CGFloat patternValue = [interpolator floatValueForFrame:frame];
- dashTotal = dashTotal + patternValue;
- [lineDashPatterns addObject:@(patternValue)];
- }
- if (dashTotal > 0) {
- self.outputLayer.lineDashPattern = lineDashPatterns;
- }
- }
- }
- - (BOOL)needsUpdateForFrame:(NSNumber *)frame {
- [self _updateLineDashPatternsForFrame:frame];
- BOOL dashOffset = NO;
- if (_dashOffsetInterpolator) {
- dashOffset = [_dashOffsetInterpolator hasUpdateForFrame:frame];
- }
- return (dashOffset ||
- [_colorInterpolator hasUpdateForFrame:frame] ||
- [_opacityInterpolator hasUpdateForFrame:frame] ||
- [_widthInterpolator hasUpdateForFrame:frame]);
- }
- - (void)performLocalUpdate {
- self.outputLayer.lineDashPhase = [_dashOffsetInterpolator floatValueForFrame:self.currentFrame];
- self.outputLayer.strokeColor = [_colorInterpolator colorForFrame:self.currentFrame];
- self.outputLayer.lineWidth = [_widthInterpolator floatValueForFrame:self.currentFrame];
- self.outputLayer.opacity = [_opacityInterpolator floatValueForFrame:self.currentFrame];
- }
- - (void)rebuildOutputs {
- self.outputLayer.path = self.inputNode.outputPath.CGPath;
- }
- - (NSDictionary *)actionsForRenderLayer {
- return @{@"strokeColor": [NSNull null],
- @"lineWidth": [NSNull null],
- @"opacity" : [NSNull null]};
- }
- @end
|