Repository: incubator-weex
Updated Branches:
  refs/heads/0.16-dev 46b98bba9 -> ee94722cf


+ [ios] LayoutAnimation


Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/6bd86e56
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/6bd86e56
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/6bd86e56

Branch: refs/heads/0.16-dev
Commit: 6bd86e5625bff1310a48244fd2c74db307b9314e
Parents: 1ebd484
Author: doumafang <doumaf...@gmail.com>
Authored: Tue Aug 8 20:31:03 2017 +0800
Committer: doumafang <doumaf...@gmail.com>
Committed: Tue Aug 8 20:31:03 2017 +0800

----------------------------------------------------------------------
 .../Sources/Component/WXComponent_internal.h    |  45 +++
 .../WeexSDK/Sources/Layout/WXComponent+Layout.m | 281 +++++++++++++++++++
 ios/sdk/WeexSDK/Sources/Model/WXComponent.m     |  33 ++-
 .../WeexSDK/Sources/Module/WXAnimationLayout.h  |  98 +++----
 .../WeexSDK/Sources/Module/WXAnimationLayout.m  | 230 +++++++--------
 .../WeexSDK/Sources/Module/WXAnimationModule.m  |  94 +++++--
 6 files changed, 584 insertions(+), 197 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/6bd86e56/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 7226ced..d2b7d54 100644
--- a/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
+++ b/ios/sdk/WeexSDK/Sources/Component/WXComponent_internal.h
@@ -23,6 +23,8 @@
 #import "WXTransform.h"
 @class WXTouchGestureRecognizer;
 @class WXThreadSafeCounter;
+@class WXLayoutAnimationInfo;
+
 
 /**
  * The following variables and methods are used in Weex INTERNAL logic.
@@ -42,6 +44,36 @@
     CGPoint _absolutePosition;
     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;
+
+    
+    
     /**
      *  View
      */
@@ -171,6 +203,11 @@
 /// @name Private Methods
 ///--------------------------------------
 
+- (void)_handleLayoutAnimationWithStyles:(NSDictionary *)styles;
+
+- (void)_modifyStyles:(NSDictionary *)styles;
+
+
 - (void)_initCSSNodeWithStyles:(NSDictionary *)styles;
 
 - (void)_updateCSSNodeStyles:(NSDictionary *)styles;
@@ -214,3 +251,11 @@
 - (void)setGradientLayer;
 
 @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/6bd86e56/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 58e76bf..14034a6 100644
--- a/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.m
+++ b/ios/sdk/WeexSDK/Sources/Layout/WXComponent+Layout.m
@@ -17,6 +17,9 @@
  * under the License.
  */
 
+#define SOLVE_EPS(dur) (1. / (1000. * (dur)))
+
+
 #import "WXComponent+Layout.h"
 #import "WXComponent_internal.h"
 #import "WXTransform.h"
@@ -112,6 +115,211 @@
     return (int)(count);
 }
 
+
+#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();
@@ -409,4 +617,77 @@ 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/6bd86e56/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 bd5549b..929d5a5 100644
--- a/ios/sdk/WeexSDK/Sources/Model/WXComponent.m
+++ b/ios/sdk/WeexSDK/Sources/Model/WXComponent.m
@@ -436,16 +436,35 @@
 
 - (void)_updateStylesOnComponentThread:(NSDictionary *)styles 
