Skip to content
This repository has been archived by the owner on Jun 3, 2021. It is now read-only.

Commit

Permalink
[WEEX-295] Rebuild transition's code and improve performance
Browse files Browse the repository at this point in the history
[WEEX-295] [iOS] Rebuild transition's code and improve performance
close #1118
  • Loading branch information
doumafang authored and acton393 committed Apr 18, 2018
1 parent 39c85a3 commit a8de438
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 76 deletions.
18 changes: 9 additions & 9 deletions ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -305,11 +305,11 @@ - (void)transition:(NSString *)nodeRef args:(NSDictionary *)args callback:(WXMod
- (void)animationWithTransitionTarget:(WXComponent *)target handleProperty:(NSString *)property withDic:(NSDictionary *)args
{
NSDictionary *styles = args[@"styles"];
_transition.addStyles = [NSMutableDictionary dictionaryWithDictionary:styles];
_transition.fromStyles =_transition.fromStyles ? :[NSMutableDictionary dictionaryWithDictionary:target.styles] ;
[_transition.fromStyles setObject:@([args[@"duration"] doubleValue]) forKey:kWXTransitionDuration];
[_transition.fromStyles setObject:@([args[@"delay"] doubleValue]) forKey:kWXTransitionDelay];
NSString *oldProperty = _transition.fromStyles[kWXTransitionProperty];
_transition.filterStyles = [NSMutableDictionary dictionaryWithDictionary:styles];
_transition.oldFilterStyles =_transition.oldFilterStyles ? :[NSMutableDictionary dictionaryWithDictionary:target.styles] ;
[_transition.oldFilterStyles setObject:@([args[@"duration"] doubleValue]) forKey:kWXTransitionDuration];
[_transition.oldFilterStyles setObject:@([args[@"delay"] doubleValue]) forKey:kWXTransitionDelay];
NSString *oldProperty = _transition.oldFilterStyles[kWXTransitionProperty];
NSString *newProperty;
if (oldProperty) {
if ([oldProperty containsString:property]) {
Expand All @@ -324,11 +324,11 @@ - (void)animationWithTransitionTarget:(WXComponent *)target handleProperty:(NSSt
{
newProperty = property;
}
[_transition.fromStyles setObject:newProperty forKey:kWXTransitionProperty];
[_transition.fromStyles setObject:args[@"timingFunction"] forKey:kWXTransitionTimingFunction];
[_transition.oldFilterStyles setObject:newProperty forKey:kWXTransitionProperty];
[_transition.oldFilterStyles setObject:args[@"timingFunction"] forKey:kWXTransitionTimingFunction];
[target _modifyStyles:styles];

}

- (void)animation:(WXComponent *)targetComponent args:(NSDictionary *)args callback:(WXModuleKeepAliveCallback)callback
{
/**
Expand Down Expand Up @@ -361,7 +361,7 @@ - (void)animation:(WXComponent *)targetComponent args:(NSDictionary *)args callb
[CATransaction commit];
if (_needLayout) {
WXPerformBlockOnComponentThread(^{
[_transition _handleTransitionWithStyles:_transition.addStyles resetStyles:nil target:targetComponent];
[_transition _handleTransitionWithStyles:_transition.filterStyles resetStyles:nil target:targetComponent];
});
}
}
Expand Down
4 changes: 2 additions & 2 deletions ios/sdk/WeexSDK/Sources/Module/WXTransition.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ typedef NS_OPTIONS(NSUInteger, WXTransitionOptions) {
@end

@interface WXTransition : NSObject
@property(nonatomic,strong) NSMutableDictionary *fromStyles;
@property(nonatomic,strong) NSMutableDictionary *addStyles;
@property(nonatomic,strong) NSMutableDictionary *oldFilterStyles;
@property(nonatomic,strong) NSMutableDictionary *filterStyles;
@property(nonatomic,strong) NSMutableArray *propertyArray;
@property(nonatomic,assign) WXTransitionOptions transitionOptions;
- (instancetype) initWithStyles:(NSDictionary *)styles;
Expand Down
149 changes: 84 additions & 65 deletions ios/sdk/WeexSDK/Sources/Module/WXTransition.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,11 @@
#import "WXLength.h"

@implementation WXTransitionInfo

@end

@interface WXTransition()
{
WXComponent *_targetComponent;

double ax;
double bx;
double cx;
Expand All @@ -54,66 +52,84 @@ @interface WXTransition()
CAMediaTimingFunction *_transitionTimingFunction;
CADisplayLink *_transitionDisplayLink;

NSMutableDictionary *_toStyles;
NSMutableDictionary *_fromStyles;
NSMutableDictionary *_addStyles;
NSMutableDictionary *_filterStyles;
NSMutableDictionary *_oldFilterStyles;
}

@end

@implementation WXTransition


- (instancetype)initWithStyles:(NSDictionary *)styles
{
if (self = [super init]) {
NSString *property = styles[kWXTransitionProperty];
_transitionOptions |= [property containsString:@"width"]? WXTransitionOptionsWidth:0;
_transitionOptions |= [property containsString:@"height"]? WXTransitionOptionsHeight:0;
_transitionOptions |= [property containsString:@"right"]? WXTransitionOptionsRight:0;
_transitionOptions |= [property containsString:@"left"]? WXTransitionOptionsLeft:0;
_transitionOptions |= [property containsString:@"bottom"]? WXTransitionOptionsBottom:0;
_transitionOptions |= [property containsString:@"top"]? WXTransitionOptionsTop:0;
_transitionOptions |= [property containsString:@"backgroundColor"]? WXTransitionOptionsBackgroundColor:0;
_transitionOptions |= [property containsString:@"transform"]? WXTransitionOptionsTransform:0;
_transitionOptions |= [property containsString:@"opacity"]? WXTransitionOptionsOpacity:0;
NSArray *properties = [property componentsSeparatedByString:@","];
for (NSString *string in properties) {
_transitionOptions |= [self transitionOptionsFromString:string];
}
}
return self;
}

#pragma mark - HandleStyle
- (WXTransitionOptions)transitionOptionsFromString:(NSString *)string
{
NSDictionary<NSString*,NSNumber*> *options = @{
@"width": @(WXTransitionOptionsWidth),
@"height": @(WXTransitionOptionsHeight),
@"right": @(WXTransitionOptionsRight),
@"left": @(WXTransitionOptionsLeft),
@"bottom": @(WXTransitionOptionsBottom),
@"top": @(WXTransitionOptionsTop),
@"backgroundColor": @(WXTransitionOptionsBackgroundColor),
@"transform": @(WXTransitionOptionsTransform),
@"opacity": @(WXTransitionOptionsOpacity),
};
return options[string].integerValue;
}

- (void)_handleTransitionWithStyles:(NSDictionary *)styles resetStyles:(NSMutableArray *)resetStyles target:(WXComponent *)targetComponent
{
if ([self _isTransitionRunning]) {
BOOL isRunning = [self _isTransitionRunning];
if (isRunning) {
[self _rollBackTransitionWithStyles:styles];
}
else
{
[self _suspendTransitionDisplayLink];
}

_targetComponent = targetComponent;
if (!_fromStyles) {
_fromStyles = [NSMutableDictionary dictionaryWithDictionary:targetComponent.styles];
_addStyles = [NSMutableDictionary dictionaryWithDictionary:styles];
}
else
{
[_addStyles addEntriesFromDictionary:styles];
}
_toStyles = [NSMutableDictionary dictionaryWithDictionary:_fromStyles];
[_toStyles addEntriesFromDictionary:_addStyles];
_filterStyles = _filterStyles ?:[NSMutableDictionary new];
_oldFilterStyles = _oldFilterStyles ?: [NSMutableDictionary new];
NSMutableDictionary *futileStyles = [NSMutableDictionary new];

_transitionDuration = _fromStyles[kWXTransitionDuration] ? [WXConvert CGFloat:_fromStyles[kWXTransitionDuration]] : 0;
_transitionDelay = _fromStyles[kWXTransitionDelay] ? [WXConvert CGFloat:_fromStyles[kWXTransitionDelay]] : 0;
_transitionTimingFunction = [WXConvert CAMediaTimingFunction:_fromStyles[kWXTransitionTimingFunction]];
for (NSString *key in styles) {
if (self.transitionOptions & [self transitionOptionsFromString:key]) {
[_filterStyles setObject:styles[key] forKey:key];
if (![key isEqualToString:@"transform"]) {
if (!isRunning) {
[_oldFilterStyles setObject:targetComponent.styles[key] forKey:key];
}
}
}
else
{
[futileStyles setObject:styles[key] forKey:key];
}
}
[self updateFutileStyles:futileStyles resetStyles:nil target:targetComponent];

_targetComponent = targetComponent;
NSMutableDictionary *componentStyles = [NSMutableDictionary dictionaryWithDictionary:styles];
[componentStyles addEntriesFromDictionary:targetComponent.styles];

_transitionDuration = componentStyles[kWXTransitionDuration] ? [WXConvert CGFloat:componentStyles[kWXTransitionDuration]] : 0;
_transitionDelay = componentStyles[kWXTransitionDelay] ? [WXConvert CGFloat:componentStyles[kWXTransitionDelay]] : 0;
_transitionTimingFunction = [WXConvert CAMediaTimingFunction:componentStyles[kWXTransitionTimingFunction]];

if (_transitionDuration == 0 ) {
[targetComponent _updateCSSNodeStyles:styles];
[targetComponent _resetCSSNodeStyles:resetStyles];
WXPerformBlockOnMainThread(^{
[targetComponent _updateViewStyles:styles];
});
[self updateFutileStyles:_filterStyles resetStyles:nil target:targetComponent];
return;
}

Expand All @@ -124,48 +140,54 @@ - (void)_handleTransitionWithStyles:(NSDictionary *)styles resetStyles:(NSMutabl
[self unitBezierp1x:vec[0] p1y:vec[1] p2x:vec[2] p2y:vec[3]];
}

NSString *transitionProperty = _fromStyles[kWXTransitionProperty];
[self _resloveTransitionProperty:transitionProperty withStyles:styles];
[self _resloveTransitionProperty];
[self performSelector:@selector(_startTransitionDisplayLink) withObject:self afterDelay:_transitionDelay/1000];
}

- (void)updateFutileStyles:(NSDictionary *)styles resetStyles:(NSMutableArray *)resetStyles target:(WXComponent *)targetComponent
{
[targetComponent _updateCSSNodeStyles:styles];
[targetComponent _resetCSSNodeStyles:resetStyles];
WXPerformBlockOnMainThread(^{
[targetComponent _updateViewStyles:styles];
});
}

- (void)_rollBackTransitionWithStyles:(NSDictionary *)styles
{
_transitionDuration = _transitionCount * 1000 / 60;
_transitionCount = 0;
_propertyArray = nil;
}

- (void)_resloveTransitionProperty:(NSString *)propertyNames withStyles:(NSDictionary *)styles
- (void)_resloveTransitionProperty
{
if (styles.count == 0) {
if (_filterStyles.count == 0) {
return;
}
for (NSString * name in styles.allKeys) {
if ([propertyNames containsString:name]) {
[self _dealTransitionWithProperty:name styles:styles];
}
for (NSString * name in _filterStyles.allKeys) {
[self _dealTransitionWithProperty:name];
}
}

- (void)_dealTransitionWithProperty:(NSString *)singleProperty styles:(NSDictionary *)styles
- (void)_dealTransitionWithProperty:(NSString *)singleProperty
{
if (styles[singleProperty])
if (_filterStyles[singleProperty])
{
if (!_propertyArray) {
_propertyArray = [NSMutableArray new];
}
if ([singleProperty isEqualToString:@"backgroundColor"]) {
WXTransitionInfo *info = [WXTransitionInfo new];
info.fromValue = [self _dealWithColor:[WXConvert UIColor:_fromStyles[singleProperty]]];
info.toValue = [self _dealWithColor:[WXConvert UIColor:_toStyles[singleProperty]]];
info.fromValue = [self _dealWithColor:[WXConvert UIColor:_oldFilterStyles[singleProperty]]];
info.toValue = [self _dealWithColor:[WXConvert UIColor:_filterStyles[singleProperty]]];
info.perValue = [self _calculatePerColorRGB1:info.toValue RGB2:info.fromValue];
info.propertyName = singleProperty;
[_propertyArray addObject:info];
}
else if ([singleProperty isEqualToString:@"transform"]) {
NSString *transformOrigin = styles[@"transformOrigin"];
WXTransform *wxTransform = [[WXTransform alloc] initWithCSSValue:_toStyles[singleProperty] origin:transformOrigin instance:_targetComponent.weexInstance];
NSString *transformOrigin = _filterStyles[@"transformOrigin"];
WXTransform *wxTransform = [[WXTransform alloc] initWithCSSValue:_filterStyles[singleProperty] origin:transformOrigin instance:_targetComponent.weexInstance];
WXTransform *oldTransform = _targetComponent->_transform;
if (wxTransform.rotateAngle != oldTransform.rotateAngle) {
WXTransitionInfo *info = [WXTransitionInfo new];
Expand Down Expand Up @@ -239,8 +261,8 @@ - (void)_dealTransitionWithProperty:(NSString *)singleProperty styles:(NSDiction
else
{
WXTransitionInfo *info = [WXTransitionInfo new];
info.fromValue = @(_fromStyles[singleProperty] ? [WXConvert CGFloat:_fromStyles[singleProperty]] : 0);
info.toValue = @(_toStyles[singleProperty] ? [WXConvert CGFloat:_toStyles[singleProperty]] : 0 );
info.fromValue = @(_oldFilterStyles[singleProperty] ? [WXConvert CGFloat:_oldFilterStyles[singleProperty]] : 0);
info.toValue = @(_filterStyles[singleProperty] ? [WXConvert CGFloat:_filterStyles[singleProperty]] : 0 );
info.perValue = @([info.toValue doubleValue] - [info.fromValue doubleValue]);
info.propertyName = singleProperty;
[_propertyArray addObject:info];
Expand Down Expand Up @@ -287,7 +309,7 @@ - (void)_calculatetransitionProcessingStyle
[_targetComponent.view setNeedsDisplay];
});
NSString *colorString = [WXConvert HexWithColor:color];
[_fromStyles setObject:colorString forKey:info.propertyName];
[_oldFilterStyles setObject:colorString forKey:info.propertyName];
}
else if ([info.propertyName hasPrefix:@"transform"])
{
Expand Down Expand Up @@ -325,18 +347,18 @@ - (void)_calculatetransitionProcessingStyle
newString = [NSString stringWithFormat:@"translateY(%lfpx)",currentValue / _targetComponent.weexInstance.pixelScaleFactor];
transformString = [transformString stringByAppendingFormat:@" %@",newString];
}
[_fromStyles setObject:transformString forKey:@"transform"];
[_oldFilterStyles setObject:transformString forKey:@"transform"];
}
else
{
double currentValue = [info.fromValue doubleValue] + [info.perValue doubleValue] * per;
[_fromStyles setObject:@(currentValue) forKey:info.propertyName];
[_oldFilterStyles setObject:@(currentValue) forKey:info.propertyName];
}
}
WXPerformBlockOnMainThread(^{
[_targetComponent _updateViewStyles:_fromStyles];
[_targetComponent _updateViewStyles:_oldFilterStyles];
});
[_targetComponent _updateCSSNodeStyles:_fromStyles];
[_targetComponent _updateCSSNodeStyles:_oldFilterStyles];
[_targetComponent.weexInstance.componentManager startComponentTasks];
}

Expand Down Expand Up @@ -409,20 +431,18 @@ - (void)_resetProcessAnimationParameter
_transitionCount = 0;
_transitionDuration = 0;
_propertyArray = nil;

_addStyles = nil;
_fromStyles = nil;
_toStyles = nil;
_oldFilterStyles = nil;
_filterStyles= nil;
}

- (NSMutableDictionary *)_addStyles
- (NSMutableDictionary *)_filterStyles
{
return self.addStyles;
return self.filterStyles;
}

- (NSMutableDictionary *)_fromStyles
- (NSMutableDictionary *)_oldFilterStyles
{
return self.fromStyles;
return self.oldFilterStyles;
}

#pragma mark UnitBezierp
Expand Down Expand Up @@ -496,5 +516,4 @@ - (double)solveWithx:(double)x epsilon:(double)epsilon
{
return [self sampleCurveY:([self solveCurveX:x epsilon:epsilon])];
}

@end

0 comments on commit a8de438

Please sign in to comment.