You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by ac...@apache.org on 2017/08/15 02:49:12 UTC
[2/7] incubator-weex git commit: * [ios] WXTransition
* [ios] WXTransition
Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/741ee207
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/741ee207
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/741ee207
Branch: refs/heads/0.16-dev
Commit: 741ee207ec66508d9124cb99a88e530a1458733f
Parents: 6bd86e5
Author: doumafang <do...@gmail.com>
Authored: Thu Aug 10 21:34:48 2017 +0800
Committer: doumafang <do...@gmail.com>
Committed: Thu Aug 10 21:34:48 2017 +0800
----------------------------------------------------------------------
.../Sources/Component/WXComponent_internal.h | 38 +--
.../WeexSDK/Sources/Layout/WXComponent+Layout.m | 280 -----------------
ios/sdk/WeexSDK/Sources/Model/WXComponent.m | 34 ++-
.../WeexSDK/Sources/Module/WXAnimationLayout.h | 49 ---
.../WeexSDK/Sources/Module/WXAnimationLayout.m | 115 -------
.../WeexSDK/Sources/Module/WXAnimationModule.h | 2 +
.../WeexSDK/Sources/Module/WXAnimationModule.m | 46 ++-
ios/sdk/WeexSDK/Sources/Module/WXTransition.h | 38 +++
ios/sdk/WeexSDK/Sources/Module/WXTransition.m | 299 +++++++++++++++++++
9 files changed, 380 insertions(+), 521 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/741ee207/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
index d2b7d54..49db7a9 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
+++ b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
@@ -21,9 +21,9 @@
#import "WXComponent.h"
#import "WXConvert.h"
#import "WXTransform.h"
+#import "WXTransition.h"
@class WXTouchGestureRecognizer;
@class WXThreadSafeCounter;
-@class WXLayoutAnimationInfo;
/**
@@ -45,34 +45,8 @@
WXPositionType _positionType;
-
- //LayoutAnimation
- WXLayoutAnimationInfo *_heightInfo;
- WXLayoutAnimationInfo *_widthInfo;
- WXLayoutAnimationInfo *_topInfo;
- WXLayoutAnimationInfo *_rightInfo;
- WXLayoutAnimationInfo *_leftInfo;
- WXLayoutAnimationInfo *_bottomInfo;
- double ax;
- double bx;
- double cx;
-
- double ay;
- double by;
- double cy;
-
-
- float _layoutAnimationDuration;
- float _layoutAnimationDelay;
- CAMediaTimingFunction *_layoutAnimationTimingFunction;
- NSUInteger _layoutAnimationCount;
-
- NSMutableDictionary *_toStyles;
- NSMutableDictionary *_fromStyles;
- NSMutableDictionary *_addStyles;
- CADisplayLink *_layoutAnimationDisplayLink;
-
-
+ //Transition
+ WXTransition *_transition;
/**
* View
@@ -252,10 +226,4 @@
@end
-@interface WXLayoutAnimationInfo : NSObject
-@property (nonatomic, strong) id fromValue;
-@property (nonatomic, strong) id toValue;
-@property (nonatomic, strong) id perValue;
-@property (nonatomic, assign) BOOL isAnimated;
-@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/741ee207/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.m b/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.m
index 14034a6..4eb57f5 100644
--- a/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.m
+++ b/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.m
@@ -17,8 +17,6 @@
* under the License.
*/
-#define SOLVE_EPS(dur) (1. / (1000. * (dur)))
-
#import "WXComponent+Layout.h"
#import "WXComponent_internal.h"
@@ -116,210 +114,6 @@
}
-#pragma mark LayoutAnimationDisplayLink
-- (void)_startLayoutAnimationDisplayLink
-{
- WXAssertComponentThread();
- if (!_layoutAnimationDisplayLink) {
- _layoutAnimationDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(_handleLayoutAnimationDisplayLink)];
- [_layoutAnimationDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
- }
- else{
- [self _awakeLayoutAnimationDisplayLink];
- }
-
-}
-
-- (void)_stopLayoutAnimationDisplayLink
-{
- WXAssertComponentThread();
- if (_layoutAnimationDisplayLink) {
- [_layoutAnimationDisplayLink invalidate];
- _layoutAnimationDisplayLink = nil;
- }
-}
-
-- (void)_suspendLayoutAnimationDisplayLink
-{
- WXAssertComponentThread();
- if(_layoutAnimationDisplayLink && !_layoutAnimationDisplayLink.paused)
- {
- _layoutAnimationDisplayLink.paused = YES;
- }
-}
-
-
-- (void)_awakeLayoutAnimationDisplayLink
-{
- WXAssertComponentThread();
- if (_layoutAnimationDisplayLink && _layoutAnimationDisplayLink.paused) {
- _layoutAnimationDisplayLink.paused = NO;
- }
-}
-
-- (void)_handleLayoutAnimationDisplayLink
-{
- WXAssertComponentThread();
- int count = _layoutAnimationDuration * 60 / 1000;
- if (_layoutAnimationCount >= count) {
- [self _suspendLayoutAnimationDisplayLink];
- [self _resetProcessAnimationParameter];
- return;
- }
- else
- {
- [self _calculateLayoutAnimationProcessingStyle];
- }
- _layoutAnimationCount ++;
-}
-
-
-- (void)_resetProcessAnimationParameter
-{
-
- _layoutAnimationCount = 0;
- _layoutAnimationDuration = 0;
- _widthInfo = nil;
- _heightInfo = nil;
- _leftInfo = nil;
- _rightInfo = nil;
- _topInfo = nil;
- _bottomInfo = nil;
-}
-
-- (void)_handleLayoutAnimationWithStyles:(NSDictionary *)styles
-{
- [self _suspendLayoutAnimationDisplayLink];
-
- if (!_addStyles) {
- _fromStyles = [NSMutableDictionary dictionaryWithDictionary:self.styles];
- _addStyles = [NSMutableDictionary dictionaryWithDictionary:styles];
- }
- else
- {
- [_addStyles addEntriesFromDictionary:styles];
- }//保证_addStyles是唯一的
-
- _toStyles = [NSMutableDictionary dictionaryWithDictionary:_fromStyles];
- [_toStyles addEntriesFromDictionary:_addStyles];
-
- _layoutAnimationDuration = _fromStyles[@"transitionDuration"] ? [WXConvert CGFloat:_fromStyles[@"transitionDuration"]] : 0;
- _layoutAnimationDelay = _fromStyles[@"transitionDelay"] ? [WXConvert CGFloat:_fromStyles[@"transitionDelay"]] : 0;
- _layoutAnimationTimingFunction = [WXConvert CAMediaTimingFunction:_fromStyles[@"transitionTimingFunction"]];
-
-
- if (_layoutAnimationDuration == 0) {
- [self _fillCSSNode:styles];
- return;//如果duration为零直接关闭动画效果
- }
-
- if (![[NSString stringWithFormat:@"%@",_layoutAnimationTimingFunction] isEqualToString: kCAMediaTimingFunctionLinear]) {
- float vec[4] = {0.};
- [_layoutAnimationTimingFunction getControlPointAtIndex:1 values:&vec[0]];
- [_layoutAnimationTimingFunction getControlPointAtIndex:2 values:&vec[2]];
- [self unitBezierp1x:vec[0] p1y:vec[1] p2x:vec[2] p2y:vec[3]];
- }
-
-
- NSString *layoutAnimationProperty = _fromStyles[@"transitionProperty"];
- if ([layoutAnimationProperty containsString:@"width"]) {
- _widthInfo = [WXLayoutAnimationInfo new];
- _widthInfo.isAnimated = YES;
- _widthInfo.fromValue = @(_fromStyles[@"width"] ? [WXConvert CGFloat:_fromStyles[@"width" ]] : 0);
- _widthInfo.toValue = @(_toStyles[@"width"] ? [WXConvert CGFloat:_toStyles[@"width"]] : 0 );
- _widthInfo.perValue = @([_widthInfo.toValue doubleValue] - [_widthInfo.fromValue doubleValue]);
-
- }
- if ([layoutAnimationProperty containsString:@"height"])
- {
- _heightInfo = [WXLayoutAnimationInfo new];
- _heightInfo.isAnimated = YES;
- _heightInfo.fromValue = @(_fromStyles[@"height"] ? [WXConvert CGFloat:_fromStyles[@"height" ]] : 0);
- _heightInfo.toValue = @(_toStyles[@"height"] ? [WXConvert CGFloat:_toStyles[@"height"]] : 0 );
- _heightInfo.perValue = @([_heightInfo.toValue doubleValue] - [_heightInfo.fromValue doubleValue]);
-
- }
- if ([layoutAnimationProperty containsString:@"left"])
- {
- _leftInfo = [WXLayoutAnimationInfo new];
- _leftInfo.isAnimated = YES;
- _leftInfo.fromValue = @(_fromStyles[@"left"] ? [WXConvert CGFloat:_fromStyles[@"left" ]] : 0);
- _leftInfo.toValue = @(_toStyles[@"left"] ? [WXConvert CGFloat:_toStyles[@"left"]] : 0 );
- _leftInfo.perValue = @([_leftInfo.toValue doubleValue] - [_leftInfo.fromValue doubleValue]);
-
- }
- if ([layoutAnimationProperty containsString:@"right"])
- {
- _rightInfo = [WXLayoutAnimationInfo new];
- _rightInfo.isAnimated = YES;
- _rightInfo.fromValue = @(_fromStyles[@"right"] ? [WXConvert CGFloat:_fromStyles[@"right" ]] : 0);
- _rightInfo.toValue = @(_toStyles[@"right"] ? [WXConvert CGFloat:_toStyles[@"right"]] : 0 );
- _rightInfo.perValue = @([_rightInfo.toValue doubleValue] - [_rightInfo.fromValue doubleValue]);
-
- }
- if ([layoutAnimationProperty containsString:@"top"])
- {
- _topInfo = [WXLayoutAnimationInfo new];
- _topInfo.isAnimated = YES;
- _topInfo.fromValue = @(_fromStyles[@"top"] ? [WXConvert CGFloat:_fromStyles[@"top" ]] : 0);
- _topInfo.toValue = @(_toStyles[@"top"] ? [WXConvert CGFloat:_toStyles[@"top"]] : 0 );
- _topInfo.perValue = @([_topInfo.toValue doubleValue] - [_topInfo.fromValue doubleValue]);
-
- }
- if ([layoutAnimationProperty containsString:@"bottom"])
- {
- _bottomInfo = [WXLayoutAnimationInfo new];
- _bottomInfo.isAnimated = YES;
- _bottomInfo.fromValue = @(_fromStyles[@"bottom"] ? [WXConvert CGFloat:_fromStyles[@"bottom" ]] : 0);
- _bottomInfo.toValue = @(_toStyles[@"bottom"] ? [WXConvert CGFloat:_toStyles[@"bottom"]] : 0 );
- _bottomInfo.perValue = @([_widthInfo.toValue doubleValue] - [_bottomInfo.fromValue doubleValue]);
-
- }
- if ([layoutAnimationProperty containsString:@"transform"]) {
-
-
- }
-
-
- [self performSelector:@selector(_startLayoutAnimationDisplayLink) withObject:self afterDelay:_layoutAnimationDelay/1000];
- // [self _startLayoutAnimationDisplayLink];
-
-}
-
-
-- (void)_calculateLayoutAnimationProcessingStyle
-{
- //linear 在做贝塞尔曲线模型
- double per = 1000 * (_layoutAnimationCount + 1 ) / (60 * _layoutAnimationDuration);//linear
- if (![[NSString stringWithFormat:@"%@",_layoutAnimationTimingFunction] isEqualToString: kCAMediaTimingFunctionLinear]) {
- per = [self solveWithx:((_layoutAnimationCount+2)*16)/_layoutAnimationDuration epsilon:SOLVE_EPS(_layoutAnimationDuration)];
- }
-
- double currentWidth = [_widthInfo.fromValue doubleValue] + [_widthInfo.perValue doubleValue] * per;
- double currentHeight = [_heightInfo.fromValue doubleValue] + [_heightInfo.perValue doubleValue] * per;
- double currentLeft = [_leftInfo.fromValue doubleValue] + [_leftInfo.perValue doubleValue] * per;
- double currentRight = [_rightInfo.fromValue doubleValue] + [_rightInfo.perValue doubleValue] * per;
- double currentTop = [_topInfo.fromValue doubleValue] + [_topInfo.perValue doubleValue] * per;
- double currentBottom = [_bottomInfo.fromValue doubleValue] + [_bottomInfo.perValue doubleValue] * per;
-
-
-
- _widthInfo.isAnimated ? [_fromStyles setObject:@(currentWidth) forKey:@"width"]:0;
- _heightInfo.isAnimated ? [_fromStyles setObject:@(currentHeight) forKey:@"height"]:0;
- _leftInfo.isAnimated ? [_fromStyles setObject:@(currentLeft) forKey:@"left"]:0;
- _rightInfo.isAnimated ? [_fromStyles setObject:@(currentRight) forKey:@"right"]:0;
- _topInfo.isAnimated ? [_fromStyles setObject:@(currentTop) forKey:@"top"]:0;
- _bottomInfo.isAnimated ? [_fromStyles setObject:@(currentBottom) forKey:@"bottom"]:0;
-
- NSLog(@"%@",_fromStyles);
-
- [self _fillCSSNode:_fromStyles];
-
-}
-
-
-
-
- (void)_frameDidCalculated:(BOOL)isChanged
{
WXAssertComponentThread();
@@ -616,78 +410,4 @@ static css_dim_t cssNodeMeasure(void *context, float width, css_measure_mode_t w
return (css_dim_t){resultSize.width, resultSize.height};
}
-
-//贝塞尔曲线计算
-- (void)unitBezierp1x:(double)p1x p1y:(double)p1y p2x:(double)p2x p2y:(double)p2y
-{
- cx = 3.0 * p1x;
- bx = 3.0 * (p2x - p1x) - cx;
- ax = 1.0 - cx -bx;
-
- cy = 3.0 * p1y;
- by = 3.0 * (p2y - p1y) - cy;
- ay = 1.0 - cy - by;
-}
-- (double)sampleCurveX:(double)t
-{
- return ((ax * t + bx) * t + cx) * t;
-}
-
-- (double)sampleCurveY:(double)t
-{
- return ((ay * t + by) * t + cy) * t;
-}
-
-- (double)sampleCurveDerivativeX:(double)t
-{
- return (3.0 * ax * t + 2.0 * bx) * t + cx;
-}
-
-- (double)solveCurveX:(double)x epsilon:(double)epsilon
-{
- double t0;
- double t1;
- double t2;
- double x2;
- double d2;
- int i;
-
- for (t2 = x, i = 0; i < 8; i++) {
- x2 = [self sampleCurveX:t2] - x;
- if (fabs (x2) < epsilon)
- return t2;
- d2 = [self sampleCurveDerivativeX:t2];
- if (fabs(d2) < 1e-6)
- break;
- t2 = t2 - x2 / d2;
- }
- t0 = 0.0;
- t1 = 1.0;
- t2 = x;
-
- if (t2 < t0)
- return t0;
- if (t2 > t1)
- return t1;
-
- while (t0 < t1) {
- x2 = [self sampleCurveX:t2];
- if (fabs(x2 - x) < epsilon)
- return t2;
- if (x > x2)
- t0 = t2;
- else
- t1 = t2;
- t2 = (t1 - t0) * .5 + t0;
- }
- return t2;
-}
-
-- (double)solveWithx:(double)x epsilon:(double)epsilon
-{
- return [self sampleCurveY:([self solveCurveX:x epsilon:epsilon])];
-}
-
-
-
@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/741ee207/ios/sdk/WeexSDK/Sources/Model/WXComponent.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Model/WXComponent.m b/ios/sdk/WeexSDK/Sources/Model/WXComponent.m
index 929d5a5..b8ae789 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Model/WXComponent.m
@@ -436,12 +436,13 @@
- (void)_updateStylesOnComponentThread:(NSDictionary *)styles resetStyles:(NSMutableArray *)resetStyles isUpdateStyles:(BOOL)isUpdateStyles
{
-
- //根据当前的style是否含有transitionProperty属性来判断是否有Layout Animation
- if (_styles[@"transitionProperty"]) {
- [self _handleLayoutAnimationWithStyles:styles];
+ if ([self _isPropertyTransition]) {
+ if (!_transition) {
+ _transition = [WXTransition new];
+ }
+ [_transition _handleTransitionWithStyles:styles withTarget:self];
}
- else//如果没有动画属性标明 直接触发layout
+ else
{
styles = [self parseStyles:styles];
[self _updateCSSNodeStyles:styles];
@@ -449,22 +450,30 @@
if (isUpdateStyles) {
[self _modifyStyles:styles];
- }//修改_style
+ }
[self _resetCSSNodeStyles:resetStyles];
}
-- (void)_modifyStyles:(NSDictionary *)styles //主要目的是来更新_style
+- (BOOL)_isPropertyTransition
+{
+ BOOL yesOrNo = false;
+ NSString *property = _styles[@"transitionProperty"];
+ if (property) {
+ if ([property containsString:@"width"]||[property containsString:@"height"]||[property containsString:@"top"]||[property containsString:@"left"]||[property containsString:@"bottom"]||[property containsString:@"transform"]) {
+ yesOrNo = true;
+ }
+ }
+ return yesOrNo;
+}
+
+- (void)_modifyStyles:(NSDictionary *)styles
{
pthread_mutex_lock(&_propertyMutex);
[_styles addEntriesFromDictionary:styles];
pthread_mutex_unlock(&_propertyMutex);
}
-
-
-
-
- (void)_updateAttributesOnComponentThread:(NSDictionary *)attributes
{
pthread_mutex_lock(&_propertyMutex);
@@ -669,6 +678,3 @@
}
@end
-@implementation WXLayoutAnimationInfo
-
-@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/741ee207/ios/sdk/WeexSDK/Sources/Module/WXAnimationLayout.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXAnimationLayout.h b/ios/sdk/WeexSDK/Sources/Module/WXAnimationLayout.h
deleted file mode 100644
index 1784498..0000000
--- a/ios/sdk/WeexSDK/Sources/Module/WXAnimationLayout.h
+++ /dev/null
@@ -1,49 +0,0 @@
-///*
-// * Licensed to the Apache Software Foundation (ASF) under one
-// * or more contributor license agreements. See the NOTICE file
-// * distributed with this work for additional information
-// * regarding copyright ownership. The ASF licenses this file
-// * to you under the Apache License, Version 2.0 (the
-// * "License"); you may not use this file except in compliance
-// * with the License. You may obtain a copy of the License at
-// *
-// * http://www.apache.org/licenses/LICENSE-2.0
-// *
-// * Unless required by applicable law or agreed to in writing,
-// * software distributed under the License is distributed on an
-// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// * KIND, either express or implied. See the License for the
-// * specific language governing permissions and limitations
-// * under the License.
-// */
-//
-//#import <Foundation/Foundation.h>
-//
-//#import "WXComponent.h"
-//#import "WXComponent_internal.h"
-//#import "NSTimer+Weex.h"
-//
-//@interface WXAnimationLayoutInfo : NSObject
-//
-//@property (nonatomic, strong) NSString *propertyName;
-//@property (nonatomic, strong) id fromValue;
-//@property (nonatomic, strong) id toValue;
-//
-//@end
-//
-//
-//@interface WXAnimationLayout : NSObject
-//
-//@property (nonatomic,strong) NSTimer *updateStyleTimer;
-//@property (nonatomic,strong) WXComponent *targetComponent;
-//@property (nonatomic,strong) NSDate *animationStartDate;
-//@property (nonatomic,strong) WXAnimationLayoutInfo *widthInfo;
-//@property (nonatomic,strong) WXAnimationLayoutInfo *heightInfo;
-//@property (nonatomic,assign) double animationDuration;
-//@property (nonatomic,assign) double animationDelay;
-//@property (nonatomic,strong) NSDictionary *needUpdateStyles;
-//@property (nonatomic, weak) WXSDKInstance *weexInstance;
-//
-//- (void)layoutForAnimation;
-//
-//@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/741ee207/ios/sdk/WeexSDK/Sources/Module/WXAnimationLayout.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXAnimationLayout.m b/ios/sdk/WeexSDK/Sources/Module/WXAnimationLayout.m
deleted file mode 100644
index 341f5d2..0000000
--- a/ios/sdk/WeexSDK/Sources/Module/WXAnimationLayout.m
+++ /dev/null
@@ -1,115 +0,0 @@
-///*
-// * Licensed to the Apache Software Foundation (ASF) under one
-// * or more contributor license agreements. See the NOTICE file
-// * distributed with this work for additional information
-// * regarding copyright ownership. The ASF licenses this file
-// * to you under the Apache License, Version 2.0 (the
-// * "License"); you may not use this file except in compliance
-// * with the License. You may obtain a copy of the License at
-// *
-// * http://www.apache.org/licenses/LICENSE-2.0
-// *
-// * Unless required by applicable law or agreed to in writing,
-// * software distributed under the License is distributed on an
-// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// * KIND, either express or implied. See the License for the
-// * specific language governing permissions and limitations
-// * under the License.
-// */
-//
-//#import "WXAnimationLayout.h"
-//#import "WXSDKInstance_private.h"
-//
-//@implementation WXAnimationLayoutInfo
-//
-//@end
-//
-//@implementation WXAnimationLayout
-//
-//- (instancetype)init
-//{
-// if (self = [super init]) {
-//
-// }
-// return self;
-//}
-//
-//- (void)layoutForAnimation
-//{
-// self.animationStartDate = [NSDate date];
-// if (_animationDelay > 0) {
-// [self performSelector:@selector(startUpdateStyleTimer) withObject:nil afterDelay:_animationDelay/1000];
-// } else {
-// [self startUpdateStyleTimer];
-// }
-//}
-//
-//#pragma mark UpdateStyle Methods
-//
-//- (void)startUpdateStyleTimer
-//{
-// if (!self.updateStyleTimer || ![self.updateStyleTimer isValid]) {
-// __weak __typeof__(self) weakSelf = self;
-// self.updateStyleTimer = [NSTimer wx_scheduledTimerWithTimeInterval:16/1000.0f block:^() {
-// [weakSelf updateStyleOnTimer];
-// } repeats:YES];
-// [[NSRunLoop currentRunLoop] addTimer:self.updateStyleTimer forMode:NSRunLoopCommonModes];
-// }
-//}
-//
-//- (void)stopUpdateStyleTimer
-//{
-// if (self.updateStyleTimer && [self.updateStyleTimer isValid]) {
-// [self.updateStyleTimer invalidate];
-// self.updateStyleTimer = nil;
-// }
-//}
-//
-//- (void)updateStyleOnTimer
-//{
-// NSTimeInterval startMsecond = [_animationStartDate timeIntervalSince1970]*1000;
-// NSTimeInterval nowMsecond = [[NSDate date] timeIntervalSince1970]*1000;
-// NSTimeInterval interval = nowMsecond - startMsecond;
-// if (!(_widthInfo || _heightInfo)) {
-// [self stopUpdateStyleTimer];
-// return;
-// }
-// if (interval > _animationDuration + _animationDelay) {
-// [self stopUpdateStyleTimer];
-// return;
-// }
-// CGFloat scaleFactor = self.weexInstance.pixelScaleFactor;
-// _needUpdateStyles = [[NSMutableDictionary alloc] init];
-// if (_widthInfo) {
-// double currentValue = (([_widthInfo.toValue doubleValue] - [_widthInfo.fromValue doubleValue]) * ((interval - _animationDelay) / _animationDuration) + [_widthInfo.fromValue doubleValue]) / scaleFactor;
-// [_needUpdateStyles setValue:[NSNumber numberWithDouble:currentValue] forKey:@"width"];
-// }
-// if (_heightInfo) {
-// double currentValue = (([_heightInfo.toValue doubleValue] - [_heightInfo.fromValue doubleValue]) * ((interval - _animationDelay) / _animationDuration) + [_heightInfo.fromValue doubleValue]) / scaleFactor;
-// [_needUpdateStyles setValue:[NSNumber numberWithDouble:currentValue] forKey:@"height"];
-// }
-// [self updateStyle:_needUpdateStyles];
-//}
-//
-//- (void)updateStyle:(NSDictionary *)styles
-//{
-// if ([styles count]>0) {
-// __weak typeof(self) weakSelf = self;
-// WXPerformBlockOnComponentThread(^{
-// WXComponentManager *manager = weakSelf.weexInstance.componentManager;
-// if (!manager.isValid) {
-// return;
-// }
-// [manager updateStyles:styles forComponent:_targetComponent.ref];
-// [manager startComponentTasks];
-// });
-// }
-//}
-//
-//- (void)dealloc
-//{
-// [self stopUpdateStyleTimer];
-// [NSObject cancelPreviousPerformRequestsWithTarget:self];
-//}
-//
-//@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/741ee207/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.h b/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.h
index ae7f068..d5a8c43 100644
--- a/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.h
+++ b/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.h
@@ -22,6 +22,8 @@
@interface WXAnimationModule : NSObject <WXModuleProtocol>
+
- (void)animation:(WXComponent *)targetComponent args:(NSDictionary *)args callback:(WXModuleCallback)callback;
+- (void)animationModuleProcessAnimationWithArgs:(NSDictionary *)args withWeexInstance:(WXSDKInstance *)instance targetComponent:(WXComponent *)target;
@end
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/741ee207/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m b/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
index 46cf68a..dc01af3 100644
--- a/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
+++ b/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
@@ -24,7 +24,7 @@
#import "WXTransform.h"
#import "WXUtility.h"
#import "WXLength.h"
-#import "WXAnimationLayout.h"
+#import "WXTransition.h"
@interface WXAnimationInfo : NSObject<NSCopying>
@@ -36,7 +36,6 @@
@property (nonatomic, assign) double delay;
@property (nonatomic, strong) CAMediaTimingFunction *timingFunction;
@property (nonatomic, assign) CGPoint originAnchorPoint;
-
@end
@implementation WXAnimationInfo
@@ -137,8 +136,9 @@
@interface WXAnimationModule ()
-//@property (nonatomic,strong) WXAnimationLayout *animationLayout;
@property (nonatomic,assign) BOOL needLayout;
+@property (nonatomic, strong) WXTransition *transition;
+
@end
@implementation WXAnimationModule
@@ -150,8 +150,6 @@ WX_EXPORT_METHOD(@selector(transition:args:callback:))
- (void)transition:(NSString *)nodeRef args:(NSDictionary *)args callback:(WXModuleCallback)callback
{
_needLayout = NO;
-// _animationLayout = [[WXAnimationLayout alloc] init];
-// _animationLayout.weexInstance = self.weexInstance;
WXPerformBlockOnComponentThread(^{
WXComponent *targetComponent = [self.weexInstance componentForRef:nodeRef];
if (!targetComponent) {
@@ -177,9 +175,8 @@ WX_EXPORT_METHOD(@selector(transition:args:callback:))
double delay = [args[@"delay"] doubleValue] / 1000;
if (args[@"needLayout"]) {
_needLayout = [WXConvert BOOL:args[@"needLayout"]];
+ _transition = [WXTransition new];
}
-// _animationLayout.animationDuration = duration * 1000;
-// _animationLayout.animationDelay = delay * 1000;
CAMediaTimingFunction *timingFunction = [WXConvert CAMediaTimingFunction:args[@"timingFunction"]];
NSDictionary *styles = args[@"styles"];
for (NSString *property in styles) {
@@ -276,10 +273,6 @@ WX_EXPORT_METHOD(@selector(transition:args:callback:))
} else if ([property isEqualToString:@"width"]) {
if (_needLayout) {
[self animationWithLayoutAnimationTarget:target handleProperty:property withDic:args];
- // _animationLayout.widthInfo = [[WXAnimationLayoutInfo alloc] init];
- // _animationLayout.widthInfo.toValue = info.toValue;
- // _animationLayout.widthInfo.fromValue = info.fromValue;
- // _animationLayout.widthInfo.propertyName = info.propertyName;
}
else
{
@@ -293,10 +286,6 @@ WX_EXPORT_METHOD(@selector(transition:args:callback:))
} else if ([property isEqualToString:@"height"]) {
if (_needLayout) {
[self animationWithLayoutAnimationTarget:target handleProperty:property withDic:args];
- // _animationLayout.heightInfo = [[WXAnimationLayoutInfo alloc] init];
- // _animationLayout.heightInfo.toValue = info.toValue;
- // _animationLayout.heightInfo.fromValue = info.fromValue;
- // _animationLayout.heightInfo.propertyName = info.propertyName;
}
else
{
@@ -313,14 +302,20 @@ WX_EXPORT_METHOD(@selector(transition:args:callback:))
return infos;
}
+- (void)animationModuleProcessAnimationWithArgs:(NSDictionary *)args withWeexInstance:(WXSDKInstance *)instance targetComponent:(WXComponent *)target
+{
+ self.weexInstance = instance;
+ [self animation:target args:args callback:nil];
+}
+
- (void)animationWithLayoutAnimationTarget:(WXComponent *)target handleProperty:(NSString *)property withDic:(NSDictionary *)args
{
NSDictionary *styles = args[@"styles"];
- target->_addStyles = [NSMutableDictionary dictionaryWithDictionary:styles];
- target->_fromStyles = target->_fromStyles ? :[NSMutableDictionary dictionaryWithDictionary:target.styles] ;
- [target->_fromStyles setObject:@([args[@"duration"] doubleValue]) forKey:@"transitionDuration"];
- [target->_fromStyles setObject:@([args[@"delay"] doubleValue]) forKey:@"transitionDelay"];
- NSString *oldProperty = target->_fromStyles[@"transitionProperty"];
+ _transition.addStyles = [NSMutableDictionary dictionaryWithDictionary:styles];
+ _transition.fromStyles =_transition.fromStyles ? :[NSMutableDictionary dictionaryWithDictionary:target.styles] ;
+ [_transition.fromStyles setObject:@([args[@"duration"] doubleValue]) forKey:@"transitionDuration"];
+ [_transition.fromStyles setObject:@([args[@"delay"] doubleValue]) forKey:@"transitionDelay"];
+ NSString *oldProperty = _transition.fromStyles[@"transitionProperty"];
NSString *newProperty;
if (oldProperty) {
if ([oldProperty containsString:property]) {
@@ -335,14 +330,11 @@ WX_EXPORT_METHOD(@selector(transition:args:callback:))
{
newProperty = property;
}
- [target->_fromStyles setObject:newProperty forKey:@"transitionProperty"];
- [target->_fromStyles setObject:args[@"timingFunction"] forKey:@"transitionTimingFunction"];
+ [_transition.fromStyles setObject:newProperty forKey:@"transitionProperty"];
+ [_transition.fromStyles setObject:args[@"timingFunction"] forKey:@"transitionTimingFunction"];
[target _modifyStyles:styles];
}
-
-
-
- (void)animation:(WXComponent *)targetComponent args:(NSDictionary *)args callback:(WXModuleCallback)callback
{
/**
@@ -364,10 +356,8 @@ WX_EXPORT_METHOD(@selector(transition:args:callback:))
[CATransaction commit];
if (_needLayout) {
- // _animationLayout.targetComponent = targetComponent;
- // [_animationLayout layoutForAnimation];
WXPerformBlockOnComponentThread(^{
- [targetComponent _handleLayoutAnimationWithStyles:targetComponent->_addStyles];
+ [_transition _handleTransitionWithStyles:_transition.addStyles withTarget:targetComponent];
});
}
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/741ee207/ios/sdk/WeexSDK/Sources/Module/WXTransition.h
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXTransition.h b/ios/sdk/WeexSDK/Sources/Module/WXTransition.h
new file mode 100644
index 0000000..9a0d5a8
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXTransition.h
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+@interface WXLayoutAnimationInfo : NSObject
+@property (nonatomic, strong) id fromValue;
+@property (nonatomic, strong) id toValue;
+@property (nonatomic, strong) id perValue;
+@property (nonatomic, strong) NSString *propertyName;
+
+@end
+
+@interface WXTransition : NSObject
+@property(nonatomic,strong) NSMutableDictionary *fromStyles;
+@property(nonatomic,strong) NSMutableDictionary *addStyles;
+@property(nonatomic,strong) NSMutableArray *propertyArray;
+- (void)_handleTransitionWithStyles:(NSDictionary *)styles withTarget:(WXComponent *)targetComponent;
+
+@end
+
+
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/741ee207/ios/sdk/WeexSDK/Sources/Module/WXTransition.m
----------------------------------------------------------------------
diff --git a/ios/sdk/WeexSDK/Sources/Module/WXTransition.m b/ios/sdk/WeexSDK/Sources/Module/WXTransition.m
new file mode 100644
index 0000000..26d9fb9
--- /dev/null
+++ b/ios/sdk/WeexSDK/Sources/Module/WXTransition.m
@@ -0,0 +1,299 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#define SOLVE_EPS(dur) (1. / (1000. * (dur)))
+
+#import <QuartzCore/CATransaction.h>
+#import <QuartzCore/CADisplayLink.h>
+#import "WXAnimationModule.h"
+#import "WXComponentManager.h"
+#import "WXSDKInstance.h"
+#import "WXComponent+Layout.h"
+#import "WXComponent_internal.h"
+#import "WXTransition.h"
+#import "WXUtility.h"
+#import "WXAssert.h"
+#import "WXSDKInstance_private.h"
+
+@implementation WXLayoutAnimationInfo
+
+@end
+
+@interface WXTransition()
+{
+ WXComponent *_targetComponent;
+
+ double ax;
+ double bx;
+ double cx;
+
+ double ay;
+ double by;
+ double cy;
+
+ float _layoutAnimationDuration;
+ float _layoutAnimationDelay;
+ NSUInteger _layoutAnimationCount;
+
+ CAMediaTimingFunction *_layoutAnimationTimingFunction;
+ CADisplayLink *_layoutAnimationDisplayLink;
+
+ NSMutableDictionary *_toStyles;
+ NSMutableDictionary *_fromStyles;
+ NSMutableDictionary *_addStyles;
+}
+
+@end
+
+@implementation WXTransition
+
+- (void)_handleTransitionWithStyles:(NSDictionary *)styles withTarget:(WXComponent *)targetComponent
+{
+ [self _suspendLayoutAnimationDisplayLink];
+ _targetComponent = targetComponent;
+ if (!_addStyles) {
+ _fromStyles = [NSMutableDictionary dictionaryWithDictionary:targetComponent.styles];
+ _addStyles = [NSMutableDictionary dictionaryWithDictionary:styles];
+ }
+ else
+ {
+ [_addStyles addEntriesFromDictionary:styles];
+ }
+
+ _toStyles = [NSMutableDictionary dictionaryWithDictionary:_fromStyles];
+ [_toStyles addEntriesFromDictionary:_addStyles];
+
+ _layoutAnimationDuration = _fromStyles[@"transitionDuration"] ? [WXConvert CGFloat:_fromStyles[@"transitionDuration"]] : 0;
+ _layoutAnimationDelay = _fromStyles[@"transitionDelay"] ? [WXConvert CGFloat:_fromStyles[@"transitionDelay"]] : 0;
+ _layoutAnimationTimingFunction = [WXConvert CAMediaTimingFunction:_fromStyles[@"transitionTimingFunction"]];
+
+ if (_layoutAnimationDuration == 0) {
+ [targetComponent _updateCSSNodeStyles:styles];
+ WXPerformBlockOnMainThread(^{
+ [targetComponent _updateViewStyles:styles];
+ });
+ return;
+ }
+
+ if (![[NSString stringWithFormat:@"%@",_layoutAnimationTimingFunction] isEqualToString: kCAMediaTimingFunctionLinear]) {
+ float vec[4] = {0.};
+ [_layoutAnimationTimingFunction getControlPointAtIndex:1 values:&vec[0]];
+ [_layoutAnimationTimingFunction getControlPointAtIndex:2 values:&vec[2]];
+ [self unitBezierp1x:vec[0] p1y:vec[1] p2x:vec[2] p2y:vec[3]];
+ }
+
+ NSString *layoutAnimationProperty = _fromStyles[@"transitionProperty"];
+ [self _resloveTransitionProperty:layoutAnimationProperty withStyles:styles];
+ [self performSelector:@selector(_startLayoutAnimationDisplayLink) withObject:self afterDelay:_layoutAnimationDelay/1000];
+}
+
+- (void)_resloveTransitionProperty:(NSString *)propertyNames withStyles:(NSDictionary *)styles
+{
+ NSArray *array = @[@"width",@"height",@"top",@"bottom",@"right",@"left",@"transform",@"backgroundColor",@"opacity"];
+ for (NSString *propertyName in array) {
+ if ([propertyNames containsString:propertyName]) {
+ [self _judgeProperty:propertyName withStyles:styles];
+ }
+ }
+}
+
+- (void)_judgeProperty:(NSString *)singleProperty withStyles:(NSDictionary *)styles
+{
+ if (([singleProperty isEqualToString:@"transform"]&&styles[@"transform"]) || ([singleProperty containsString:@"backgroundColor"]&&styles[@"backgroundColor"]) || ([singleProperty containsString:@"opacity"]&&styles[@"opacity"])) {
+ NSDictionary *args = @{@"delay":@(_layoutAnimationDelay),@"duration":@(_layoutAnimationDuration),@"styles":styles,@"timingFunction":_fromStyles[@"transitionTimingFunction"]};
+ [self _animationModuleHandleTransition:args];
+ }
+ else{
+ WXLayoutAnimationInfo *info = [WXLayoutAnimationInfo new];
+ info.fromValue = @(_fromStyles[singleProperty] ? [WXConvert CGFloat:_fromStyles[singleProperty]] : 0);
+ info.toValue = @(_toStyles[singleProperty] ? [WXConvert CGFloat:_toStyles[singleProperty]] : 0 );
+ info.perValue = @([info.toValue doubleValue] - [info.fromValue doubleValue]);
+ info.propertyName = singleProperty;
+ if (!_propertyArray) {
+ _propertyArray = [NSMutableArray new];
+ }
+ [_propertyArray addObject:info];
+ }
+}
+
+- (void)_calculateLayoutAnimationProcessingStyle
+{
+ double per = 1000 * (_layoutAnimationCount + 1 ) / (60 * _layoutAnimationDuration);//linear
+ if (![[NSString stringWithFormat:@"%@",_layoutAnimationTimingFunction] isEqualToString: kCAMediaTimingFunctionLinear]) {
+ per = [self solveWithx:((_layoutAnimationCount+2)*16)/_layoutAnimationDuration epsilon:SOLVE_EPS(_layoutAnimationDuration)];
+ }
+ for (WXLayoutAnimationInfo *info in _propertyArray) {
+ double currentValue = [info.fromValue doubleValue] + [info.perValue doubleValue] * per;
+ [_fromStyles setObject:@(currentValue) forKey:info.propertyName];
+ }
+ [_targetComponent _updateCSSNodeStyles:_fromStyles];
+ [_targetComponent.weexInstance.componentManager startComponentTasks];
+}
+
+- (void)_startLayoutAnimationDisplayLink
+{
+ WXAssertComponentThread();
+ if (!_layoutAnimationDisplayLink) {
+ _layoutAnimationDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(_handleLayoutAnimationDisplayLink)];
+ [_layoutAnimationDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
+ }
+ else{
+ [self _awakeLayoutAnimationDisplayLink];
+ }
+}
+
+- (void)_stopLayoutAnimationDisplayLink
+{
+ WXAssertComponentThread();
+ if (_layoutAnimationDisplayLink) {
+ [_layoutAnimationDisplayLink invalidate];
+ _layoutAnimationDisplayLink = nil;
+ }
+}
+
+- (void)_suspendLayoutAnimationDisplayLink
+{
+ WXAssertComponentThread();
+ if(_layoutAnimationDisplayLink && !_layoutAnimationDisplayLink.paused)
+ {
+ _layoutAnimationDisplayLink.paused = YES;
+ }
+}
+
+- (void)_awakeLayoutAnimationDisplayLink
+{
+ WXAssertComponentThread();
+ if (_layoutAnimationDisplayLink && _layoutAnimationDisplayLink.paused) {
+ _layoutAnimationDisplayLink.paused = NO;
+ }
+}
+
+- (void)_handleLayoutAnimationDisplayLink
+{
+ WXAssertComponentThread();
+ int count = _layoutAnimationDuration * 60 / 1000;
+ if (_layoutAnimationCount >= count) {
+ [self _suspendLayoutAnimationDisplayLink];
+ [self _resetProcessAnimationParameter];
+ return;
+ }
+ else
+ {
+ [self _calculateLayoutAnimationProcessingStyle];
+ }
+ _layoutAnimationCount ++;
+}
+
+- (void)_resetProcessAnimationParameter
+{
+ _layoutAnimationCount = 0;
+ _layoutAnimationDuration = 0;
+
+}
+
+- (void)_animationModuleHandleTransition:(NSDictionary *)args
+{
+ WXAnimationModule *animation = [WXAnimationModule new];
+ WXPerformBlockOnMainThread(^{
+ [animation animationModuleProcessAnimationWithArgs:args withWeexInstance:_targetComponent.weexInstance targetComponent:_targetComponent];
+ });
+}
+
+- (NSMutableDictionary *)_addStyles
+{
+ return self.addStyles;
+}
+
+- (NSMutableDictionary *)_fromStyles
+{
+ return self.fromStyles;
+}
+
+- (void)unitBezierp1x:(double)p1x p1y:(double)p1y p2x:(double)p2x p2y:(double)p2y
+{
+ cx = 3.0 * p1x;
+ bx = 3.0 * (p2x - p1x) - cx;
+ ax = 1.0 - cx -bx;
+
+ cy = 3.0 * p1y;
+ by = 3.0 * (p2y - p1y) - cy;
+ ay = 1.0 - cy - by;
+}
+
+- (double)sampleCurveX:(double)t
+{
+ return ((ax * t + bx) * t + cx) * t;
+}
+
+- (double)sampleCurveY:(double)t
+{
+ return ((ay * t + by) * t + cy) * t;
+}
+
+- (double)sampleCurveDerivativeX:(double)t
+{
+ return (3.0 * ax * t + 2.0 * bx) * t + cx;
+}
+
+- (double)solveCurveX:(double)x epsilon:(double)epsilon
+{
+ double t0;
+ double t1;
+ double t2;
+ double x2;
+ double d2;
+ int i;
+
+ for (t2 = x, i = 0; i < 8; i++) {
+ x2 = [self sampleCurveX:t2] - x;
+ if (fabs (x2) < epsilon)
+ return t2;
+ d2 = [self sampleCurveDerivativeX:t2];
+ if (fabs(d2) < 1e-6)
+ break;
+ t2 = t2 - x2 / d2;
+ }
+ t0 = 0.0;
+ t1 = 1.0;
+ t2 = x;
+
+ if (t2 < t0)
+ return t0;
+ if (t2 > t1)
+ return t1;
+
+ while (t0 < t1) {
+ x2 = [self sampleCurveX:t2];
+ if (fabs(x2 - x) < epsilon)
+ return t2;
+ if (x > x2)
+ t0 = t2;
+ else
+ t1 = t2;
+ t2 = (t1 - t0) * .5 + t0;
+ }
+ return t2;
+}
+
+- (double)solveWithx:(double)x epsilon:(double)epsilon
+{
+ return [self sampleCurveY:([self solveCurveX:x epsilon:epsilon])];
+}
+
+@end