mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-04-28 20:34:52 +08:00
[change] update Animated implementation
Mirror contents of React Native 0.55.4
This commit is contained in:
@@ -16,13 +16,17 @@ import invariant from 'fbjs/lib/invariant';
|
||||
|
||||
const { shouldUseNativeDriver } = NativeAnimatedHelper;
|
||||
|
||||
export type Mapping = { [key: string]: Mapping } | AnimatedValue;
|
||||
export type Mapping = {[key: string]: Mapping} | AnimatedValue;
|
||||
export type EventConfig = {
|
||||
listener?: ?Function,
|
||||
useNativeDriver?: boolean
|
||||
useNativeDriver?: boolean,
|
||||
};
|
||||
|
||||
function attachNativeEvent(viewRef: any, eventName: string, argMapping: Array<?Mapping>) {
|
||||
function attachNativeEvent(
|
||||
viewRef: any,
|
||||
eventName: string,
|
||||
argMapping: Array<?Mapping>,
|
||||
) {
|
||||
// Find animated values in `argMapping` and create an array representing their
|
||||
// key path inside the `nativeEvent` object. Ex.: ['contentOffset', 'x'].
|
||||
const eventMappings = [];
|
||||
@@ -33,7 +37,7 @@ function attachNativeEvent(viewRef: any, eventName: string, argMapping: Array<?M
|
||||
|
||||
eventMappings.push({
|
||||
nativeEventPath: path,
|
||||
animatedValueTag: value.__getNativeTag()
|
||||
animatedValueTag: value.__getNativeTag(),
|
||||
});
|
||||
} else if (typeof value === 'object') {
|
||||
for (const key in value) {
|
||||
@@ -44,7 +48,7 @@ function attachNativeEvent(viewRef: any, eventName: string, argMapping: Array<?M
|
||||
|
||||
invariant(
|
||||
argMapping[0] && argMapping[0].nativeEvent,
|
||||
'Native driven events only support animated values contained inside `nativeEvent`.'
|
||||
'Native driven events only support animated values contained inside `nativeEvent`.',
|
||||
);
|
||||
|
||||
// Assume that the event containing `nativeEvent` is always the first argument.
|
||||
@@ -53,7 +57,11 @@ function attachNativeEvent(viewRef: any, eventName: string, argMapping: Array<?M
|
||||
const viewTag = findNodeHandle(viewRef);
|
||||
|
||||
eventMappings.forEach(mapping => {
|
||||
NativeAnimatedHelper.API.addAnimatedEventToView(viewTag, eventName, mapping);
|
||||
NativeAnimatedHelper.API.addAnimatedEventToView(
|
||||
viewTag,
|
||||
eventName,
|
||||
mapping,
|
||||
);
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -62,10 +70,10 @@ function attachNativeEvent(viewRef: any, eventName: string, argMapping: Array<?M
|
||||
NativeAnimatedHelper.API.removeAnimatedEventFromView(
|
||||
viewTag,
|
||||
eventName,
|
||||
mapping.animatedValueTag
|
||||
mapping.animatedValueTag,
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -74,7 +82,7 @@ class AnimatedEvent {
|
||||
_listeners: Array<Function> = [];
|
||||
_callListeners: Function;
|
||||
_attachedEvent: ?{
|
||||
detach: () => void
|
||||
detach: () => void,
|
||||
};
|
||||
__isNative: boolean;
|
||||
|
||||
@@ -101,13 +109,23 @@ class AnimatedEvent {
|
||||
}
|
||||
|
||||
__attach(viewRef: any, eventName: string) {
|
||||
invariant(this.__isNative, 'Only native driven events need to be attached.');
|
||||
invariant(
|
||||
this.__isNative,
|
||||
'Only native driven events need to be attached.',
|
||||
);
|
||||
|
||||
this._attachedEvent = attachNativeEvent(viewRef, eventName, this._argMapping);
|
||||
this._attachedEvent = attachNativeEvent(
|
||||
viewRef,
|
||||
eventName,
|
||||
this._argMapping,
|
||||
);
|
||||
}
|
||||
|
||||
__detach(viewTag: any, eventName: string) {
|
||||
invariant(this.__isNative, 'Only native driven events need to be detached.');
|
||||
invariant(
|
||||
this.__isNative,
|
||||
'Only native driven events need to be detached.',
|
||||
);
|
||||
|
||||
this._attachedEvent && this._attachedEvent.detach();
|
||||
}
|
||||
@@ -153,17 +171,17 @@ class AnimatedEvent {
|
||||
typeof recMapping +
|
||||
' for key ' +
|
||||
key +
|
||||
', event value must map to AnimatedValue'
|
||||
', event value must map to AnimatedValue',
|
||||
);
|
||||
return;
|
||||
}
|
||||
invariant(
|
||||
typeof recMapping === 'object',
|
||||
'Bad mapping of type ' + typeof recMapping + ' for key ' + key
|
||||
'Bad mapping of type ' + typeof recMapping + ' for key ' + key,
|
||||
);
|
||||
invariant(
|
||||
typeof recEvt === 'object',
|
||||
'Bad event of type ' + typeof recEvt + ' for key ' + key
|
||||
'Bad event of type ' + typeof recEvt + ' for key ' + key,
|
||||
);
|
||||
for (const mappingKey in recMapping) {
|
||||
traverse(recMapping[mappingKey], recEvt[mappingKey], mappingKey);
|
||||
|
||||
@@ -34,25 +34,31 @@ import type { DecayAnimationConfig } from './animations/DecayAnimation';
|
||||
import type { SpringAnimationConfig } from './animations/SpringAnimation';
|
||||
import type { Mapping, EventConfig } from './AnimatedEvent';
|
||||
|
||||
type CompositeAnimation = {
|
||||
export type CompositeAnimation = {
|
||||
start: (callback?: ?EndCallback) => void,
|
||||
stop: () => void,
|
||||
reset: () => void,
|
||||
_startNativeLoop: (iterations?: number) => void,
|
||||
_isUsingNativeDriver: () => boolean
|
||||
_isUsingNativeDriver: () => boolean,
|
||||
};
|
||||
|
||||
const add = function(a: AnimatedNode | number, b: AnimatedNode | number): AnimatedAddition {
|
||||
const add = function(
|
||||
a: AnimatedNode | number,
|
||||
b: AnimatedNode | number,
|
||||
): AnimatedAddition {
|
||||
return new AnimatedAddition(a, b);
|
||||
};
|
||||
|
||||
const divide = function(a: AnimatedNode | number, b: AnimatedNode | number): AnimatedDivision {
|
||||
const divide = function(
|
||||
a: AnimatedNode | number,
|
||||
b: AnimatedNode | number,
|
||||
): AnimatedDivision {
|
||||
return new AnimatedDivision(a, b);
|
||||
};
|
||||
|
||||
const multiply = function(
|
||||
a: AnimatedNode | number,
|
||||
b: AnimatedNode | number
|
||||
b: AnimatedNode | number,
|
||||
): AnimatedMultiplication {
|
||||
return new AnimatedMultiplication(a, b);
|
||||
};
|
||||
@@ -61,11 +67,18 @@ const modulo = function(a: AnimatedNode, modulus: number): AnimatedModulo {
|
||||
return new AnimatedModulo(a, modulus);
|
||||
};
|
||||
|
||||
const diffClamp = function(a: AnimatedNode, min: number, max: number): AnimatedDiffClamp {
|
||||
const diffClamp = function(
|
||||
a: AnimatedNode,
|
||||
min: number,
|
||||
max: number,
|
||||
): AnimatedDiffClamp {
|
||||
return new AnimatedDiffClamp(a, min, max);
|
||||
};
|
||||
|
||||
const _combineCallbacks = function(callback: ?EndCallback, config: AnimationConfig) {
|
||||
const _combineCallbacks = function(
|
||||
callback: ?EndCallback,
|
||||
config: AnimationConfig,
|
||||
) {
|
||||
if (callback && config.onComplete) {
|
||||
return (...args) => {
|
||||
config.onComplete && config.onComplete(...args);
|
||||
@@ -79,13 +92,13 @@ const _combineCallbacks = function(callback: ?EndCallback, config: AnimationConf
|
||||
const maybeVectorAnim = function(
|
||||
value: AnimatedValue | AnimatedValueXY,
|
||||
config: Object,
|
||||
anim: (value: AnimatedValue, config: Object) => CompositeAnimation
|
||||
anim: (value: AnimatedValue, config: Object) => CompositeAnimation,
|
||||
): ?CompositeAnimation {
|
||||
if (value instanceof AnimatedValueXY) {
|
||||
const configX = { ...config };
|
||||
const configY = { ...config };
|
||||
const configX = {...config};
|
||||
const configY = {...config};
|
||||
for (const key in config) {
|
||||
const { x, y } = config[key];
|
||||
const {x, y} = config[key];
|
||||
if (x !== undefined && y !== undefined) {
|
||||
configX[key] = x;
|
||||
configY[key] = y;
|
||||
@@ -95,19 +108,19 @@ const maybeVectorAnim = function(
|
||||
const aY = anim((value: AnimatedValueXY).y, configY);
|
||||
// We use `stopTogether: false` here because otherwise tracking will break
|
||||
// because the second animation will get stopped before it can update.
|
||||
return parallel([aX, aY], { stopTogether: false });
|
||||
return parallel([aX, aY], {stopTogether: false});
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const spring = function(
|
||||
value: AnimatedValue | AnimatedValueXY,
|
||||
config: SpringAnimationConfig
|
||||
config: SpringAnimationConfig,
|
||||
): CompositeAnimation {
|
||||
const start = function(
|
||||
animatedValue: AnimatedValue | AnimatedValueXY,
|
||||
configuration: SpringAnimationConfig,
|
||||
callback?: ?EndCallback
|
||||
callback?: ?EndCallback,
|
||||
): void {
|
||||
callback = _combineCallbacks(callback, configuration);
|
||||
const singleValue: any = animatedValue;
|
||||
@@ -120,8 +133,8 @@ const spring = function(
|
||||
configuration.toValue,
|
||||
SpringAnimation,
|
||||
singleConfig,
|
||||
callback
|
||||
)
|
||||
callback,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
singleValue.animate(new SpringAnimation(singleConfig), callback);
|
||||
@@ -142,25 +155,25 @@ const spring = function(
|
||||
},
|
||||
|
||||
_startNativeLoop: function(iterations?: number): void {
|
||||
const singleConfig = { ...config, iterations };
|
||||
const singleConfig = {...config, iterations};
|
||||
start(value, singleConfig);
|
||||
},
|
||||
|
||||
_isUsingNativeDriver: function(): boolean {
|
||||
return config.useNativeDriver || false;
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const timing = function(
|
||||
value: AnimatedValue | AnimatedValueXY,
|
||||
config: TimingAnimationConfig
|
||||
config: TimingAnimationConfig,
|
||||
): CompositeAnimation {
|
||||
const start = function(
|
||||
animatedValue: AnimatedValue | AnimatedValueXY,
|
||||
configuration: TimingAnimationConfig,
|
||||
callback?: ?EndCallback
|
||||
callback?: ?EndCallback,
|
||||
): void {
|
||||
callback = _combineCallbacks(callback, configuration);
|
||||
const singleValue: any = animatedValue;
|
||||
@@ -173,8 +186,8 @@ const timing = function(
|
||||
configuration.toValue,
|
||||
TimingAnimation,
|
||||
singleConfig,
|
||||
callback
|
||||
)
|
||||
callback,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
singleValue.animate(new TimingAnimation(singleConfig), callback);
|
||||
@@ -196,25 +209,25 @@ const timing = function(
|
||||
},
|
||||
|
||||
_startNativeLoop: function(iterations?: number): void {
|
||||
const singleConfig = { ...config, iterations };
|
||||
const singleConfig = {...config, iterations};
|
||||
start(value, singleConfig);
|
||||
},
|
||||
|
||||
_isUsingNativeDriver: function(): boolean {
|
||||
return config.useNativeDriver || false;
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const decay = function(
|
||||
value: AnimatedValue | AnimatedValueXY,
|
||||
config: DecayAnimationConfig
|
||||
config: DecayAnimationConfig,
|
||||
): CompositeAnimation {
|
||||
const start = function(
|
||||
animatedValue: AnimatedValue | AnimatedValueXY,
|
||||
configuration: DecayAnimationConfig,
|
||||
callback?: ?EndCallback
|
||||
callback?: ?EndCallback,
|
||||
): void {
|
||||
callback = _combineCallbacks(callback, configuration);
|
||||
const singleValue: any = animatedValue;
|
||||
@@ -238,18 +251,20 @@ const decay = function(
|
||||
},
|
||||
|
||||
_startNativeLoop: function(iterations?: number): void {
|
||||
const singleConfig = { ...config, iterations };
|
||||
const singleConfig = {...config, iterations};
|
||||
start(value, singleConfig);
|
||||
},
|
||||
|
||||
_isUsingNativeDriver: function(): boolean {
|
||||
return config.useNativeDriver || false;
|
||||
}
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const sequence = function(animations: Array<CompositeAnimation>): CompositeAnimation {
|
||||
const sequence = function(
|
||||
animations: Array<CompositeAnimation>,
|
||||
): CompositeAnimation {
|
||||
let current = 0;
|
||||
return {
|
||||
start: function(callback?: ?EndCallback) {
|
||||
@@ -270,7 +285,7 @@ const sequence = function(animations: Array<CompositeAnimation>): CompositeAnima
|
||||
};
|
||||
|
||||
if (animations.length === 0) {
|
||||
callback && callback({ finished: true });
|
||||
callback && callback({finished: true});
|
||||
} else {
|
||||
animations[current].start(onComplete);
|
||||
}
|
||||
@@ -293,22 +308,22 @@ const sequence = function(animations: Array<CompositeAnimation>): CompositeAnima
|
||||
|
||||
_startNativeLoop: function() {
|
||||
throw new Error(
|
||||
'Loops run using the native driver cannot contain Animated.sequence animations'
|
||||
'Loops run using the native driver cannot contain Animated.sequence animations',
|
||||
);
|
||||
},
|
||||
|
||||
_isUsingNativeDriver: function(): boolean {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
type ParallelConfig = {
|
||||
stopTogether?: boolean // If one is stopped, stop all. default: true
|
||||
stopTogether?: boolean, // If one is stopped, stop all. default: true
|
||||
};
|
||||
const parallel = function(
|
||||
animations: Array<CompositeAnimation>,
|
||||
config?: ?ParallelConfig
|
||||
config?: ?ParallelConfig,
|
||||
): CompositeAnimation {
|
||||
let doneCount = 0;
|
||||
// Make sure we only call stop() at most once for each animation
|
||||
@@ -318,7 +333,7 @@ const parallel = function(
|
||||
const result = {
|
||||
start: function(callback?: ?EndCallback) {
|
||||
if (doneCount === animations.length) {
|
||||
callback && callback({ finished: true });
|
||||
callback && callback({finished: true});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -338,7 +353,7 @@ const parallel = function(
|
||||
};
|
||||
|
||||
if (!animation) {
|
||||
cb({ finished: true });
|
||||
cb({finished: true});
|
||||
} else {
|
||||
animation.start(cb);
|
||||
}
|
||||
@@ -362,13 +377,13 @@ const parallel = function(
|
||||
|
||||
_startNativeLoop: function() {
|
||||
throw new Error(
|
||||
'Loops run using the native driver cannot contain Animated.parallel animations'
|
||||
'Loops run using the native driver cannot contain Animated.parallel animations',
|
||||
);
|
||||
},
|
||||
|
||||
_isUsingNativeDriver: function(): boolean {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
return result;
|
||||
@@ -376,29 +391,36 @@ const parallel = function(
|
||||
|
||||
const delay = function(time: number): CompositeAnimation {
|
||||
// Would be nice to make a specialized implementation
|
||||
return timing(new AnimatedValue(0), { toValue: 0, delay: time, duration: 0 });
|
||||
return timing(new AnimatedValue(0), {toValue: 0, delay: time, duration: 0});
|
||||
};
|
||||
|
||||
const stagger = function(time: number, animations: Array<CompositeAnimation>): CompositeAnimation {
|
||||
const stagger = function(
|
||||
time: number,
|
||||
animations: Array<CompositeAnimation>,
|
||||
): CompositeAnimation {
|
||||
return parallel(
|
||||
animations.map((animation, i) => {
|
||||
return sequence([delay(time * i), animation]);
|
||||
})
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
type LoopAnimationConfig = { iterations: number };
|
||||
type LoopAnimationConfig = {iterations: number};
|
||||
|
||||
const loop = function(
|
||||
animation: CompositeAnimation,
|
||||
{ iterations = -1 }: LoopAnimationConfig = {}
|
||||
{iterations = -1}: LoopAnimationConfig = {},
|
||||
): CompositeAnimation {
|
||||
let isFinished = false;
|
||||
let iterationsSoFar = 0;
|
||||
return {
|
||||
start: function(callback?: ?EndCallback) {
|
||||
const restart = function(result: EndResult = { finished: true }): void {
|
||||
if (isFinished || iterationsSoFar === iterations || result.finished === false) {
|
||||
const restart = function(result: EndResult = {finished: true}): void {
|
||||
if (
|
||||
isFinished ||
|
||||
iterationsSoFar === iterations ||
|
||||
result.finished === false
|
||||
) {
|
||||
callback && callback(result);
|
||||
} else {
|
||||
iterationsSoFar++;
|
||||
@@ -407,7 +429,7 @@ const loop = function(
|
||||
}
|
||||
};
|
||||
if (!animation || iterations === 0) {
|
||||
callback && callback({ finished: true });
|
||||
callback && callback({finished: true});
|
||||
} else {
|
||||
if (animation._isUsingNativeDriver()) {
|
||||
animation._startNativeLoop(iterations);
|
||||
@@ -429,18 +451,20 @@ const loop = function(
|
||||
},
|
||||
|
||||
_startNativeLoop: function() {
|
||||
throw new Error('Loops run using the native driver cannot contain Animated.loop animations');
|
||||
throw new Error(
|
||||
'Loops run using the native driver cannot contain Animated.loop animations',
|
||||
);
|
||||
},
|
||||
|
||||
_isUsingNativeDriver: function(): boolean {
|
||||
return animation._isUsingNativeDriver();
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
function forkEvent(
|
||||
event: ?AnimatedEvent | ?Function,
|
||||
listener: Function
|
||||
listener: Function,
|
||||
): AnimatedEvent | Function {
|
||||
if (!event) {
|
||||
return listener;
|
||||
@@ -455,7 +479,10 @@ function forkEvent(
|
||||
}
|
||||
}
|
||||
|
||||
function unforkEvent(event: ?AnimatedEvent | ?Function, listener: Function): void {
|
||||
function unforkEvent(
|
||||
event: ?AnimatedEvent | ?Function,
|
||||
listener: Function,
|
||||
): void {
|
||||
if (event && event instanceof AnimatedEvent) {
|
||||
event.__removeListener(listener);
|
||||
}
|
||||
@@ -638,7 +665,7 @@ const AnimatedImplementation = {
|
||||
forkEvent,
|
||||
unforkEvent,
|
||||
|
||||
__PropsOnlyForTests: AnimatedProps
|
||||
__PropsOnlyForTests: AnimatedProps,
|
||||
};
|
||||
|
||||
export default AnimatedImplementation;
|
||||
export default AnimatedImplementation
|
||||
|
||||
@@ -61,22 +61,14 @@ class Easing {
|
||||
/**
|
||||
* A stepping function, returns 1 for any positive value of `n`.
|
||||
*/
|
||||
/* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
|
||||
* caught by Flow 0.59 which was not caught before. Most likely, this error
|
||||
* is because an exported function parameter is missing an annotation.
|
||||
* Without an annotation, these parameters are uncovered by Flow. */
|
||||
static step0(n) {
|
||||
static step0(n: number) {
|
||||
return n > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* A stepping function, returns 1 if `n` is greater than or equal to 1.
|
||||
*/
|
||||
/* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
|
||||
* caught by Flow 0.59 which was not caught before. Most likely, this error
|
||||
* is because an exported function parameter is missing an annotation.
|
||||
* Without an annotation, these parameters are uncovered by Flow. */
|
||||
static step1(n) {
|
||||
static step1(n: number) {
|
||||
return n >= 1 ? 1 : 0;
|
||||
}
|
||||
|
||||
@@ -86,11 +78,7 @@ class Easing {
|
||||
*
|
||||
* http://cubic-bezier.com/#0,0,1,1
|
||||
*/
|
||||
/* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
|
||||
* caught by Flow 0.59 which was not caught before. Most likely, this error
|
||||
* is because an exported function parameter is missing an annotation.
|
||||
* Without an annotation, these parameters are uncovered by Flow. */
|
||||
static linear(t) {
|
||||
static linear(t: number) {
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -113,11 +101,7 @@ class Easing {
|
||||
*
|
||||
* http://easings.net/#easeInQuad
|
||||
*/
|
||||
/* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
|
||||
* caught by Flow 0.59 which was not caught before. Most likely, this error
|
||||
* is because an exported function parameter is missing an annotation.
|
||||
* Without an annotation, these parameters are uncovered by Flow. */
|
||||
static quad(t) {
|
||||
static quad(t: number) {
|
||||
return t * t;
|
||||
}
|
||||
|
||||
@@ -127,11 +111,7 @@ class Easing {
|
||||
*
|
||||
* http://easings.net/#easeInCubic
|
||||
*/
|
||||
/* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
|
||||
* caught by Flow 0.59 which was not caught before. Most likely, this error
|
||||
* is because an exported function parameter is missing an annotation.
|
||||
* Without an annotation, these parameters are uncovered by Flow. */
|
||||
static cubic(t) {
|
||||
static cubic(t: number) {
|
||||
return t * t * t;
|
||||
}
|
||||
|
||||
@@ -141,17 +121,8 @@ class Easing {
|
||||
* n = 4: http://easings.net/#easeInQuart
|
||||
* n = 5: http://easings.net/#easeInQuint
|
||||
*/
|
||||
/* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
|
||||
* caught by Flow 0.59 which was not caught before. Most likely, this error
|
||||
* is because an exported function parameter is missing an annotation.
|
||||
* Without an annotation, these parameters are uncovered by Flow. */
|
||||
static poly(n) {
|
||||
/* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an
|
||||
* error caught by Flow 0.59 which was not caught before. Most likely, this
|
||||
* error is because an exported function parameter is missing an
|
||||
* annotation. Without an annotation, these parameters are uncovered by
|
||||
* Flow. */
|
||||
return t => Math.pow(t, n);
|
||||
static poly(n: number) {
|
||||
return (t: number) => Math.pow(t, n);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,11 +130,7 @@ class Easing {
|
||||
*
|
||||
* http://easings.net/#easeInSine
|
||||
*/
|
||||
/* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
|
||||
* caught by Flow 0.59 which was not caught before. Most likely, this error
|
||||
* is because an exported function parameter is missing an annotation.
|
||||
* Without an annotation, these parameters are uncovered by Flow. */
|
||||
static sin(t) {
|
||||
static sin(t: number) {
|
||||
return 1 - Math.cos(t * Math.PI / 2);
|
||||
}
|
||||
|
||||
@@ -172,11 +139,7 @@ class Easing {
|
||||
*
|
||||
* http://easings.net/#easeInCirc
|
||||
*/
|
||||
/* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
|
||||
* caught by Flow 0.59 which was not caught before. Most likely, this error
|
||||
* is because an exported function parameter is missing an annotation.
|
||||
* Without an annotation, these parameters are uncovered by Flow. */
|
||||
static circle(t) {
|
||||
static circle(t: number) {
|
||||
return 1 - Math.sqrt(1 - t * t);
|
||||
}
|
||||
|
||||
@@ -185,11 +148,7 @@ class Easing {
|
||||
*
|
||||
* http://easings.net/#easeInExpo
|
||||
*/
|
||||
/* $FlowFixMe(>=0.59.0 site=react_native_fb) This comment suppresses an error
|
||||
* caught by Flow 0.59 which was not caught before. Most likely, this error
|
||||
* is because an exported function parameter is missing an annotation.
|
||||
* Without an annotation, these parameters are uncovered by Flow. */
|
||||
static exp(t) {
|
||||
static exp(t: number) {
|
||||
return Math.pow(2, 10 * (t - 1));
|
||||
}
|
||||
|
||||
@@ -205,7 +164,7 @@ class Easing {
|
||||
*/
|
||||
static elastic(bounciness: number = 1): (t: number) => number {
|
||||
const p = bounciness * Math.PI;
|
||||
return t => 1 - Math.pow(Math.cos(t * Math.PI / 2), 3) * Math.cos(t * p);
|
||||
return (t) => 1 - Math.pow(Math.cos(t * Math.PI / 2), 3) * Math.cos(t * p);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,7 +179,7 @@ class Easing {
|
||||
if (s === undefined) {
|
||||
s = 1.70158;
|
||||
}
|
||||
return t => t * t * ((s + 1) * t - s);
|
||||
return (t) => t * t * ((s + 1) * t - s);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,22 +213,31 @@ class Easing {
|
||||
* A useful tool to visualize cubic bezier curves can be found at
|
||||
* http://cubic-bezier.com/
|
||||
*/
|
||||
static bezier(x1: number, y1: number, x2: number, y2: number): (t: number) => number {
|
||||
static bezier(
|
||||
x1: number,
|
||||
y1: number,
|
||||
x2: number,
|
||||
y2: number
|
||||
): (t: number) => number {
|
||||
return _bezier(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs an easing function forwards.
|
||||
*/
|
||||
static in(easing: (t: number) => number): (t: number) => number {
|
||||
static in(
|
||||
easing: (t: number) => number,
|
||||
): (t: number) => number {
|
||||
return easing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs an easing function backwards.
|
||||
*/
|
||||
static out(easing: (t: number) => number): (t: number) => number {
|
||||
return t => 1 - easing(1 - t);
|
||||
static out(
|
||||
easing: (t: number) => number,
|
||||
): (t: number) => number {
|
||||
return (t) => 1 - easing(1 - t);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -277,8 +245,10 @@ class Easing {
|
||||
* forwards for half of the duration, then backwards for the rest of the
|
||||
* duration.
|
||||
*/
|
||||
static inOut(easing: (t: number) => number): (t: number) => number {
|
||||
return t => {
|
||||
static inOut(
|
||||
easing: (t: number) => number,
|
||||
): (t: number) => number {
|
||||
return (t) => {
|
||||
if (t < 0.5) {
|
||||
return easing(t * 2) / 2;
|
||||
}
|
||||
|
||||
@@ -13,19 +13,19 @@ import invariant from 'fbjs/lib/invariant';
|
||||
import NativeModules from '../../../exports/NativeModules';
|
||||
import NativeEventEmitter from '../../../modules/NativeEventEmitter';
|
||||
|
||||
import type { AnimationConfig } from './animations/Animation';
|
||||
import type { EventConfig } from './AnimatedEvent';
|
||||
import type {AnimationConfig} from './animations/Animation';
|
||||
import type {EventConfig} from './AnimatedEvent';
|
||||
|
||||
const NativeAnimatedModule = NativeModules.NativeAnimatedModule;
|
||||
|
||||
let __nativeAnimatedNodeTagCount = 1; /* used for animated nodes */
|
||||
let __nativeAnimationIdCount = 1; /* used for started animations */
|
||||
|
||||
type EndResult = { finished: boolean };
|
||||
type EndResult = {finished: boolean};
|
||||
type EndCallback = (result: EndResult) => void;
|
||||
type EventMapping = {
|
||||
nativeEventPath: Array<string>,
|
||||
animatedValueTag: ?number
|
||||
animatedValueTag: ?number,
|
||||
};
|
||||
|
||||
let nativeEventEmitter;
|
||||
@@ -51,7 +51,10 @@ const API = {
|
||||
assertNativeAnimatedModule();
|
||||
NativeAnimatedModule.connectAnimatedNodes(parentTag, childTag);
|
||||
},
|
||||
disconnectAnimatedNodes: function(parentTag: ?number, childTag: ?number): void {
|
||||
disconnectAnimatedNodes: function(
|
||||
parentTag: ?number,
|
||||
childTag: ?number,
|
||||
): void {
|
||||
assertNativeAnimatedModule();
|
||||
NativeAnimatedModule.disconnectAnimatedNodes(parentTag, childTag);
|
||||
},
|
||||
@@ -59,10 +62,15 @@ const API = {
|
||||
animationId: ?number,
|
||||
nodeTag: ?number,
|
||||
config: Object,
|
||||
endCallback: EndCallback
|
||||
endCallback: EndCallback,
|
||||
): void {
|
||||
assertNativeAnimatedModule();
|
||||
NativeAnimatedModule.startAnimatingNode(animationId, nodeTag, config, endCallback);
|
||||
NativeAnimatedModule.startAnimatingNode(
|
||||
animationId,
|
||||
nodeTag,
|
||||
config,
|
||||
endCallback,
|
||||
);
|
||||
},
|
||||
stopAnimation: function(animationId: ?number) {
|
||||
assertNativeAnimatedModule();
|
||||
@@ -84,11 +92,17 @@ const API = {
|
||||
assertNativeAnimatedModule();
|
||||
NativeAnimatedModule.extractAnimatedNodeOffset(nodeTag);
|
||||
},
|
||||
connectAnimatedNodeToView: function(nodeTag: ?number, viewTag: ?number): void {
|
||||
connectAnimatedNodeToView: function(
|
||||
nodeTag: ?number,
|
||||
viewTag: ?number,
|
||||
): void {
|
||||
assertNativeAnimatedModule();
|
||||
NativeAnimatedModule.connectAnimatedNodeToView(nodeTag, viewTag);
|
||||
},
|
||||
disconnectAnimatedNodeFromView: function(nodeTag: ?number, viewTag: ?number): void {
|
||||
disconnectAnimatedNodeFromView: function(
|
||||
nodeTag: ?number,
|
||||
viewTag: ?number,
|
||||
): void {
|
||||
assertNativeAnimatedModule();
|
||||
NativeAnimatedModule.disconnectAnimatedNodeFromView(nodeTag, viewTag);
|
||||
},
|
||||
@@ -99,15 +113,27 @@ const API = {
|
||||
addAnimatedEventToView: function(
|
||||
viewTag: ?number,
|
||||
eventName: string,
|
||||
eventMapping: EventMapping
|
||||
eventMapping: EventMapping,
|
||||
) {
|
||||
assertNativeAnimatedModule();
|
||||
NativeAnimatedModule.addAnimatedEventToView(viewTag, eventName, eventMapping);
|
||||
NativeAnimatedModule.addAnimatedEventToView(
|
||||
viewTag,
|
||||
eventName,
|
||||
eventMapping,
|
||||
);
|
||||
},
|
||||
removeAnimatedEventFromView(viewTag: ?number, eventName: string, animatedNodeTag: ?number) {
|
||||
removeAnimatedEventFromView(
|
||||
viewTag: ?number,
|
||||
eventName: string,
|
||||
animatedNodeTag: ?number,
|
||||
) {
|
||||
assertNativeAnimatedModule();
|
||||
NativeAnimatedModule.removeAnimatedEventFromView(viewTag, eventName, animatedNodeTag);
|
||||
}
|
||||
NativeAnimatedModule.removeAnimatedEventFromView(
|
||||
viewTag,
|
||||
eventName,
|
||||
animatedNodeTag,
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -126,7 +152,7 @@ const STYLES_WHITELIST = {
|
||||
scaleX: true,
|
||||
scaleY: true,
|
||||
translateX: true,
|
||||
translateY: true
|
||||
translateY: true,
|
||||
};
|
||||
|
||||
const TRANSFORM_WHITELIST = {
|
||||
@@ -138,13 +164,37 @@ const TRANSFORM_WHITELIST = {
|
||||
rotate: true,
|
||||
rotateX: true,
|
||||
rotateY: true,
|
||||
perspective: true
|
||||
perspective: true,
|
||||
};
|
||||
|
||||
const SUPPORTED_INTERPOLATION_PARAMS = {
|
||||
inputRange: true,
|
||||
outputRange: true,
|
||||
extrapolate: true,
|
||||
extrapolateRight: true,
|
||||
extrapolateLeft: true,
|
||||
};
|
||||
|
||||
function addWhitelistedStyleProp(prop: string): void {
|
||||
STYLES_WHITELIST[prop] = true;
|
||||
}
|
||||
|
||||
function addWhitelistedTransformProp(prop: string): void {
|
||||
TRANSFORM_WHITELIST[prop] = true;
|
||||
}
|
||||
|
||||
function addWhitelistedInterpolationParam(param: string): void {
|
||||
SUPPORTED_INTERPOLATION_PARAMS[param] = true;
|
||||
}
|
||||
|
||||
function validateTransform(configs: Array<Object>): void {
|
||||
configs.forEach(config => {
|
||||
if (!TRANSFORM_WHITELIST.hasOwnProperty(config.property)) {
|
||||
throw new Error(`Property '${config.property}' is not supported by native animated module`);
|
||||
throw new Error(
|
||||
`Property '${
|
||||
config.property
|
||||
}' is not supported by native animated module`,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -152,22 +202,19 @@ function validateTransform(configs: Array<Object>): void {
|
||||
function validateStyles(styles: Object): void {
|
||||
for (var key in styles) {
|
||||
if (!STYLES_WHITELIST.hasOwnProperty(key)) {
|
||||
throw new Error(`Style property '${key}' is not supported by native animated module`);
|
||||
throw new Error(
|
||||
`Style property '${key}' is not supported by native animated module`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function validateInterpolation(config: Object): void {
|
||||
var SUPPORTED_INTERPOLATION_PARAMS = {
|
||||
inputRange: true,
|
||||
outputRange: true,
|
||||
extrapolate: true,
|
||||
extrapolateRight: true,
|
||||
extrapolateLeft: true
|
||||
};
|
||||
for (var key in config) {
|
||||
if (!SUPPORTED_INTERPOLATION_PARAMS.hasOwnProperty(key)) {
|
||||
throw new Error(`Interpolation property '${key}' is not supported by native animated module`);
|
||||
throw new Error(
|
||||
`Interpolation property '${key}' is not supported by native animated module`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -194,7 +241,7 @@ function shouldUseNativeDriver(config: AnimationConfig | EventConfig): boolean {
|
||||
'animated module is missing. Falling back to JS-based animation. To ' +
|
||||
'resolve this, add `RCTAnimation` module to this app, or remove ' +
|
||||
'`useNativeDriver`. ' +
|
||||
'More info: https://github.com/facebook/react-native/issues/11094#issuecomment-263240420'
|
||||
'More info: https://github.com/facebook/react-native/issues/11094#issuecomment-263240420',
|
||||
);
|
||||
_warnedMissingNativeAnimated = true;
|
||||
}
|
||||
@@ -206,6 +253,9 @@ function shouldUseNativeDriver(config: AnimationConfig | EventConfig): boolean {
|
||||
|
||||
const NativeAnimatedHelper = {
|
||||
API,
|
||||
addWhitelistedStyleProp,
|
||||
addWhitelistedTransformProp,
|
||||
addWhitelistedInterpolationParam,
|
||||
validateStyles,
|
||||
validateTransform,
|
||||
validateInterpolation,
|
||||
@@ -223,6 +273,9 @@ const NativeAnimatedHelper = {
|
||||
|
||||
export {
|
||||
API,
|
||||
addWhitelistedStyleProp,
|
||||
addWhitelistedTransformProp,
|
||||
addWhitelistedInterpolationParam,
|
||||
validateStyles,
|
||||
validateTransform,
|
||||
validateInterpolation,
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
type SpringConfigType = {
|
||||
stiffness: number,
|
||||
damping: number
|
||||
damping: number,
|
||||
};
|
||||
|
||||
function stiffnessFromOrigamiValue(oValue) {
|
||||
@@ -22,20 +22,26 @@ function dampingFromOrigamiValue(oValue) {
|
||||
return (oValue - 8) * 3 + 25;
|
||||
}
|
||||
|
||||
function fromOrigamiTensionAndFriction(tension: number, friction: number): SpringConfigType {
|
||||
function fromOrigamiTensionAndFriction(
|
||||
tension: number,
|
||||
friction: number,
|
||||
): SpringConfigType {
|
||||
return {
|
||||
stiffness: stiffnessFromOrigamiValue(tension),
|
||||
damping: dampingFromOrigamiValue(friction)
|
||||
damping: dampingFromOrigamiValue(friction),
|
||||
};
|
||||
}
|
||||
|
||||
function fromBouncinessAndSpeed(bounciness: number, speed: number): SpringConfigType {
|
||||
function fromBouncinessAndSpeed(
|
||||
bounciness: number,
|
||||
speed: number,
|
||||
): SpringConfigType {
|
||||
function normalize(value, startValue, endValue) {
|
||||
return (value - startValue) / (endValue - startValue);
|
||||
}
|
||||
|
||||
function projectNormal(n, start, end) {
|
||||
return start + n * (end - start);
|
||||
return start + (n * (end - start));
|
||||
}
|
||||
|
||||
function linearInterpolation(t, start, end) {
|
||||
@@ -47,15 +53,18 @@ function fromBouncinessAndSpeed(bounciness: number, speed: number): SpringConfig
|
||||
}
|
||||
|
||||
function b3Friction1(x) {
|
||||
return 0.0007 * Math.pow(x, 3) - 0.031 * Math.pow(x, 2) + 0.64 * x + 1.28;
|
||||
return (0.0007 * Math.pow(x, 3)) -
|
||||
(0.031 * Math.pow(x, 2)) + 0.64 * x + 1.28;
|
||||
}
|
||||
|
||||
function b3Friction2(x) {
|
||||
return 0.000044 * Math.pow(x, 3) - 0.006 * Math.pow(x, 2) + 0.36 * x + 2;
|
||||
return (0.000044 * Math.pow(x, 3)) -
|
||||
(0.006 * Math.pow(x, 2)) + 0.36 * x + 2;
|
||||
}
|
||||
|
||||
function b3Friction3(x) {
|
||||
return 0.00000045 * Math.pow(x, 3) - 0.000332 * Math.pow(x, 2) + 0.1078 * x + 5.84;
|
||||
return (0.00000045 * Math.pow(x, 3)) -
|
||||
(0.000332 * Math.pow(x, 2)) + 0.1078 * x + 5.84;
|
||||
}
|
||||
|
||||
function b3Nobounce(tension) {
|
||||
@@ -72,11 +81,15 @@ function fromBouncinessAndSpeed(bounciness: number, speed: number): SpringConfig
|
||||
b = projectNormal(b, 0, 0.8);
|
||||
var s = normalize(speed / 1.7, 0, 20);
|
||||
var bouncyTension = projectNormal(s, 0.5, 200);
|
||||
var bouncyFriction = quadraticOutInterpolation(b, b3Nobounce(bouncyTension), 0.01);
|
||||
var bouncyFriction = quadraticOutInterpolation(
|
||||
b,
|
||||
b3Nobounce(bouncyTension),
|
||||
0.01
|
||||
);
|
||||
|
||||
return {
|
||||
stiffness: stiffnessFromOrigamiValue(bouncyTension),
|
||||
damping: dampingFromOrigamiValue(bouncyFriction)
|
||||
damping: dampingFromOrigamiValue(bouncyFriction),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -13,14 +13,14 @@ import NativeAnimatedHelper from '../NativeAnimatedHelper';
|
||||
|
||||
import type AnimatedValue from '../nodes/AnimatedValue';
|
||||
|
||||
export type EndResult = { finished: boolean };
|
||||
export type EndResult = {finished: boolean};
|
||||
export type EndCallback = (result: EndResult) => void;
|
||||
|
||||
export type AnimationConfig = {
|
||||
isInteraction?: boolean,
|
||||
useNativeDriver?: boolean,
|
||||
onComplete?: ?EndCallback,
|
||||
iterations?: number
|
||||
iterations?: number,
|
||||
};
|
||||
|
||||
// Important note: start() and stop() will only be called at most once.
|
||||
@@ -37,7 +37,7 @@ class Animation {
|
||||
onUpdate: (value: number) => void,
|
||||
onEnd: ?EndCallback,
|
||||
previousAnimation: ?Animation,
|
||||
animatedValue: AnimatedValue
|
||||
animatedValue: AnimatedValue,
|
||||
): void {}
|
||||
stop(): void {
|
||||
if (this.__nativeId) {
|
||||
@@ -62,7 +62,7 @@ class Animation {
|
||||
this.__nativeId,
|
||||
animatedValue.__getNativeTag(),
|
||||
this.__getNativeAnimationConfig(),
|
||||
this.__debouncedOnEnd.bind(this)
|
||||
this.__debouncedOnEnd.bind(this),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,13 +17,13 @@ import type { AnimationConfig, EndCallback } from './Animation';
|
||||
import type AnimatedValue from '../nodes/AnimatedValue';
|
||||
|
||||
export type DecayAnimationConfig = AnimationConfig & {
|
||||
velocity: number | { x: number, y: number },
|
||||
deceleration?: number
|
||||
velocity: number | {x: number, y: number},
|
||||
deceleration?: number,
|
||||
};
|
||||
|
||||
export type DecayAnimationConfigSingle = AnimationConfig & {
|
||||
velocity: number,
|
||||
deceleration?: number
|
||||
deceleration?: number,
|
||||
};
|
||||
|
||||
class DecayAnimation extends Animation {
|
||||
@@ -38,10 +38,12 @@ class DecayAnimation extends Animation {
|
||||
|
||||
constructor(config: DecayAnimationConfigSingle) {
|
||||
super();
|
||||
this._deceleration = config.deceleration !== undefined ? config.deceleration : 0.998;
|
||||
this._deceleration =
|
||||
config.deceleration !== undefined ? config.deceleration : 0.998;
|
||||
this._velocity = config.velocity;
|
||||
this._useNativeDriver = shouldUseNativeDriver(config);
|
||||
this.__isInteraction = config.isInteraction !== undefined ? config.isInteraction : true;
|
||||
this.__isInteraction =
|
||||
config.isInteraction !== undefined ? config.isInteraction : true;
|
||||
this.__iterations = config.iterations !== undefined ? config.iterations : 1;
|
||||
}
|
||||
|
||||
@@ -50,7 +52,7 @@ class DecayAnimation extends Animation {
|
||||
type: 'decay',
|
||||
deceleration: this._deceleration,
|
||||
velocity: this._velocity,
|
||||
iterations: this.__iterations
|
||||
iterations: this.__iterations,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -59,7 +61,7 @@ class DecayAnimation extends Animation {
|
||||
onUpdate: (value: number) => void,
|
||||
onEnd: ?EndCallback,
|
||||
previousAnimation: ?Animation,
|
||||
animatedValue: AnimatedValue
|
||||
animatedValue: AnimatedValue,
|
||||
): void {
|
||||
this.__active = true;
|
||||
this._lastValue = fromValue;
|
||||
@@ -86,7 +88,7 @@ class DecayAnimation extends Animation {
|
||||
this._onUpdate(value);
|
||||
|
||||
if (Math.abs(this._lastValue - value) < 0.1) {
|
||||
this.__debouncedOnEnd({ finished: true });
|
||||
this.__debouncedOnEnd({finished: true});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -100,7 +102,7 @@ class DecayAnimation extends Animation {
|
||||
super.stop();
|
||||
this.__active = false;
|
||||
global.cancelAnimationFrame(this._animationFrame);
|
||||
this.__debouncedOnEnd({ finished: false });
|
||||
this.__debouncedOnEnd({finished: false});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,14 +17,14 @@ import SpringConfig from '../SpringConfig';
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
import { shouldUseNativeDriver } from '../NativeAnimatedHelper';
|
||||
|
||||
import type { AnimationConfig, EndCallback } from './Animation';
|
||||
import type {AnimationConfig, EndCallback} from './Animation';
|
||||
|
||||
export type SpringAnimationConfig = AnimationConfig & {
|
||||
toValue: number | AnimatedValue | { x: number, y: number } | AnimatedValueXY,
|
||||
toValue: number | AnimatedValue | {x: number, y: number} | AnimatedValueXY,
|
||||
overshootClamping?: boolean,
|
||||
restDisplacementThreshold?: number,
|
||||
restSpeedThreshold?: number,
|
||||
velocity?: number | { x: number, y: number },
|
||||
velocity?: number | {x: number, y: number},
|
||||
bounciness?: number,
|
||||
speed?: number,
|
||||
tension?: number,
|
||||
@@ -32,7 +32,7 @@ export type SpringAnimationConfig = AnimationConfig & {
|
||||
stiffness?: number,
|
||||
damping?: number,
|
||||
mass?: number,
|
||||
delay?: number
|
||||
delay?: number,
|
||||
};
|
||||
|
||||
export type SpringAnimationConfigSingle = AnimationConfig & {
|
||||
@@ -48,7 +48,7 @@ export type SpringAnimationConfigSingle = AnimationConfig & {
|
||||
stiffness?: number,
|
||||
damping?: number,
|
||||
mass?: number,
|
||||
delay?: number
|
||||
delay?: number,
|
||||
};
|
||||
|
||||
function withDefault<T>(value: ?T, defaultValue: T): T {
|
||||
@@ -84,14 +84,18 @@ class SpringAnimation extends Animation {
|
||||
super();
|
||||
|
||||
this._overshootClamping = withDefault(config.overshootClamping, false);
|
||||
this._restDisplacementThreshold = withDefault(config.restDisplacementThreshold, 0.001);
|
||||
this._restDisplacementThreshold = withDefault(
|
||||
config.restDisplacementThreshold,
|
||||
0.001,
|
||||
);
|
||||
this._restSpeedThreshold = withDefault(config.restSpeedThreshold, 0.001);
|
||||
this._initialVelocity = withDefault(config.velocity, 0);
|
||||
this._lastVelocity = withDefault(config.velocity, 0);
|
||||
this._toValue = config.toValue;
|
||||
this._delay = withDefault(config.delay, 0);
|
||||
this._useNativeDriver = shouldUseNativeDriver(config);
|
||||
this.__isInteraction = config.isInteraction !== undefined ? config.isInteraction : true;
|
||||
this.__isInteraction =
|
||||
config.isInteraction !== undefined ? config.isInteraction : true;
|
||||
this.__iterations = config.iterations !== undefined ? config.iterations : 1;
|
||||
|
||||
if (
|
||||
@@ -104,7 +108,7 @@ class SpringAnimation extends Animation {
|
||||
config.speed === undefined &&
|
||||
config.tension === undefined &&
|
||||
config.friction === undefined,
|
||||
'You can define one of bounciness/speed, tension/friction, or stiffness/damping/mass, but not more than one'
|
||||
'You can define one of bounciness/speed, tension/friction, or stiffness/damping/mass, but not more than one',
|
||||
);
|
||||
this._stiffness = withDefault(config.stiffness, 100);
|
||||
this._damping = withDefault(config.damping, 10);
|
||||
@@ -118,11 +122,11 @@ class SpringAnimation extends Animation {
|
||||
config.stiffness === undefined &&
|
||||
config.damping === undefined &&
|
||||
config.mass === undefined,
|
||||
'You can define one of bounciness/speed, tension/friction, or stiffness/damping/mass, but not more than one'
|
||||
'You can define one of bounciness/speed, tension/friction, or stiffness/damping/mass, but not more than one',
|
||||
);
|
||||
const springConfig = SpringConfig.fromBouncinessAndSpeed(
|
||||
withDefault(config.bounciness, 8),
|
||||
withDefault(config.speed, 12)
|
||||
withDefault(config.speed, 12),
|
||||
);
|
||||
this._stiffness = springConfig.stiffness;
|
||||
this._damping = springConfig.damping;
|
||||
@@ -132,7 +136,7 @@ class SpringAnimation extends Animation {
|
||||
// We assume mass is 1.
|
||||
const springConfig = SpringConfig.fromOrigamiTensionAndFriction(
|
||||
withDefault(config.tension, 40),
|
||||
withDefault(config.friction, 7)
|
||||
withDefault(config.friction, 7),
|
||||
);
|
||||
this._stiffness = springConfig.stiffness;
|
||||
this._damping = springConfig.damping;
|
||||
@@ -155,7 +159,7 @@ class SpringAnimation extends Animation {
|
||||
mass: this._mass,
|
||||
initialVelocity: withDefault(this._initialVelocity, this._lastVelocity),
|
||||
toValue: this._toValue,
|
||||
iterations: this.__iterations
|
||||
iterations: this.__iterations,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -164,7 +168,7 @@ class SpringAnimation extends Animation {
|
||||
onUpdate: (value: number) => void,
|
||||
onEnd: ?EndCallback,
|
||||
previousAnimation: ?Animation,
|
||||
animatedValue: AnimatedValue
|
||||
animatedValue: AnimatedValue,
|
||||
): void {
|
||||
this.__active = true;
|
||||
this._startPosition = fromValue;
|
||||
@@ -204,7 +208,7 @@ class SpringAnimation extends Animation {
|
||||
return {
|
||||
lastPosition: this._lastPosition,
|
||||
lastVelocity: this._lastVelocity,
|
||||
lastTime: this._lastTime
|
||||
lastTime: this._lastTime,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -262,21 +266,25 @@ class SpringAnimation extends Animation {
|
||||
position =
|
||||
this._toValue -
|
||||
envelope *
|
||||
((v0 + zeta * omega0 * x0) / omega1 * Math.sin(omega1 * t) + x0 * Math.cos(omega1 * t));
|
||||
((v0 + zeta * omega0 * x0) / omega1 * Math.sin(omega1 * t) +
|
||||
x0 * Math.cos(omega1 * t));
|
||||
// This looks crazy -- it's actually just the derivative of the
|
||||
// oscillation function
|
||||
velocity =
|
||||
zeta *
|
||||
omega0 *
|
||||
envelope *
|
||||
(Math.sin(omega1 * t) * (v0 + zeta * omega0 * x0) / omega1 + x0 * Math.cos(omega1 * t)) -
|
||||
(Math.sin(omega1 * t) * (v0 + zeta * omega0 * x0) / omega1 +
|
||||
x0 * Math.cos(omega1 * t)) -
|
||||
envelope *
|
||||
(Math.cos(omega1 * t) * (v0 + zeta * omega0 * x0) - omega1 * x0 * Math.sin(omega1 * t));
|
||||
(Math.cos(omega1 * t) * (v0 + zeta * omega0 * x0) -
|
||||
omega1 * x0 * Math.sin(omega1 * t));
|
||||
} else {
|
||||
// Critically damped
|
||||
const envelope = Math.exp(-omega0 * t);
|
||||
position = this._toValue - envelope * (x0 + (v0 + omega0 * x0) * t);
|
||||
velocity = envelope * (v0 * (t * omega0 - 1) + t * x0 * (omega0 * omega0));
|
||||
velocity =
|
||||
envelope * (v0 * (t * omega0 - 1) + t * x0 * (omega0 * omega0));
|
||||
}
|
||||
|
||||
this._lastTime = now;
|
||||
@@ -301,7 +309,8 @@ class SpringAnimation extends Animation {
|
||||
const isVelocity = Math.abs(velocity) <= this._restSpeedThreshold;
|
||||
let isDisplacement = true;
|
||||
if (this._stiffness !== 0) {
|
||||
isDisplacement = Math.abs(this._toValue - position) <= this._restDisplacementThreshold;
|
||||
isDisplacement =
|
||||
Math.abs(this._toValue - position) <= this._restDisplacementThreshold;
|
||||
}
|
||||
|
||||
if (isOvershooting || (isVelocity && isDisplacement)) {
|
||||
@@ -312,7 +321,7 @@ class SpringAnimation extends Animation {
|
||||
this._onUpdate(this._toValue);
|
||||
}
|
||||
|
||||
this.__debouncedOnEnd({ finished: true });
|
||||
this.__debouncedOnEnd({finished: true});
|
||||
return;
|
||||
}
|
||||
this._animationFrame = requestAnimationFrame(this.onUpdate.bind(this));
|
||||
@@ -323,7 +332,7 @@ class SpringAnimation extends Animation {
|
||||
this.__active = false;
|
||||
clearTimeout(this._timeout);
|
||||
global.cancelAnimationFrame(this._animationFrame);
|
||||
this.__debouncedOnEnd({ finished: false });
|
||||
this.__debouncedOnEnd({finished: false});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,20 +16,20 @@ import Easing from '../Easing';
|
||||
|
||||
import { shouldUseNativeDriver } from '../NativeAnimatedHelper';
|
||||
|
||||
import type { AnimationConfig, EndCallback } from './Animation';
|
||||
import type {AnimationConfig, EndCallback} from './Animation';
|
||||
|
||||
export type TimingAnimationConfig = AnimationConfig & {
|
||||
toValue: number | AnimatedValue | { x: number, y: number } | AnimatedValueXY,
|
||||
toValue: number | AnimatedValue | {x: number, y: number} | AnimatedValueXY,
|
||||
easing?: (value: number) => number,
|
||||
duration?: number,
|
||||
delay?: number
|
||||
delay?: number,
|
||||
};
|
||||
|
||||
export type TimingAnimationConfigSingle = AnimationConfig & {
|
||||
toValue: number | AnimatedValue,
|
||||
easing?: (value: number) => number,
|
||||
duration?: number,
|
||||
delay?: number
|
||||
delay?: number,
|
||||
};
|
||||
|
||||
let _easeInOut;
|
||||
@@ -59,7 +59,8 @@ class TimingAnimation extends Animation {
|
||||
this._duration = config.duration !== undefined ? config.duration : 500;
|
||||
this._delay = config.delay !== undefined ? config.delay : 0;
|
||||
this.__iterations = config.iterations !== undefined ? config.iterations : 1;
|
||||
this.__isInteraction = config.isInteraction !== undefined ? config.isInteraction : true;
|
||||
this.__isInteraction =
|
||||
config.isInteraction !== undefined ? config.isInteraction : true;
|
||||
this._useNativeDriver = shouldUseNativeDriver(config);
|
||||
}
|
||||
|
||||
@@ -74,7 +75,7 @@ class TimingAnimation extends Animation {
|
||||
type: 'frames',
|
||||
frames,
|
||||
toValue: this._toValue,
|
||||
iterations: this.__iterations
|
||||
iterations: this.__iterations,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -83,7 +84,7 @@ class TimingAnimation extends Animation {
|
||||
onUpdate: (value: number) => void,
|
||||
onEnd: ?EndCallback,
|
||||
previousAnimation: ?Animation,
|
||||
animatedValue: AnimatedValue
|
||||
animatedValue: AnimatedValue,
|
||||
): void {
|
||||
this.__active = true;
|
||||
this._fromValue = fromValue;
|
||||
@@ -96,13 +97,15 @@ class TimingAnimation extends Animation {
|
||||
// not cause intermixed JS and native animations.
|
||||
if (this._duration === 0 && !this._useNativeDriver) {
|
||||
this._onUpdate(this._toValue);
|
||||
this.__debouncedOnEnd({ finished: true });
|
||||
this.__debouncedOnEnd({finished: true});
|
||||
} else {
|
||||
this._startTime = Date.now();
|
||||
if (this._useNativeDriver) {
|
||||
this.__startNativeAnimation(animatedValue);
|
||||
} else {
|
||||
this._animationFrame = requestAnimationFrame(this.onUpdate.bind(this));
|
||||
this._animationFrame = requestAnimationFrame(
|
||||
this.onUpdate.bind(this),
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -119,15 +122,18 @@ class TimingAnimation extends Animation {
|
||||
if (this._duration === 0) {
|
||||
this._onUpdate(this._toValue);
|
||||
} else {
|
||||
this._onUpdate(this._fromValue + this._easing(1) * (this._toValue - this._fromValue));
|
||||
this._onUpdate(
|
||||
this._fromValue + this._easing(1) * (this._toValue - this._fromValue),
|
||||
);
|
||||
}
|
||||
this.__debouncedOnEnd({ finished: true });
|
||||
this.__debouncedOnEnd({finished: true});
|
||||
return;
|
||||
}
|
||||
|
||||
this._onUpdate(
|
||||
this._fromValue +
|
||||
this._easing((now - this._startTime) / this._duration) * (this._toValue - this._fromValue)
|
||||
this._easing((now - this._startTime) / this._duration) *
|
||||
(this._toValue - this._fromValue),
|
||||
);
|
||||
if (this.__active) {
|
||||
this._animationFrame = requestAnimationFrame(this.onUpdate.bind(this));
|
||||
@@ -139,7 +145,7 @@ class TimingAnimation extends Animation {
|
||||
this.__active = false;
|
||||
clearTimeout(this._timeout);
|
||||
global.cancelAnimationFrame(this._animationFrame);
|
||||
this.__debouncedOnEnd({ finished: false });
|
||||
this.__debouncedOnEnd({finished: false});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,54 +7,42 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
// These values are established by empiricism with tests (tradeoff: performance VS precision)
|
||||
var NEWTON_ITERATIONS = 4;
|
||||
var NEWTON_MIN_SLOPE = 0.001;
|
||||
var SUBDIVISION_PRECISION = 0.0000001;
|
||||
var SUBDIVISION_MAX_ITERATIONS = 10;
|
||||
// These values are established by empiricism with tests (tradeoff: performance VS precision)
|
||||
var NEWTON_ITERATIONS = 4;
|
||||
var NEWTON_MIN_SLOPE = 0.001;
|
||||
var SUBDIVISION_PRECISION = 0.0000001;
|
||||
var SUBDIVISION_MAX_ITERATIONS = 10;
|
||||
|
||||
var kSplineTableSize = 11;
|
||||
var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
|
||||
var kSplineTableSize = 11;
|
||||
var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
|
||||
|
||||
var float32ArraySupported = typeof Float32Array === 'function';
|
||||
var float32ArraySupported = typeof Float32Array === 'function';
|
||||
|
||||
function A(aA1, aA2) {
|
||||
return 1.0 - 3.0 * aA2 + 3.0 * aA1;
|
||||
}
|
||||
function B(aA1, aA2) {
|
||||
return 3.0 * aA2 - 6.0 * aA1;
|
||||
}
|
||||
function C(aA1) {
|
||||
return 3.0 * aA1;
|
||||
}
|
||||
function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
|
||||
function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
|
||||
function C (aA1) { return 3.0 * aA1; }
|
||||
|
||||
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
|
||||
function calcBezier(aT, aA1, aA2) {
|
||||
return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
|
||||
}
|
||||
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
|
||||
function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; }
|
||||
|
||||
// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
|
||||
function getSlope(aT, aA1, aA2) {
|
||||
return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
|
||||
}
|
||||
// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
|
||||
function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); }
|
||||
|
||||
function binarySubdivide(aX, aA, aB, mX1, mX2) {
|
||||
var currentX,
|
||||
currentT,
|
||||
i = 0;
|
||||
do {
|
||||
currentT = aA + (aB - aA) / 2.0;
|
||||
currentX = calcBezier(currentT, mX1, mX2) - aX;
|
||||
if (currentX > 0.0) {
|
||||
aB = currentT;
|
||||
} else {
|
||||
aA = currentT;
|
||||
}
|
||||
} while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
|
||||
return currentT;
|
||||
}
|
||||
function binarySubdivide (aX, aA, aB, mX1, mX2) {
|
||||
var currentX, currentT, i = 0;
|
||||
do {
|
||||
currentT = aA + (aB - aA) / 2.0;
|
||||
currentX = calcBezier(currentT, mX1, mX2) - aX;
|
||||
if (currentX > 0.0) {
|
||||
aB = currentT;
|
||||
} else {
|
||||
aA = currentT;
|
||||
}
|
||||
} while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
|
||||
return currentT;
|
||||
}
|
||||
|
||||
function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
|
||||
function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
|
||||
for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
|
||||
var currentSlope = getSlope(aGuessT, mX1, mX2);
|
||||
if (currentSlope === 0.0) {
|
||||
@@ -64,63 +52,56 @@ function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
|
||||
aGuessT -= currentX / currentSlope;
|
||||
}
|
||||
return aGuessT;
|
||||
}
|
||||
}
|
||||
|
||||
function bezier(mX1, mY1, mX2, mY2) {
|
||||
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {
|
||||
// eslint-disable-line yoda
|
||||
throw new Error('bezier x values must be in [0, 1] range');
|
||||
}
|
||||
module.exports = function bezier (mX1, mY1, mX2, mY2) {
|
||||
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) { // eslint-disable-line yoda
|
||||
throw new Error('bezier x values must be in [0, 1] range');
|
||||
}
|
||||
|
||||
// Precompute samples table
|
||||
var sampleValues = float32ArraySupported
|
||||
? new Float32Array(kSplineTableSize)
|
||||
: new Array(kSplineTableSize);
|
||||
if (mX1 !== mY1 || mX2 !== mY2) {
|
||||
for (var i = 0; i < kSplineTableSize; ++i) {
|
||||
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
|
||||
}
|
||||
}
|
||||
// Precompute samples table
|
||||
var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
|
||||
if (mX1 !== mY1 || mX2 !== mY2) {
|
||||
for (var i = 0; i < kSplineTableSize; ++i) {
|
||||
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
|
||||
}
|
||||
}
|
||||
|
||||
function getTForX(aX) {
|
||||
var intervalStart = 0.0;
|
||||
var currentSample = 1;
|
||||
var lastSample = kSplineTableSize - 1;
|
||||
function getTForX (aX) {
|
||||
var intervalStart = 0.0;
|
||||
var currentSample = 1;
|
||||
var lastSample = kSplineTableSize - 1;
|
||||
|
||||
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
|
||||
intervalStart += kSampleStepSize;
|
||||
}
|
||||
--currentSample;
|
||||
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
|
||||
intervalStart += kSampleStepSize;
|
||||
}
|
||||
--currentSample;
|
||||
|
||||
// Interpolate to provide an initial guess for t
|
||||
var dist =
|
||||
(aX - sampleValues[currentSample]) /
|
||||
(sampleValues[currentSample + 1] - sampleValues[currentSample]);
|
||||
var guessForT = intervalStart + dist * kSampleStepSize;
|
||||
// Interpolate to provide an initial guess for t
|
||||
var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
|
||||
var guessForT = intervalStart + dist * kSampleStepSize;
|
||||
|
||||
var initialSlope = getSlope(guessForT, mX1, mX2);
|
||||
if (initialSlope >= NEWTON_MIN_SLOPE) {
|
||||
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
|
||||
} else if (initialSlope === 0.0) {
|
||||
return guessForT;
|
||||
} else {
|
||||
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
|
||||
}
|
||||
}
|
||||
var initialSlope = getSlope(guessForT, mX1, mX2);
|
||||
if (initialSlope >= NEWTON_MIN_SLOPE) {
|
||||
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
|
||||
} else if (initialSlope === 0.0) {
|
||||
return guessForT;
|
||||
} else {
|
||||
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
|
||||
}
|
||||
}
|
||||
|
||||
return function BezierEasing(x) {
|
||||
if (mX1 === mY1 && mX2 === mY2) {
|
||||
return x; // linear
|
||||
}
|
||||
// Because JavaScript number are imprecise, we should guarantee the extremes are right.
|
||||
if (x === 0) {
|
||||
return 0;
|
||||
}
|
||||
if (x === 1) {
|
||||
return 1;
|
||||
}
|
||||
return calcBezier(getTForX(x), mY1, mY2);
|
||||
};
|
||||
}
|
||||
|
||||
export default bezier;
|
||||
return function BezierEasing (x) {
|
||||
if (mX1 === mY1 && mX2 === mY2) {
|
||||
return x; // linear
|
||||
}
|
||||
// Because JavaScript number are imprecise, we should guarantee the extremes are right.
|
||||
if (x === 0) {
|
||||
return 0;
|
||||
}
|
||||
if (x === 1) {
|
||||
return 1;
|
||||
}
|
||||
return calcBezier(getTForX(x), mY1, mY2);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -13,8 +13,16 @@ import { AnimatedEvent } from './AnimatedEvent';
|
||||
import AnimatedProps from './nodes/AnimatedProps';
|
||||
import React from 'react';
|
||||
import ViewStylePropTypes from '../../../exports/View/ViewStylePropTypes';
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
|
||||
function createAnimatedComponent(Component: any): any {
|
||||
invariant(
|
||||
typeof Component === 'string' ||
|
||||
(Component.prototype && Component.prototype.isReactComponent),
|
||||
'`createAnimatedComponent` does not support stateless functional components; ' +
|
||||
'use a class component instead.',
|
||||
);
|
||||
|
||||
class AnimatedComponent extends React.Component<Object> {
|
||||
_component: any;
|
||||
_invokeAnimatedPropsCallbackOnMount: boolean = false;
|
||||
@@ -39,7 +47,7 @@ function createAnimatedComponent(Component: any): any {
|
||||
this._component.setNativeProps(props);
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
UNSAFE_componentWillMount() {
|
||||
this._attachProps(this.props);
|
||||
}
|
||||
|
||||
@@ -93,12 +101,14 @@ function createAnimatedComponent(Component: any): any {
|
||||
) {
|
||||
this.forceUpdate();
|
||||
} else if (!this._propsAnimated.__isNative) {
|
||||
this._component.setNativeProps(this._propsAnimated.__getAnimatedValue());
|
||||
this._component.setNativeProps(
|
||||
this._propsAnimated.__getAnimatedValue(),
|
||||
);
|
||||
} else {
|
||||
throw new Error(
|
||||
'Attempting to run JS driven animation on animated ' +
|
||||
'node that has been moved to "native" earlier by starting an ' +
|
||||
'animation with `useNativeDriver: true`'
|
||||
'animation with `useNativeDriver: true`',
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -106,7 +116,10 @@ function createAnimatedComponent(Component: any): any {
|
||||
_attachProps(nextProps) {
|
||||
const oldPropsAnimated = this._propsAnimated;
|
||||
|
||||
this._propsAnimated = new AnimatedProps(nextProps, this._animatedPropsCallback);
|
||||
this._propsAnimated = new AnimatedProps(
|
||||
nextProps,
|
||||
this._animatedPropsCallback,
|
||||
);
|
||||
|
||||
// When you call detach, it removes the element from the parent list
|
||||
// of children. If it goes to 0, then the parent also detaches itself
|
||||
@@ -119,7 +132,7 @@ function createAnimatedComponent(Component: any): any {
|
||||
oldPropsAnimated && oldPropsAnimated.__detach();
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps) {
|
||||
UNSAFE_componentWillReceiveProps(newProps) {
|
||||
this._attachProps(newProps);
|
||||
}
|
||||
|
||||
@@ -141,9 +154,11 @@ function createAnimatedComponent(Component: any): any {
|
||||
ref={this._setComponentRef}
|
||||
// The native driver updates views directly through the UI thread so we
|
||||
// have to make sure the view doesn't get optimized away because it cannot
|
||||
// go through the NativeViewHierachyManager since it operates on the shadow
|
||||
// go through the NativeViewHierarchyManager since it operates on the shadow
|
||||
// thread.
|
||||
collapsable={this._propsAnimated.__isNative ? false : props.collapsable}
|
||||
collapsable={
|
||||
this._propsAnimated.__isNative ? false : props.collapsable
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -177,11 +192,11 @@ function createAnimatedComponent(Component: any): any {
|
||||
'should nest it in a style object. ' +
|
||||
'E.g. `{ style: { ' +
|
||||
key +
|
||||
': ... } }`'
|
||||
': ... } }`',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
return AnimatedComponent;
|
||||
|
||||
@@ -14,7 +14,7 @@ import AnimatedNode from './AnimatedNode';
|
||||
import AnimatedValue from './AnimatedValue';
|
||||
import AnimatedWithChildren from './AnimatedWithChildren';
|
||||
|
||||
import type { InterpolationConfigType } from './AnimatedInterpolation';
|
||||
import type {InterpolationConfigType} from './AnimatedInterpolation';
|
||||
|
||||
class AnimatedAddition extends AnimatedWithChildren {
|
||||
_a: AnimatedNode;
|
||||
@@ -54,7 +54,7 @@ class AnimatedAddition extends AnimatedWithChildren {
|
||||
__getNativeConfig(): any {
|
||||
return {
|
||||
type: 'addition',
|
||||
input: [this._a.__getNativeTag(), this._b.__getNativeTag()]
|
||||
input: [this._a.__getNativeTag(), this._b.__getNativeTag()],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import AnimatedInterpolation from './AnimatedInterpolation';
|
||||
import AnimatedNode from './AnimatedNode';
|
||||
import AnimatedWithChildren from './AnimatedWithChildren';
|
||||
|
||||
import type { InterpolationConfigType } from './AnimatedInterpolation';
|
||||
import type {InterpolationConfigType} from './AnimatedInterpolation';
|
||||
|
||||
class AnimatedDiffClamp extends AnimatedWithChildren {
|
||||
_a: AnimatedNode;
|
||||
@@ -62,7 +62,7 @@ class AnimatedDiffClamp extends AnimatedWithChildren {
|
||||
type: 'diffclamp',
|
||||
input: this._a.__getNativeTag(),
|
||||
min: this._min,
|
||||
max: this._max
|
||||
max: this._max,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import AnimatedNode from './AnimatedNode';
|
||||
import AnimatedValue from './AnimatedValue';
|
||||
import AnimatedWithChildren from './AnimatedWithChildren';
|
||||
|
||||
import type { InterpolationConfigType } from './AnimatedInterpolation';
|
||||
import type {InterpolationConfigType} from './AnimatedInterpolation';
|
||||
|
||||
class AnimatedDivision extends AnimatedWithChildren {
|
||||
_a: AnimatedNode;
|
||||
@@ -59,7 +59,7 @@ class AnimatedDivision extends AnimatedWithChildren {
|
||||
__getNativeConfig(): any {
|
||||
return {
|
||||
type: 'division',
|
||||
input: [this._a.__getNativeTag(), this._b.__getNativeTag()]
|
||||
input: [this._a.__getNativeTag(), this._b.__getNativeTag()],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ export type InterpolationConfigType = {
|
||||
easing?: (input: number) => number,
|
||||
extrapolate?: ExtrapolateType,
|
||||
extrapolateLeft?: ExtrapolateType,
|
||||
extrapolateRight?: ExtrapolateType
|
||||
extrapolateRight?: ExtrapolateType,
|
||||
};
|
||||
|
||||
const linear = t => t;
|
||||
@@ -38,7 +38,9 @@ const linear = t => t;
|
||||
* Very handy helper to map input ranges to output ranges with an easing
|
||||
* function and custom behavior outside of the ranges.
|
||||
*/
|
||||
function createInterpolation(config: InterpolationConfigType): (input: number) => number | string {
|
||||
function createInterpolation(
|
||||
config: InterpolationConfigType,
|
||||
): (input: number) => number | string {
|
||||
if (config.outputRange && typeof config.outputRange[0] === 'string') {
|
||||
return createInterpolationFromStringOutputRange(config);
|
||||
}
|
||||
@@ -56,7 +58,7 @@ function createInterpolation(config: InterpolationConfigType): (input: number) =
|
||||
inputRange.length +
|
||||
') and outputRange (' +
|
||||
outputRange.length +
|
||||
') must have the same length'
|
||||
') must have the same length',
|
||||
);
|
||||
|
||||
const easing = config.easing || linear;
|
||||
@@ -76,7 +78,10 @@ function createInterpolation(config: InterpolationConfigType): (input: number) =
|
||||
}
|
||||
|
||||
return input => {
|
||||
invariant(typeof input === 'number', 'Cannot interpolation an input which is not a number');
|
||||
invariant(
|
||||
typeof input === 'number',
|
||||
'Cannot interpolation an input which is not a number',
|
||||
);
|
||||
|
||||
const range = findRange(input, inputRange);
|
||||
return interpolate(
|
||||
@@ -87,7 +92,7 @@ function createInterpolation(config: InterpolationConfigType): (input: number) =
|
||||
outputRange[range + 1],
|
||||
easing,
|
||||
extrapolateLeft,
|
||||
extrapolateRight
|
||||
extrapolateRight,
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -100,7 +105,7 @@ function interpolate(
|
||||
outputMax: number,
|
||||
easing: (input: number) => number,
|
||||
extrapolateLeft: ExtrapolateType,
|
||||
extrapolateRight: ExtrapolateType
|
||||
extrapolateRight: ExtrapolateType,
|
||||
) {
|
||||
let result = input;
|
||||
|
||||
@@ -187,7 +192,7 @@ const stringShapeRegex = /[0-9\.-]+/g;
|
||||
* -45deg // values with units
|
||||
*/
|
||||
function createInterpolationFromStringOutputRange(
|
||||
config: InterpolationConfigType
|
||||
config: InterpolationConfigType,
|
||||
): (input: number) => string {
|
||||
let outputRange: Array<string> = (config.outputRange: any);
|
||||
invariant(outputRange.length >= 2, 'Bad output range');
|
||||
@@ -218,12 +223,14 @@ function createInterpolationFromStringOutputRange(
|
||||
/* $FlowFixMe(>=0.18.0): `outputRange[0].match()` can return `null`. Need to
|
||||
* guard against this possibility.
|
||||
*/
|
||||
const interpolations = outputRange[0].match(stringShapeRegex).map((value, i) => {
|
||||
return createInterpolation({
|
||||
...config,
|
||||
outputRange: outputRanges[i]
|
||||
const interpolations = outputRange[0]
|
||||
.match(stringShapeRegex)
|
||||
.map((value, i) => {
|
||||
return createInterpolation({
|
||||
...config,
|
||||
outputRange: outputRanges[i],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// rgba requires that the r,g,b are integers.... so we want to round them, but we *dont* want to
|
||||
// round the opacity (4th column).
|
||||
@@ -236,7 +243,8 @@ function createInterpolationFromStringOutputRange(
|
||||
// 'rgba(${interpolations[0](input)}, ${interpolations[1](input)}, ...'
|
||||
return outputRange[0].replace(stringShapeRegex, () => {
|
||||
const val = +interpolations[i++](input);
|
||||
const rounded = shouldRound && i < 4 ? Math.round(val) : Math.round(val * 1000) / 1000;
|
||||
const rounded =
|
||||
shouldRound && i < 4 ? Math.round(val) : Math.round(val * 1000) / 1000;
|
||||
return String(rounded);
|
||||
});
|
||||
};
|
||||
@@ -251,7 +259,7 @@ function checkPattern(arr: Array<string>) {
|
||||
for (let i = 1; i < arr.length; ++i) {
|
||||
invariant(
|
||||
pattern === arr[i].replace(stringShapeRegex, ''),
|
||||
'invalid pattern ' + arr[0] + ' and ' + arr[i]
|
||||
'invalid pattern ' + arr[0] + ' and ' + arr[i],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -277,7 +285,7 @@ function checkValidInputRange(arr: Array<number>) {
|
||||
* mean this implicit string conversion, you can do something like
|
||||
* String(myThing)
|
||||
*/
|
||||
'inputRange must be monotonically increasing ' + arr
|
||||
'inputRange must be monotonically increasing ' + arr,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -292,7 +300,7 @@ function checkInfiniteRange(name: string, arr: Array<number>) {
|
||||
* this implicit string conversion, you can do something like
|
||||
* String(myThing)
|
||||
*/
|
||||
name + 'cannot be ]-infinity;+infinity[ ' + arr
|
||||
name + 'cannot be ]-infinity;+infinity[ ' + arr,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -320,7 +328,7 @@ class AnimatedInterpolation extends AnimatedWithChildren {
|
||||
const parentValue: number = this._parent.__getValue();
|
||||
invariant(
|
||||
typeof parentValue === 'number',
|
||||
'Cannot interpolate an input which is not a number.'
|
||||
'Cannot interpolate an input which is not a number.',
|
||||
);
|
||||
return this._interpolation(parentValue);
|
||||
}
|
||||
@@ -363,11 +371,13 @@ class AnimatedInterpolation extends AnimatedWithChildren {
|
||||
|
||||
return {
|
||||
inputRange: this._config.inputRange,
|
||||
// Only the `outputRange` can contain strings so we don't need to tranform `inputRange` here
|
||||
// Only the `outputRange` can contain strings so we don't need to transform `inputRange` here
|
||||
outputRange: this.__transformDataType(this._config.outputRange),
|
||||
extrapolateLeft: this._config.extrapolateLeft || this._config.extrapolate || 'extend',
|
||||
extrapolateRight: this._config.extrapolateRight || this._config.extrapolate || 'extend',
|
||||
type: 'interpolation'
|
||||
extrapolateLeft:
|
||||
this._config.extrapolateLeft || this._config.extrapolate || 'extend',
|
||||
extrapolateRight:
|
||||
this._config.extrapolateRight || this._config.extrapolate || 'extend',
|
||||
type: 'interpolation',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import AnimatedInterpolation from './AnimatedInterpolation';
|
||||
import AnimatedNode from './AnimatedNode';
|
||||
import AnimatedWithChildren from './AnimatedWithChildren';
|
||||
|
||||
import type { InterpolationConfigType } from './AnimatedInterpolation';
|
||||
import type {InterpolationConfigType} from './AnimatedInterpolation';
|
||||
|
||||
class AnimatedModulo extends AnimatedWithChildren {
|
||||
_a: AnimatedNode;
|
||||
@@ -31,7 +31,9 @@ class AnimatedModulo extends AnimatedWithChildren {
|
||||
}
|
||||
|
||||
__getValue(): number {
|
||||
return (this._a.__getValue() % this._modulus + this._modulus) % this._modulus;
|
||||
return (
|
||||
(this._a.__getValue() % this._modulus + this._modulus) % this._modulus
|
||||
);
|
||||
}
|
||||
|
||||
interpolate(config: InterpolationConfigType): AnimatedInterpolation {
|
||||
@@ -51,7 +53,7 @@ class AnimatedModulo extends AnimatedWithChildren {
|
||||
return {
|
||||
type: 'modulus',
|
||||
input: this._a.__getNativeTag(),
|
||||
modulus: this._modulus
|
||||
modulus: this._modulus,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import AnimatedNode from './AnimatedNode';
|
||||
import AnimatedValue from './AnimatedValue';
|
||||
import AnimatedWithChildren from './AnimatedWithChildren';
|
||||
|
||||
import type { InterpolationConfigType } from './AnimatedInterpolation';
|
||||
import type {InterpolationConfigType} from './AnimatedInterpolation';
|
||||
|
||||
class AnimatedMultiplication extends AnimatedWithChildren {
|
||||
_a: AnimatedNode;
|
||||
@@ -54,7 +54,7 @@ class AnimatedMultiplication extends AnimatedWithChildren {
|
||||
__getNativeConfig(): any {
|
||||
return {
|
||||
type: 'multiplication',
|
||||
input: [this._a.__getNativeTag(), this._b.__getNativeTag()]
|
||||
input: [this._a.__getNativeTag(), this._b.__getNativeTag()],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,16 +43,24 @@ class AnimatedNode {
|
||||
}
|
||||
__getNativeTag(): ?number {
|
||||
NativeAnimatedHelper.assertNativeAnimatedModule();
|
||||
invariant(this.__isNative, 'Attempt to get native tag from node not marked as "native"');
|
||||
invariant(
|
||||
this.__isNative,
|
||||
'Attempt to get native tag from node not marked as "native"',
|
||||
);
|
||||
if (this.__nativeTag == null) {
|
||||
const nativeTag: ?number = NativeAnimatedHelper.generateNewNodeTag();
|
||||
NativeAnimatedHelper.API.createAnimatedNode(nativeTag, this.__getNativeConfig());
|
||||
NativeAnimatedHelper.API.createAnimatedNode(
|
||||
nativeTag,
|
||||
this.__getNativeConfig(),
|
||||
);
|
||||
this.__nativeTag = nativeTag;
|
||||
}
|
||||
return this.__nativeTag;
|
||||
}
|
||||
__getNativeConfig(): Object {
|
||||
throw new Error('This JS animated node type cannot be used as native animated node');
|
||||
throw new Error(
|
||||
'This JS animated node type cannot be used as native animated node',
|
||||
);
|
||||
}
|
||||
toJSON(): any {
|
||||
return this.__getValue();
|
||||
|
||||
@@ -27,7 +27,7 @@ class AnimatedProps extends AnimatedNode {
|
||||
if (props.style) {
|
||||
props = {
|
||||
...props,
|
||||
style: new AnimatedStyle(props.style)
|
||||
style: new AnimatedStyle(props.style),
|
||||
};
|
||||
}
|
||||
this._props = props;
|
||||
@@ -118,16 +118,32 @@ class AnimatedProps extends AnimatedNode {
|
||||
|
||||
__connectAnimatedView(): void {
|
||||
invariant(this.__isNative, 'Expected node to be marked as "native"');
|
||||
const nativeViewTag: ?number = findNodeHandle(this._animatedView);
|
||||
invariant(nativeViewTag != null, 'Unable to locate attached view in the native tree');
|
||||
NativeAnimatedHelper.API.connectAnimatedNodeToView(this.__getNativeTag(), nativeViewTag);
|
||||
const nativeViewTag: ?number = findNodeHandle(
|
||||
this._animatedView,
|
||||
);
|
||||
invariant(
|
||||
nativeViewTag != null,
|
||||
'Unable to locate attached view in the native tree',
|
||||
);
|
||||
NativeAnimatedHelper.API.connectAnimatedNodeToView(
|
||||
this.__getNativeTag(),
|
||||
nativeViewTag,
|
||||
);
|
||||
}
|
||||
|
||||
__disconnectAnimatedView(): void {
|
||||
invariant(this.__isNative, 'Expected node to be marked as "native"');
|
||||
const nativeViewTag: ?number = findNodeHandle(this._animatedView);
|
||||
invariant(nativeViewTag != null, 'Unable to locate attached view in the native tree');
|
||||
NativeAnimatedHelper.API.disconnectAnimatedNodeFromView(this.__getNativeTag(), nativeViewTag);
|
||||
const nativeViewTag: ?number = findNodeHandle(
|
||||
this._animatedView,
|
||||
);
|
||||
invariant(
|
||||
nativeViewTag != null,
|
||||
'Unable to locate attached view in the native tree',
|
||||
);
|
||||
NativeAnimatedHelper.API.disconnectAnimatedNodeFromView(
|
||||
this.__getNativeTag(),
|
||||
nativeViewTag,
|
||||
);
|
||||
}
|
||||
|
||||
__getNativeConfig(): Object {
|
||||
@@ -140,7 +156,7 @@ class AnimatedProps extends AnimatedNode {
|
||||
}
|
||||
return {
|
||||
type: 'props',
|
||||
props: propsConfig
|
||||
props: propsConfig,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @noflow
|
||||
* @format
|
||||
*/
|
||||
'use strict';
|
||||
@@ -26,14 +26,14 @@ class AnimatedStyle extends AnimatedWithChildren {
|
||||
if (style.transform) {
|
||||
style = {
|
||||
...style,
|
||||
transform: new AnimatedTransform(style.transform)
|
||||
transform: new AnimatedTransform(style.transform),
|
||||
};
|
||||
}
|
||||
this._style = style;
|
||||
}
|
||||
|
||||
// Recursively get values for nested styles (like iOS's shadowOffset)
|
||||
_walkStyleAndGetValues(style: Object) {
|
||||
_walkStyleAndGetValues(style) {
|
||||
const updatedStyle = {};
|
||||
for (const key in style) {
|
||||
const value = style[key];
|
||||
@@ -58,7 +58,7 @@ class AnimatedStyle extends AnimatedWithChildren {
|
||||
}
|
||||
|
||||
// Recursively get animated values for nested styles (like iOS's shadowOffset)
|
||||
_walkStyleAndGetAnimatedValues(style: Object) {
|
||||
_walkStyleAndGetAnimatedValues(style) {
|
||||
const updatedStyle = {};
|
||||
for (const key in style) {
|
||||
const value = style[key];
|
||||
@@ -117,7 +117,7 @@ class AnimatedStyle extends AnimatedWithChildren {
|
||||
NativeAnimatedHelper.validateStyles(styleConfig);
|
||||
return {
|
||||
type: 'style',
|
||||
style: styleConfig
|
||||
style: styleConfig,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,12 @@
|
||||
|
||||
import AnimatedValue from './AnimatedValue';
|
||||
import AnimatedNode from './AnimatedNode';
|
||||
import {
|
||||
generateNewAnimationId,
|
||||
shouldUseNativeDriver,
|
||||
} from '../NativeAnimatedHelper';
|
||||
|
||||
import type { EndCallback } from '../animations/Animation';
|
||||
import type {EndCallback} from '../animations/Animation';
|
||||
|
||||
class AnimatedTracking extends AnimatedNode {
|
||||
_value: AnimatedValue;
|
||||
@@ -20,29 +24,46 @@ class AnimatedTracking extends AnimatedNode {
|
||||
_callback: ?EndCallback;
|
||||
_animationConfig: Object;
|
||||
_animationClass: any;
|
||||
_useNativeDriver: boolean;
|
||||
|
||||
constructor(
|
||||
value: AnimatedValue,
|
||||
parent: AnimatedNode,
|
||||
animationClass: any,
|
||||
animationConfig: Object,
|
||||
callback?: ?EndCallback
|
||||
callback?: ?EndCallback,
|
||||
) {
|
||||
super();
|
||||
this._value = value;
|
||||
this._parent = parent;
|
||||
this._animationClass = animationClass;
|
||||
this._animationConfig = animationConfig;
|
||||
this._useNativeDriver = shouldUseNativeDriver(animationConfig);
|
||||
this._callback = callback;
|
||||
this.__attach();
|
||||
}
|
||||
|
||||
__makeNative() {
|
||||
this.__isNative = true;
|
||||
this._parent.__makeNative();
|
||||
super.__makeNative();
|
||||
this._value.__makeNative();
|
||||
}
|
||||
|
||||
__getValue(): Object {
|
||||
return this._parent.__getValue();
|
||||
}
|
||||
|
||||
__attach(): void {
|
||||
this._parent.__addChild(this);
|
||||
if (this._useNativeDriver) {
|
||||
// when the tracking starts we need to convert this node to a "native node"
|
||||
// so that the parent node will be made "native" too. This is necessary as
|
||||
// if we don't do this `update` method will get called. At that point it
|
||||
// may be too late as it would mean the JS driver has already started
|
||||
// updating node values
|
||||
this.__makeNative();
|
||||
}
|
||||
}
|
||||
|
||||
__detach(): void {
|
||||
@@ -54,11 +75,27 @@ class AnimatedTracking extends AnimatedNode {
|
||||
this._value.animate(
|
||||
new this._animationClass({
|
||||
...this._animationConfig,
|
||||
toValue: (this._animationConfig.toValue: any).__getValue()
|
||||
toValue: (this._animationConfig.toValue: any).__getValue(),
|
||||
}),
|
||||
this._callback
|
||||
this._callback,
|
||||
);
|
||||
}
|
||||
|
||||
__getNativeConfig(): any {
|
||||
const animation = new this._animationClass({
|
||||
...this._animationConfig,
|
||||
// remove toValue from the config as it's a ref to Animated.Value
|
||||
toValue: undefined,
|
||||
});
|
||||
const animationConfig = animation.__getNativeAnimationConfig();
|
||||
return {
|
||||
type: 'tracking',
|
||||
animationId: generateNewAnimationId(),
|
||||
animationConfig,
|
||||
toValue: this._parent.__getNativeTag(),
|
||||
value: this._value.__getNativeTag(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default AnimatedTracking;
|
||||
|
||||
@@ -14,9 +14,9 @@ import AnimatedWithChildren from './AnimatedWithChildren';
|
||||
import NativeAnimatedHelper from '../NativeAnimatedHelper';
|
||||
|
||||
class AnimatedTransform extends AnimatedWithChildren {
|
||||
_transforms: Array<Object>;
|
||||
_transforms: $ReadOnlyArray<Object>;
|
||||
|
||||
constructor(transforms: Array<Object>) {
|
||||
constructor(transforms: $ReadOnlyArray<Object>) {
|
||||
super();
|
||||
this._transforms = transforms;
|
||||
}
|
||||
@@ -33,7 +33,7 @@ class AnimatedTransform extends AnimatedWithChildren {
|
||||
});
|
||||
}
|
||||
|
||||
__getValue(): Array<Object> {
|
||||
__getValue(): $ReadOnlyArray<Object> {
|
||||
return this._transforms.map(transform => {
|
||||
const result = {};
|
||||
for (const key in transform) {
|
||||
@@ -48,7 +48,7 @@ class AnimatedTransform extends AnimatedWithChildren {
|
||||
});
|
||||
}
|
||||
|
||||
__getAnimatedValue(): Array<Object> {
|
||||
__getAnimatedValue(): $ReadOnlyArray<Object> {
|
||||
return this._transforms.map(transform => {
|
||||
const result = {};
|
||||
for (const key in transform) {
|
||||
@@ -97,13 +97,13 @@ class AnimatedTransform extends AnimatedWithChildren {
|
||||
transConfigs.push({
|
||||
type: 'animated',
|
||||
property: key,
|
||||
nodeTag: value.__getNativeTag()
|
||||
nodeTag: value.__getNativeTag(),
|
||||
});
|
||||
} else {
|
||||
transConfigs.push({
|
||||
type: 'static',
|
||||
property: key,
|
||||
value
|
||||
value,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -112,7 +112,7 @@ class AnimatedTransform extends AnimatedWithChildren {
|
||||
NativeAnimatedHelper.validateTransform(transConfigs);
|
||||
return {
|
||||
type: 'transform',
|
||||
transforms: transConfigs
|
||||
transforms: transConfigs,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,12 +15,13 @@ import AnimatedWithChildren from './AnimatedWithChildren';
|
||||
import InteractionManager from '../../../../exports/InteractionManager';
|
||||
import NativeAnimatedHelper from '../NativeAnimatedHelper';
|
||||
|
||||
import type Animation, { EndCallback } from '../animations/Animation';
|
||||
import type { InterpolationConfigType } from './AnimatedInterpolation';
|
||||
import type Animation, {EndCallback} from '../animations/Animation';
|
||||
import type {InterpolationConfigType} from './AnimatedInterpolation';
|
||||
import type AnimatedTracking from './AnimatedTracking';
|
||||
|
||||
const NativeAnimatedAPI = NativeAnimatedHelper.API;
|
||||
|
||||
type ValueListenerCallback = (state: { value: number }) => void;
|
||||
type ValueListenerCallback = (state: {value: number}) => void;
|
||||
|
||||
let _uniqueId = 1;
|
||||
|
||||
@@ -73,8 +74,8 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
_startingValue: number;
|
||||
_offset: number;
|
||||
_animation: ?Animation;
|
||||
_tracking: ?AnimatedNode;
|
||||
_listeners: { [key: string]: ValueListenerCallback };
|
||||
_tracking: ?AnimatedTracking;
|
||||
_listeners: {[key: string]: ValueListenerCallback};
|
||||
__nativeAnimatedValueListener: ?any;
|
||||
|
||||
constructor(value: number) {
|
||||
@@ -115,7 +116,7 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
}
|
||||
this._updateValue(
|
||||
value,
|
||||
!this.__isNative /* don't perform a flush for natively driven values */
|
||||
!this.__isNative /* don't perform a flush for natively driven values */,
|
||||
);
|
||||
if (this.__isNative) {
|
||||
NativeAnimatedAPI.setAnimatedNodeValue(this.__getNativeTag(), value);
|
||||
@@ -218,7 +219,7 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
return;
|
||||
}
|
||||
this._updateValue(data.value, false /* flush */);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -293,7 +294,7 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
callback && callback(result);
|
||||
},
|
||||
previousAnimation,
|
||||
this
|
||||
this,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -308,7 +309,7 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
/**
|
||||
* Typically only used internally.
|
||||
*/
|
||||
track(tracking: AnimatedNode): void {
|
||||
track(tracking: AnimatedTracking): void {
|
||||
this.stopTracking();
|
||||
this._tracking = tracking;
|
||||
}
|
||||
@@ -319,7 +320,7 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
_flush(this);
|
||||
}
|
||||
for (const key in this._listeners) {
|
||||
this._listeners[key]({ value: this.__getValue() });
|
||||
this._listeners[key]({value: this.__getValue()});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,7 +328,7 @@ class AnimatedValue extends AnimatedWithChildren {
|
||||
return {
|
||||
type: 'value',
|
||||
value: this._value,
|
||||
offset: this._offset
|
||||
offset: this._offset,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import AnimatedWithChildren from './AnimatedWithChildren';
|
||||
|
||||
import invariant from 'fbjs/lib/invariant';
|
||||
|
||||
type ValueXYListenerCallback = (value: { x: number, y: number }) => void;
|
||||
type ValueXYListenerCallback = (value: {x: number, y: number}) => void;
|
||||
|
||||
let _uniqueId = 1;
|
||||
|
||||
@@ -27,18 +27,21 @@ let _uniqueId = 1;
|
||||
class AnimatedValueXY extends AnimatedWithChildren {
|
||||
x: AnimatedValue;
|
||||
y: AnimatedValue;
|
||||
_listeners: { [key: string]: { x: string, y: string } };
|
||||
_listeners: {[key: string]: {x: string, y: string}};
|
||||
|
||||
constructor(valueIn?: ?{ x: number | AnimatedValue, y: number | AnimatedValue }) {
|
||||
constructor(
|
||||
valueIn?: ?{+x: number | AnimatedValue, +y: number | AnimatedValue},
|
||||
) {
|
||||
super();
|
||||
const value: any = valueIn || { x: 0, y: 0 }; // @flowfixme: shouldn't need `: any`
|
||||
const value: any = valueIn || {x: 0, y: 0}; // @flowfixme: shouldn't need `: any`
|
||||
if (typeof value.x === 'number' && typeof value.y === 'number') {
|
||||
this.x = new AnimatedValue(value.x);
|
||||
this.y = new AnimatedValue(value.y);
|
||||
} else {
|
||||
invariant(
|
||||
value.x instanceof AnimatedValue && value.y instanceof AnimatedValue,
|
||||
'AnimatedValueXY must be initalized with an object of numbers or ' + 'AnimatedValues.'
|
||||
'AnimatedValueXY must be initialized with an object of numbers or ' +
|
||||
'AnimatedValues.',
|
||||
);
|
||||
this.x = value.x;
|
||||
this.y = value.y;
|
||||
@@ -52,7 +55,7 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#setvalue
|
||||
*/
|
||||
setValue(value: { x: number, y: number }) {
|
||||
setValue(value: {x: number, y: number}) {
|
||||
this.x.setValue(value.x);
|
||||
this.y.setValue(value.y);
|
||||
}
|
||||
@@ -64,7 +67,7 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#setoffset
|
||||
*/
|
||||
setOffset(offset: { x: number, y: number }) {
|
||||
setOffset(offset: {x: number, y: number}) {
|
||||
this.x.setOffset(offset.x);
|
||||
this.y.setOffset(offset.y);
|
||||
}
|
||||
@@ -91,10 +94,10 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
this.y.extractOffset();
|
||||
}
|
||||
|
||||
__getValue(): { x: number, y: number } {
|
||||
__getValue(): {x: number, y: number} {
|
||||
return {
|
||||
x: this.x.__getValue(),
|
||||
y: this.y.__getValue()
|
||||
y: this.y.__getValue(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -103,7 +106,7 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#resetanimation
|
||||
*/
|
||||
resetAnimation(callback?: (value: { x: number, y: number }) => void): void {
|
||||
resetAnimation(callback?: (value: {x: number, y: number}) => void): void {
|
||||
this.x.resetAnimation();
|
||||
this.y.resetAnimation();
|
||||
callback && callback(this.__getValue());
|
||||
@@ -116,7 +119,7 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#stopanimation
|
||||
*/
|
||||
stopAnimation(callback?: (value: { x: number, y: number }) => void): void {
|
||||
stopAnimation(callback?: (value: {x: number, y: number}) => void): void {
|
||||
this.x.stopAnimation();
|
||||
this.y.stopAnimation();
|
||||
callback && callback(this.__getValue());
|
||||
@@ -133,12 +136,12 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
*/
|
||||
addListener(callback: ValueXYListenerCallback): string {
|
||||
const id = String(_uniqueId++);
|
||||
const jointCallback = ({ value: number }) => {
|
||||
const jointCallback = ({value: number}) => {
|
||||
callback(this.__getValue());
|
||||
};
|
||||
this._listeners[id] = {
|
||||
x: this.x.addListener(jointCallback),
|
||||
y: this.y.addListener(jointCallback)
|
||||
y: this.y.addListener(jointCallback),
|
||||
};
|
||||
return id;
|
||||
}
|
||||
@@ -171,10 +174,10 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#getlayout
|
||||
*/
|
||||
getLayout(): { [key: string]: AnimatedValue } {
|
||||
getLayout(): {[key: string]: AnimatedValue} {
|
||||
return {
|
||||
left: this.x,
|
||||
top: this.y
|
||||
top: this.y,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -183,8 +186,8 @@ class AnimatedValueXY extends AnimatedWithChildren {
|
||||
*
|
||||
* See http://facebook.github.io/react-native/docs/animatedvaluexy.html#gettranslatetransform
|
||||
*/
|
||||
getTranslateTransform(): Array<{ [key: string]: AnimatedValue }> {
|
||||
return [{ translateX: this.x }, { translateY: this.y }];
|
||||
getTranslateTransform(): Array<{[key: string]: AnimatedValue}> {
|
||||
return [{translateX: this.x}, {translateY: this.y}];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ class AnimatedWithChildren extends AnimatedNode {
|
||||
child.__makeNative();
|
||||
NativeAnimatedHelper.API.connectAnimatedNodes(
|
||||
this.__getNativeTag(),
|
||||
child.__getNativeTag()
|
||||
child.__getNativeTag(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,10 @@ class AnimatedWithChildren extends AnimatedNode {
|
||||
if (this.__isNative) {
|
||||
// Only accept "native" animated nodes as children
|
||||
child.__makeNative();
|
||||
NativeAnimatedHelper.API.connectAnimatedNodes(this.__getNativeTag(), child.__getNativeTag());
|
||||
NativeAnimatedHelper.API.connectAnimatedNodes(
|
||||
this.__getNativeTag(),
|
||||
child.__getNativeTag(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +57,7 @@ class AnimatedWithChildren extends AnimatedNode {
|
||||
if (this.__isNative && child.__isNative) {
|
||||
NativeAnimatedHelper.API.disconnectAnimatedNodes(
|
||||
this.__getNativeTag(),
|
||||
child.__getNativeTag()
|
||||
child.__getNativeTag(),
|
||||
);
|
||||
}
|
||||
this._children.splice(index, 1);
|
||||
|
||||
13
packages/react-native-web/src/vendor/react-native/Animated/polyfills/InteractionManager.js
vendored
Normal file
13
packages/react-native-web/src/vendor/react-native/Animated/polyfills/InteractionManager.js
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
createInteractionHandle: function() {},
|
||||
clearInteractionHandle: function() {}
|
||||
};
|
||||
24
packages/react-native-web/src/vendor/react-native/Animated/polyfills/Set.js
vendored
Normal file
24
packages/react-native-web/src/vendor/react-native/Animated/polyfills/Set.js
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
function SetPolyfill() {
|
||||
this._cache = [];
|
||||
}
|
||||
|
||||
SetPolyfill.prototype.add = function(e) {
|
||||
if (this._cache.indexOf(e) === -1) {
|
||||
this._cache.push(e);
|
||||
}
|
||||
};
|
||||
|
||||
SetPolyfill.prototype.forEach = function(cb) {
|
||||
this._cache.forEach(cb);
|
||||
};
|
||||
|
||||
module.exports = SetPolyfill;
|
||||
10
packages/react-native-web/src/vendor/react-native/Animated/polyfills/flattenStyle.js
vendored
Normal file
10
packages/react-native-web/src/vendor/react-native/Animated/polyfills/flattenStyle.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
'use strict';
|
||||
module.exports = function(style) {
|
||||
return style;
|
||||
};
|
||||
Reference in New Issue
Block a user