resetStyles:(NSMutableArray *)resetStyles isUpdateStyles:(BOOL)isUpdateStyles
 {
-    if (isUpdateStyles) {
-        pthread_mutex_lock(&_propertyMutex);
-        [_styles addEntriesFromDictionary:styles];
-        pthread_mutex_unlock(&_propertyMutex);
+    
+    //æ 
¹æ®å½“前的style是否含有transitionProperty属性来判断是否有Layout 
Animation
+    if (_styles[@"transitionProperty"]) {
+        [self _handleLayoutAnimationWithStyles:styles];
     }
-    styles = [self parseStyles:styles];
-    [self _updateCSSNodeStyles:styles];
+    else//如果没有动画属性标明 直接触发layout
+    {
+        styles = [self parseStyles:styles];
+        [self _updateCSSNodeStyles:styles];
+    }
+    
+    if (isUpdateStyles) {
+        [self _modifyStyles:styles];
+    }//修改_style
+    
     [self _resetCSSNodeStyles:resetStyles];
 }
 
+- (void)_modifyStyles:(NSDictionary *)styles //主要目的是来更新_style
+{
+    pthread_mutex_lock(&_propertyMutex);
+    [_styles addEntriesFromDictionary:styles];
+    pthread_mutex_unlock(&_propertyMutex);
+}
+
+
+
+
+
 - (void)_updateAttributesOnComponentThread:(NSDictionary *)attributes
 {
     pthread_mutex_lock(&_propertyMutex);
@@ -650,4 +669,6 @@
 }
 
 @end
+@implementation WXLayoutAnimationInfo
 
+@end

http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/6bd86e56/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
index b239c22..1784498 100644
--- a/ios/sdk/WeexSDK/Sources/Module/WXAnimationLayout.h
+++ b/ios/sdk/WeexSDK/Sources/Module/WXAnimationLayout.h
@@ -1,49 +1,49 @@
-/*
- * 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
+///*
+// * 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/6bd86e56/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
index 087135e..341f5d2 100644
--- a/ios/sdk/WeexSDK/Sources/Module/WXAnimationLayout.m
+++ b/ios/sdk/WeexSDK/Sources/Module/WXAnimationLayout.m
@@ -1,115 +1,115 @@
-/*
- * 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
+///*
+// * 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/6bd86e56/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 38651e0..46cf68a 100644
--- a/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
+++ b/ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
@@ -137,7 +137,7 @@
 
 @interface WXAnimationModule ()
 
-@property (nonatomic,strong) WXAnimationLayout *animationLayout;
+//@property (nonatomic,strong) WXAnimationLayout *animationLayout;
 @property (nonatomic,assign) BOOL needLayout;
 @end
 
@@ -150,8 +150,8 @@ 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;
+//    _animationLayout = [[WXAnimationLayout alloc] init];
+//    _animationLayout.weexInstance = self.weexInstance;
     WXPerformBlockOnComponentThread(^{
         WXComponent *targetComponent = [self.weexInstance 
componentForRef:nodeRef];
         if (!targetComponent) {
@@ -178,8 +178,8 @@ WX_EXPORT_METHOD(@selector(transition:args:callback:))
     if (args[@"needLayout"]) {
         _needLayout = [WXConvert BOOL:args[@"needLayout"]];
     }
-    _animationLayout.animationDuration = duration * 1000;
-    _animationLayout.animationDelay = delay * 1000;
+//    _animationLayout.animationDuration = duration * 1000;
+//    _animationLayout.animationDelay = delay * 1000;
     CAMediaTimingFunction *timingFunction = [WXConvert 
CAMediaTimingFunction:args[@"timingFunction"]];
     NSDictionary *styles = args[@"styles"];
     for (NSString *property in styles) {
@@ -274,30 +274,38 @@ WX_EXPORT_METHOD(@selector(transition:args:callback:))
             info.toValue = @([value floatValue]);
             [infos addObject:info];
         } else if ([property isEqualToString:@"width"]) {
-            info.propertyName = @"bounds.size.width";
-            info.fromValue = @(layer.bounds.size.width);
-            CGRect newBounds = layer.bounds;
-            newBounds.size = CGSizeMake([WXConvert WXPixelType:value 
scaleFactor:self.weexInstance.pixelScaleFactor], newBounds.size.height);
-            info.toValue = @(newBounds.size.width);
-            [infos addObject:info];
             if (_needLayout) {
-                _animationLayout.widthInfo = [[WXAnimationLayoutInfo alloc] 
init];
-                _animationLayout.widthInfo.toValue = info.toValue;
-                _animationLayout.widthInfo.fromValue = info.fromValue;
-                _animationLayout.widthInfo.propertyName = info.propertyName;
+                [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
+            {
+                info.propertyName = @"bounds.size.width";
+                info.fromValue = @(layer.bounds.size.width);
+                CGRect newBounds = layer.bounds;
+                newBounds.size = CGSizeMake([WXConvert WXPixelType:value 
scaleFactor:self.weexInstance.pixelScaleFactor], newBounds.size.height);
+                info.toValue = @(newBounds.size.width);
+                [infos addObject:info];
             }
         } else if ([property isEqualToString:@"height"]) {
-            info.propertyName = @"bounds.size.height";
-            info.fromValue = @(layer.bounds.size.height);
-            CGRect newBounds = layer.bounds;
-            newBounds.size = CGSizeMake(newBounds.size.width, [WXConvert 
WXPixelType:value scaleFactor:self.weexInstance.pixelScaleFactor]);
-            info.toValue = @(newBounds.size.height);
-            [infos addObject:info];
             if (_needLayout) {
-                _animationLayout.heightInfo = [[WXAnimationLayoutInfo alloc] 
init];
-                _animationLayout.heightInfo.toValue = info.toValue;
-                _animationLayout.heightInfo.fromValue = info.fromValue;
-                _animationLayout.heightInfo.propertyName = info.propertyName;
+                [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
+            {
+                info.propertyName = @"bounds.size.height";
+                info.fromValue = @(layer.bounds.size.height);
+                CGRect newBounds = layer.bounds;
+                newBounds.size = CGSizeMake(newBounds.size.width, [WXConvert 
WXPixelType:value scaleFactor:self.weexInstance.pixelScaleFactor]);
+                info.toValue = @(newBounds.size.height);
+                [infos addObject:info];
             }
         }
     }
@@ -305,6 +313,35 @@ WX_EXPORT_METHOD(@selector(transition:args:callback:))
     return infos;
 }
 
+- (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"];
+    NSString *newProperty;
+    if (oldProperty) {
+        if ([oldProperty containsString:property]) {
+            newProperty = oldProperty;
+        }
+        else
+        {
+            newProperty = [NSString 
stringWithFormat:@"%@,%@",oldProperty,property];
+        }
+    }
+    else
+    {
+        newProperty = property;
+    }
+    [target->_fromStyles setObject:newProperty forKey:@"transitionProperty"];
+    [target->_fromStyles setObject:args[@"timingFunction"] 
forKey:@"transitionTimingFunction"];
+    [target _modifyStyles:styles];
+    
+}
+
+
 
 - (void)animation:(WXComponent *)targetComponent args:(NSDictionary *)args 
callback:(WXModuleCallback)callback
 {
@@ -327,8 +364,11 @@ WX_EXPORT_METHOD(@selector(transition:args:callback:))
     
     [CATransaction commit];
     if (_needLayout) {
-        _animationLayout.targetComponent = targetComponent;
-        [_animationLayout layoutForAnimation];
+        //        _animationLayout.targetComponent = targetComponent;
+        //        [_animationLayout layoutForAnimation];
+        WXPerformBlockOnComponentThread(^{
+            [targetComponent 
_handleLayoutAnimationWithStyles:targetComponent->_addStyles];
+        });
     }
 }
 

Reply via email to