diff --git a/Libraries/Animation/AnimationExperimental.js b/Libraries/Animation/AnimationExperimental.js deleted file mode 100644 index e871c6a0d..000000000 --- a/Libraries/Animation/AnimationExperimental.js +++ /dev/null @@ -1,99 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule AnimationExperimental - */ -'use strict'; - -var RCTAnimationManager = require('NativeModules').AnimationExperimentalManager; -if (!RCTAnimationManager) { - // AnimationExperimental isn't available internally - this is a temporary - // workaround to enable its availability to be determined at runtime. - // For Flow let's pretend like we always export AnimationExperimental - // so all our users don't need to do null checks - module.exports = null; -} else { - -var React = require('React'); -var AnimationUtils = require('AnimationUtils'); - -type EasingFunction = (t: number) => number; - -var Properties = { - opacity: true, - position: true, - positionX: true, - positionY: true, - rotation: true, - scaleXY: true, -}; - -type ValueType = number | Array | {[key: string]: number}; - -/** - * This is an experimental module that is under development, incomplete, - * potentially buggy, not used in any production apps, and will probably change - * in non-backward compatible ways. - * - * Use at your own risk. - */ -var AnimationExperimental = { - startAnimation: function( - anim: { - node: any; - duration: number; - easing: ($Enum | EasingFunction); - property: $Enum; - toValue: ValueType; - fromValue?: ValueType; - delay?: number; - }, - callback?: ?(finished: bool) => void - ): number { - var nodeHandle = React.findNodeHandle(anim.node); - var easingSample = AnimationUtils.evaluateEasingFunction( - anim.duration, - anim.easing - ); - var tag: number = AnimationUtils.allocateTag(); - var props = {}; - props[anim.property] = {to: anim.toValue}; - RCTAnimationManager.startAnimation( - nodeHandle, - tag, - anim.duration, - anim.delay, - easingSample, - props, - callback - ); - return tag; - }, - - stopAnimation: function(tag: number) { - RCTAnimationManager.stopAnimation(tag); - }, -}; - -if (__DEV__) { - if (RCTAnimationManager && RCTAnimationManager.Properties) { - var a = Object.keys(Properties); - var b = RCTAnimationManager.Properties; - var diff = a.filter((i) => b.indexOf(i) < 0).concat( - b.filter((i) => a.indexOf(i) < 0) - ); - if (diff.length > 0) { - throw new Error('JS animation properties don\'t match native properties.' + - JSON.stringify(diff, null, ' ')); - } - } -} - -module.exports = AnimationExperimental; - -} diff --git a/Libraries/Animation/AnimationUtils.js b/Libraries/Animation/AnimationUtils.js deleted file mode 100644 index 2ee2d8a70..000000000 --- a/Libraries/Animation/AnimationUtils.js +++ /dev/null @@ -1,244 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * The easing functions come from the the jQuery UI project. - * See http://api.jqueryui.com/easings/ - * Copyright jQuery Foundation and other contributors, https://jquery.org/ - * Copyright (c) 2008 George McGinley Smith - * Copyright (c) 2001 Robert Penner - * - * @providesModule AnimationUtils - * @flow - */ -'use strict'; - -type EasingFunction = (t: number) => number; - -var defaults = { - linear: function(t: number): number { - return t; - }, - easeInQuad: function(t: number): number { - return t * t; - }, - easeOutQuad: function(t: number): number { - return -t * (t - 2); - }, - easeInOutQuad: function(t: number): number { - t = t * 2; - if (t < 1) { - return 0.5 * t * t; - } - return -((t - 1) * (t - 3) - 1) / 2; - }, - easeInCubic: function(t: number): number { - return t * t * t; - }, - easeOutCubic: function(t: number): number { - t -= 1; - return t * t * t + 1; - }, - easeInOutCubic: function(t: number): number { - t *= 2; - if (t < 1) { - return 0.5 * t * t * t; - } - t -= 2; - return (t * t * t + 2) / 2; - }, - easeInQuart: function(t: number): number { - return t * t * t * t; - }, - easeOutQuart: function(t: number): number { - t -= 1; - return -(t * t * t * t - 1); - }, - easeInOutQuart: function(t: number): number { - t *= 2; - if (t < 1) { - return 0.5 * t * t * t * t; - } - t -= 2; - return -(t * t * t * t - 2) / 2; - }, - easeInQuint: function(t: number): number { - return t * t * t * t * t; - }, - easeOutQuint: function(t: number): number { - t -= 1; - return t * t * t * t * t + 1; - }, - easeInOutQuint: function(t: number): number { - t *= 2; - if (t < 1) { - return (t * t * t * t * t) / 2; - } - t -= 2; - return (t * t * t * t * t + 2) / 2; - }, - easeInSine: function(t: number): number { - return -Math.cos(t * (Math.PI / 2)) + 1; - }, - easeOutSine: function(t: number): number { - return Math.sin(t * (Math.PI / 2)); - }, - easeInOutSine: function(t: number): number { - return -(Math.cos(Math.PI * t) - 1) / 2; - }, - easeInExpo: function(t: number): number { - return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)); - }, - easeOutExpo: function(t: number): number { - return (t === 1) ? 1 : (-Math.pow(2, -10 * t) + 1); - }, - easeInOutExpo: function(t: number): number { - if (t === 0) { - return 0; - } - if (t === 1) { - return 1; - } - t *= 2; - if (t < 1) { - return 0.5 * Math.pow(2, 10 * (t - 1)); - } - return (-Math.pow(2, -10 * (t - 1)) + 2) / 2; - }, - easeInCirc: function(t: number): number { - return -(Math.sqrt(1 - t * t) - 1); - }, - easeOutCirc: function(t: number): number { - t -= 1; - return Math.sqrt(1 - t * t); - }, - easeInOutCirc: function(t: number): number { - t *= 2; - if (t < 1) { - return -(Math.sqrt(1 - t * t) - 1) / 2; - } - t -= 2; - return (Math.sqrt(1 - t * t) + 1) / 2; - }, - easeInElastic: function(t: number): number { - var s = 1.70158; - var p = 0.3; - if (t === 0) { - return 0; - } - if (t === 1) { - return 1; - } - var s = p / (2 * Math.PI) * Math.asin(1); - t -= 1; - return -(Math.pow(2, 10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p)); - }, - easeOutElastic: function(t: number): number { - var s = 1.70158; - var p = 0.3; - if (t === 0) { - return 0; - } - if (t === 1) { - return 1; - } - var s = p / (2 * Math.PI) * Math.asin(1); - return Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1; - }, - easeInOutElastic: function(t: number): number { - var s = 1.70158; - var p = 0.3 * 1.5; - if (t === 0) { - return 0; - } - t *= 2; - if (t === 2) { - return 1; - } - var s = p / (2 * Math.PI) * Math.asin(1); - if (t < 1) { - t -= 1; - return -(Math.pow(2, 10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p)) / 2; - } - t -= 1; - return Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) / 2 + 1; - }, - easeInBack: function(t: number): number { - var s = 1.70158; - return t * t * ((s + 1) * t - s); - }, - easeOutBack: function(t: number): number { - var s = 1.70158; - t -= 1; - return (t * t * ((s + 1) * t + s) + 1); - }, - easeInOutBack: function(t: number): number { - var s = 1.70158 * 1.525; - t *= 2; - if (t < 1) { - return (t * t * ((s + 1) * t - s)) / 2; - } - t -= 2; - return (t * t * ((s + 1) * t + s) + 2) / 2; - }, - easeInBounce: function(t: number): number { - return 1 - this.easeOutBounce(1 - t); - }, - easeOutBounce: function(t: number): number { - if (t < (1 / 2.75)) { - return 7.5625 * t * t; - } else if (t < (2 / 2.75)) { - t -= 1.5 / 2.75; - return 7.5625 * t * t + 0.75; - } else if (t < (2.5 / 2.75)) { - t -= 2.25 / 2.75; - return 7.5625 * t * t + 0.9375; - } else { - t -= 2.625 / 2.75; - return 7.5625 * t * t + 0.984375; - } - }, - easeInOutBounce: function(t: number): number { - if (t < 0.5) { - return this.easeInBounce(t * 2) / 2; - } - return this.easeOutBounce(t * 2 - 1) / 2 + 0.5; - }, -}; - -var ticksPerSecond = 60; -var lastUsedTag = 0; - -module.exports = { - /** - * Returns a new unique animation tag. - */ - allocateTag: function(): number { - return ++lastUsedTag; - }, - - /** - * Returns the values of the easing function at discrete ticks (60 per second). - */ - evaluateEasingFunction: function(duration: number, easing: string | EasingFunction): Array { - if (typeof easing === 'string') { - easing = defaults[easing] || defaults.easeOutQuad; - } - - var tickCount = Math.round(duration * ticksPerSecond / 1000); - var samples = []; - if (tickCount > 0) { - for (var i = 0; i <= tickCount; i++) { - samples.push(easing.call(defaults, i / tickCount)); - } - } - - return samples; - }, - - Defaults: defaults, -}; diff --git a/Libraries/Animation/RCTAnimationExperimental.xcodeproj/project.pbxproj b/Libraries/Animation/RCTAnimationExperimental.xcodeproj/project.pbxproj deleted file mode 100644 index 038ec7252..000000000 --- a/Libraries/Animation/RCTAnimationExperimental.xcodeproj/project.pbxproj +++ /dev/null @@ -1,250 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 13BE3DEE1AC21097009241FE /* RCTAnimationExperimentalManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BE3DED1AC21097009241FE /* RCTAnimationExperimentalManager.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 58B511D91A9E6C8500147676 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "include/$(PRODUCT_NAME)"; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 134814201AA4EA6300B7C361 /* libRCTAnimationExperimental.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTAnimationExperimental.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 13BE3DEC1AC21097009241FE /* RCTAnimationExperimentalManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAnimationExperimentalManager.h; sourceTree = ""; }; - 13BE3DED1AC21097009241FE /* RCTAnimationExperimentalManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAnimationExperimentalManager.m; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 58B511D81A9E6C8500147676 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 134814211AA4EA7D00B7C361 /* Products */ = { - isa = PBXGroup; - children = ( - 134814201AA4EA6300B7C361 /* libRCTAnimationExperimental.a */, - ); - name = Products; - sourceTree = ""; - }; - 58B511D21A9E6C8500147676 = { - isa = PBXGroup; - children = ( - 13BE3DEC1AC21097009241FE /* RCTAnimationExperimentalManager.h */, - 13BE3DED1AC21097009241FE /* RCTAnimationExperimentalManager.m */, - 134814211AA4EA7D00B7C361 /* Products */, - ); - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 58B511DA1A9E6C8500147676 /* RCTAnimationExperimental */ = { - isa = PBXNativeTarget; - buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTAnimationExperimental" */; - buildPhases = ( - 58B511D71A9E6C8500147676 /* Sources */, - 58B511D81A9E6C8500147676 /* Frameworks */, - 58B511D91A9E6C8500147676 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = RCTAnimationExperimental; - productName = RCTDataManager; - productReference = 134814201AA4EA6300B7C361 /* libRCTAnimationExperimental.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 58B511D31A9E6C8500147676 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0610; - ORGANIZATIONNAME = Facebook; - TargetAttributes = { - 58B511DA1A9E6C8500147676 = { - CreatedOnToolsVersion = 6.1.1; - }; - }; - }; - buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTAnimationExperimental" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = 58B511D21A9E6C8500147676; - productRefGroup = 58B511D21A9E6C8500147676; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 58B511DA1A9E6C8500147676 /* RCTAnimationExperimental */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 58B511D71A9E6C8500147676 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 13BE3DEE1AC21097009241FE /* RCTAnimationExperimentalManager.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 58B511ED1A9E6C8500147676 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 58B511EE1A9E6C8500147676 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = YES; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 58B511F01A9E6C8500147676 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "$(SRCROOT)/../../React/**", - ); - LIBRARY_SEARCH_PATHS = "$(inherited)"; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = RCTAnimationExperimental; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 58B511F11A9E6C8500147676 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - HEADER_SEARCH_PATHS = ( - "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, - "$(SRCROOT)/../../React/**", - ); - LIBRARY_SEARCH_PATHS = "$(inherited)"; - OTHER_LDFLAGS = "-ObjC"; - PRODUCT_NAME = RCTAnimationExperimental; - SKIP_INSTALL = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTAnimationExperimental" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 58B511ED1A9E6C8500147676 /* Debug */, - 58B511EE1A9E6C8500147676 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTAnimationExperimental" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 58B511F01A9E6C8500147676 /* Debug */, - 58B511F11A9E6C8500147676 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 58B511D31A9E6C8500147676 /* Project object */; -} diff --git a/Libraries/Animation/RCTAnimationExperimentalManager.h b/Libraries/Animation/RCTAnimationExperimentalManager.h deleted file mode 100644 index 0affc5233..000000000 --- a/Libraries/Animation/RCTAnimationExperimentalManager.h +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import -#import - -#import "RCTBridgeModule.h" - -@interface RCTAnimationExperimentalManager : NSObject - -@end diff --git a/Libraries/Animation/RCTAnimationExperimentalManager.m b/Libraries/Animation/RCTAnimationExperimentalManager.m deleted file mode 100644 index cff4ece15..000000000 --- a/Libraries/Animation/RCTAnimationExperimentalManager.m +++ /dev/null @@ -1,299 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -#import "RCTAnimationExperimentalManager.h" - -#import - -#import "RCTSparseArray.h" -#import "RCTUIManager.h" -#import "RCTUtils.h" - -#if CGFLOAT_IS_DOUBLE - #define CG_APPEND(PREFIX, SUFFIX_F, SUFFIX_D) PREFIX##SUFFIX_D -#else - #define CG_APPEND(PREFIX, SUFFIX_F, SUFFIX_D) PREFIX##SUFFIX_F -#endif - -@implementation RCTAnimationExperimentalManager -{ - RCTSparseArray *_animationRegistry; // Main thread only; animation tag -> view tag - RCTSparseArray *_callbackRegistry; // Main thread only; animation tag -> callback - NSDictionary *_keypathMapping; -} - -RCT_EXPORT_MODULE() - -@synthesize bridge = _bridge; - -- (instancetype)init -{ - if ((self = [super init])) { - _animationRegistry = [[RCTSparseArray alloc] init]; - _callbackRegistry = [[RCTSparseArray alloc] init]; - _keypathMapping = @{ - @"opacity": @{ - @"keypath": @"opacity", - @"type": @"NSNumber", - }, - @"position": @{ - @"keypath": @"position", - @"type": @"CGPoint", - }, - @"positionX": @{ - @"keypath": @"position.x", - @"type": @"NSNumber", - }, - @"positionY": @{ - @"keypath": @"position.y", - @"type": @"NSNumber", - }, - @"rotation": @{ - @"keypath": @"transform.rotation.z", - @"type": @"NSNumber", - }, - @"scaleXY": @{ - @"keypath": @"transform.scale", - @"type": @"CGPoint", - }, - }; - } - - return self; -} - -- (dispatch_queue_t)methodQueue -{ - return _bridge.uiManager.methodQueue; -} - -- (id (^)(CGFloat))interpolateFrom:(CGFloat[])fromArray to:(CGFloat[])toArray count:(NSUInteger)count typeName:(const char *)typeName -{ - if (count == 1) { - CGFloat from = *fromArray, to = *toArray, delta = to - from; - return ^(CGFloat t) { - return @(from + t * delta); - }; - } - - CG_APPEND(vDSP_vsub,,D)(fromArray, 1, toArray, 1, toArray, 1, count); - - const size_t size = count * sizeof(CGFloat); - NSData *deltaData = [NSData dataWithBytes:toArray length:size]; - NSData *fromData = [NSData dataWithBytes:fromArray length:size]; - - return ^(CGFloat t) { - const CGFloat *delta = deltaData.bytes; - const CGFloat *_fromArray = fromData.bytes; - - CGFloat value[count]; - CG_APPEND(vDSP_vma,,D)(delta, 1, &t, 0, _fromArray, 1, value, 1, count); - return [NSValue valueWithBytes:value objCType:typeName]; - }; -} - -static void RCTInvalidAnimationProp(RCTSparseArray *callbacks, NSNumber *tag, NSString *key, id value) -{ - RCTResponseSenderBlock callback = callbacks[tag]; - RCTLogError(@"Invalid animation property `%@ = %@`", key, value); - if (callback) { - callback(@[@NO]); - callbacks[tag] = nil; - } - [CATransaction commit]; - return; -} - -RCT_EXPORT_METHOD(startAnimation:(NSNumber *)reactTag - animationTag:(NSNumber *)animationTag - duration:(NSTimeInterval)duration - delay:(NSTimeInterval)delay - easingSample:(NSNumberArray *)easingSample - properties:(NSDictionary *)properties - callback:(RCTResponseSenderBlock)callback) -{ - __weak RCTAnimationExperimentalManager *weakSelf = self; - [_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) { - RCTAnimationExperimentalManager *strongSelf = weakSelf; - - UIView *view = viewRegistry[reactTag]; - if (!view) { - RCTLogWarn(@"React tag #%@ is not registered with the view registry", reactTag); - return; - } - __block BOOL completionBlockSet = NO; - [CATransaction begin]; - for (NSString *prop in properties) { - NSString *keypath = _keypathMapping[prop][@"keypath"]; - id obj = properties[prop][@"to"]; - if (!keypath) { - return RCTInvalidAnimationProp(strongSelf->_callbackRegistry, animationTag, keypath, obj); - } - NSValue *toValue = nil; - if ([keypath isEqualToString:@"transform.scale"]) { - CGPoint point = [RCTConvert CGPoint:obj]; - if (point.x != point.y) { - return RCTInvalidAnimationProp(strongSelf->_callbackRegistry, animationTag, keypath, obj); - } - toValue = @(point.x); - } else if ([obj respondsToSelector:@selector(count)]) { - switch ([obj count]) { - case 2: - if (![obj respondsToSelector:@selector(objectForKeyedSubscript:)] || obj[@"x"]) { - toValue = [NSValue valueWithCGPoint:[RCTConvert CGPoint:obj]]; - } else { - toValue = [NSValue valueWithCGSize:[RCTConvert CGSize:obj]]; - } - break; - case 4: - toValue = [NSValue valueWithCGRect:[RCTConvert CGRect:obj]]; - break; - case 16: - toValue = [NSValue valueWithCGAffineTransform:[RCTConvert CGAffineTransform:obj]]; - break; - default: - return RCTInvalidAnimationProp(strongSelf->_callbackRegistry, animationTag, keypath, obj); - } - } else if (![obj respondsToSelector:@selector(objCType)]) { - return RCTInvalidAnimationProp(strongSelf->_callbackRegistry, animationTag, keypath, obj); - } - if (!toValue) { - toValue = obj; - } - const char *typeName = toValue.objCType; - - size_t count; - switch (typeName[0]) { - case 'i': - case 'I': - case 's': - case 'S': - case 'l': - case 'L': - case 'q': - case 'Q': - count = 1; - break; - - default: { - NSUInteger size; - NSGetSizeAndAlignment(typeName, &size, NULL); - count = size / sizeof(CGFloat); - break; - } - } - - CGFloat toFields[count]; - - switch (typeName[0]) { -#define CASE(encoding, type) \ - case encoding: { \ - type value; \ - [toValue getValue:&value]; \ - toFields[0] = value; \ - break; \ - } - - CASE('i', int) - CASE('I', unsigned int) - CASE('s', short) - CASE('S', unsigned short) - CASE('l', long) - CASE('L', unsigned long) - CASE('q', long long) - CASE('Q', unsigned long long) - -#undef CASE - - default: - [toValue getValue:toFields]; - break; - } - - NSValue *fromValue = [view.layer.presentationLayer valueForKeyPath:keypath]; -#if !CGFLOAT_IS_DOUBLE - if ([fromValue isKindOfClass:[NSNumber class]]) { - fromValue = [NSNumber numberWithFloat:[(NSNumber *)fromValue doubleValue]]; - } -#endif - CGFloat fromFields[count]; - [fromValue getValue:fromFields]; - - id (^interpolationBlock)(CGFloat t) = [strongSelf interpolateFrom:fromFields to:toFields count:count typeName:typeName]; - - NSMutableArray *sampledValues = [NSMutableArray arrayWithCapacity:easingSample.count]; - for (NSNumber *sample in easingSample) { - CGFloat t = sample.CG_APPEND(, floatValue, doubleValue); - [sampledValues addObject:interpolationBlock(t)]; - } - CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:keypath]; - animation.beginTime = CACurrentMediaTime() + delay; - animation.duration = duration; - animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; - animation.values = sampledValues; - @try { - [view.layer setValue:toValue forKey:keypath]; - NSString *animationKey = [@"RCT" stringByAppendingString:RCTJSONStringify(@{@"tag": animationTag, @"key": keypath}, nil)]; - if (!completionBlockSet) { - strongSelf->_callbackRegistry[animationTag] = callback; - [CATransaction setCompletionBlock:^{ - RCTResponseSenderBlock cb = strongSelf->_callbackRegistry[animationTag]; - if (cb) { - cb(@[@YES]); - strongSelf->_callbackRegistry[animationTag] = nil; - } - }]; - completionBlockSet = YES; - } - [view.layer addAnimation:animation forKey:animationKey]; - } - @catch (NSException *exception) { - return RCTInvalidAnimationProp(strongSelf->_callbackRegistry, animationTag, keypath, toValue); - } - } - [CATransaction commit]; - strongSelf->_animationRegistry[animationTag] = reactTag; - }]; -} - -RCT_EXPORT_METHOD(stopAnimation:(NSNumber *)animationTag) -{ - __weak RCTAnimationExperimentalManager *weakSelf = self; - [_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) { - RCTAnimationExperimentalManager *strongSelf = weakSelf; - - NSNumber *reactTag = strongSelf->_animationRegistry[animationTag]; - if (!reactTag) { - return; - } - - UIView *view = viewRegistry[reactTag]; - for (NSString *animationKey in view.layer.animationKeys) { - if ([animationKey hasPrefix:@"RCT{"]) { - NSDictionary *data = RCTJSONParse([animationKey substringFromIndex:3], nil); - if (animationTag.integerValue == [data[@"tag"] integerValue]) { - [view.layer removeAnimationForKey:animationKey]; - } - } - } - RCTResponseSenderBlock cb = strongSelf->_callbackRegistry[animationTag]; - if (cb) { - cb(@[@NO]); - strongSelf->_callbackRegistry[animationTag] = nil; - } - strongSelf->_animationRegistry[animationTag] = nil; - }]; -} - -- (NSDictionary *)constantsToExport -{ - return @{@"Properties": [_keypathMapping allKeys] }; -} - -@end