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

0.13 dev animate #336

Merged
merged 4 commits into from
May 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions ios/sdk/WeexSDK.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
2AE5B7561CABA04E0082FDDB /* WXEventModuleProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AE5B7551CABA04E0082FDDB /* WXEventModuleProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
2AFEB17B1C747139000507FA /* WXInstanceWrap.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AFEB1791C747139000507FA /* WXInstanceWrap.h */; };
2AFEB17C1C747139000507FA /* WXInstanceWrap.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AFEB17A1C747139000507FA /* WXInstanceWrap.m */; };
375A228F1EC440A600BC2086 /* WXAnimationLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 375A228D1EC440A600BC2086 /* WXAnimationLayout.m */; };
375A22901EC440A600BC2086 /* WXAnimationLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 375A228E1EC440A600BC2086 /* WXAnimationLayout.h */; };
37B51EE41E97804D0040A743 /* WXCycleSliderComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 37B51EE21E97804D0040A743 /* WXCycleSliderComponent.h */; };
37B51EE51E97804D0040A743 /* WXCycleSliderComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 37B51EE31E97804D0040A743 /* WXCycleSliderComponent.m */; };
591324A31D49B7F1004E89ED /* WXTimerModuleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 591324A21D49B7F1004E89ED /* WXTimerModuleTests.m */; };
Expand Down Expand Up @@ -347,6 +349,8 @@
2AE5B7551CABA04E0082FDDB /* WXEventModuleProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXEventModuleProtocol.h; sourceTree = "<group>"; };
2AFEB1791C747139000507FA /* WXInstanceWrap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXInstanceWrap.h; sourceTree = "<group>"; };
2AFEB17A1C747139000507FA /* WXInstanceWrap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXInstanceWrap.m; sourceTree = "<group>"; };
375A228D1EC440A600BC2086 /* WXAnimationLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXAnimationLayout.m; sourceTree = "<group>"; };
375A228E1EC440A600BC2086 /* WXAnimationLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXAnimationLayout.h; sourceTree = "<group>"; };
37B51EE21E97804D0040A743 /* WXCycleSliderComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXCycleSliderComponent.h; sourceTree = "<group>"; };
37B51EE31E97804D0040A743 /* WXCycleSliderComponent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXCycleSliderComponent.m; sourceTree = "<group>"; };
591324A21D49B7F1004E89ED /* WXTimerModuleTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXTimerModuleTests.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1070,6 +1074,8 @@
74A4BAA51CB4F98300195969 /* WXStreamModule.m */,
594C28911CF9E61A009793A4 /* WXAnimationModule.h */,
594C28901CF9E61A009793A4 /* WXAnimationModule.m */,
375A228D1EC440A600BC2086 /* WXAnimationLayout.m */,
375A228E1EC440A600BC2086 /* WXAnimationLayout.h */,
2AFEB1791C747139000507FA /* WXInstanceWrap.h */,
2AFEB17A1C747139000507FA /* WXInstanceWrap.m */,
77E659D81C07F594008B8775 /* WXDomModule.h */,
Expand Down Expand Up @@ -1226,6 +1232,7 @@
2A837AB41CD9DE9200AEDF03 /* WXLoadingIndicator.h in Headers */,
747A787C1D1BAAC900DED9D0 /* WXComponent+ViewManagement.h in Headers */,
DC0F99311D48E5320087C6AF /* WeexSDK.h in Headers */,
375A22901EC440A600BC2086 /* WXAnimationLayout.h in Headers */,
2AE5B7561CABA04E0082FDDB /* WXEventModuleProtocol.h in Headers */,
C4C30DE91E1B833D00786B6C /* WXComponent+PseudoClassManagement.h in Headers */,
591DD3321D23AD5800BE8709 /* WXErrorView.h in Headers */,
Expand Down Expand Up @@ -1552,6 +1559,7 @@
59A5961D1CB630F10012CD52 /* WXComponent+Navigation.m in Sources */,
77D161631C02ED790010B15B /* WXLog.m in Sources */,
744BEA5A1D0520F300452B5D /* WXComponent+Layout.m in Sources */,
375A228F1EC440A600BC2086 /* WXAnimationLayout.m in Sources */,
59A582FD1CF5B17B0081FD3E /* WXBridgeContext.m in Sources */,
743933B51C7ED9AA00773BB7 /* WXSimulatorShortcutManager.m in Sources */,
74BB5FBA1DFEE81A004FC3DF /* WXMetaModule.m in Sources */,
Expand Down
49 changes: 49 additions & 0 deletions ios/sdk/WeexSDK/Sources/Module/WXAnimationLayout.h
Original file line number Diff line number Diff line change
@@ -0,0 +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
115 changes: 115 additions & 0 deletions ios/sdk/WeexSDK/Sources/Module/WXAnimationLayout.m
Original file line number Diff line number Diff line change
@@ -0,0 +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
30 changes: 28 additions & 2 deletions ios/sdk/WeexSDK/Sources/Module/WXAnimationModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#import "WXTransform.h"
#import "WXUtility.h"
#import "WXLength.h"
#import "WXAnimationLayout.h"

@interface WXAnimationInfo : NSObject<NSCopying>

Expand Down Expand Up @@ -79,7 +80,6 @@ - (instancetype)initWithAnimationInfo:(WXAnimationInfo *)info finishBlock:(void
_animationInfo = info;
_finishBlock = finishBlock;
}

return self;
}

Expand Down Expand Up @@ -133,6 +133,8 @@ - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag

@interface WXAnimationModule ()

@property (nonatomic,strong) WXAnimationLayout *animationLayout;
@property (nonatomic,assign) BOOL needLayout;
@end

@implementation WXAnimationModule
Expand All @@ -143,6 +145,9 @@ @implementation WXAnimationModule

- (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) {
Expand All @@ -166,6 +171,11 @@ - (void)transition:(NSString *)nodeRef args:(NSDictionary *)args callback:(WXMod

double duration = [args[@"duration"] doubleValue] / 1000;
double delay = [args[@"delay"] doubleValue] / 1000;
if (args[@"needLayout"]) {
_needLayout = [WXConvert BOOL:args[@"needLayout"]];
}
_animationLayout.animationDuration = duration * 1000;
_animationLayout.animationDelay = delay * 1000;
CAMediaTimingFunction *timingFunction = [WXConvert CAMediaTimingFunction:args[@"timingFunction"]];
NSDictionary *styles = args[@"styles"];
for (NSString *property in styles) {
Expand Down Expand Up @@ -242,13 +252,25 @@ - (void)transition:(NSString *)nodeRef args:(NSDictionary *)args callback:(WXMod
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;
}
} 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;
}
}
}

Expand All @@ -274,8 +296,12 @@ - (void)animation:(WXComponent *)targetComponent args:(NSDictionary *)args callb
for (WXAnimationInfo *info in infos) {
[self _createCAAnimation:info];
}

[CATransaction commit];
if (_needLayout) {
_animationLayout.targetComponent = targetComponent;
[_animationLayout layoutForAnimation];
}
}

- (void)_createCAAnimation:(WXAnimationInfo *)info
Expand Down