Created
November 15, 2016 00:50
-
-
Save dabbott/8335f232c8c90ef056ac5912e6cd4b38 to your computer and use it in GitHub Desktop.
react-native-animatable
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
Object.defineProperty(exports, "__esModule", { | |
value: true | |
}); | |
exports.Image = exports.Text = exports.View = undefined; | |
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | |
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | |
exports.createAnimatableComponent = createAnimatableComponent; | |
var _react = require('react'); | |
var _react2 = _interopRequireDefault(_react); | |
var _reactNative = require('react-native'); | |
var _reactNative2 = _interopRequireDefault(_reactNative); | |
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | |
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | |
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | |
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | |
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | |
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | |
// Transform an object to an array the way react native wants it for transform styles | |
// { a: x, b: y } => [{ a: x }, { b: y }] | |
function createKeyedArray(obj) { | |
return Object.keys(obj).map(function (key) { | |
var keyed = {}; | |
keyed[key] = obj[key]; | |
return keyed; | |
}); | |
} | |
// Helper function to calculate transform values, args: | |
// direction: in|out | |
// originOrDestination: up|down|left|right | |
// verticalValue: amplitude for up/down animations | |
// horizontalValue: amplitude for left/right animations | |
function getAnimationValueForDirection(direction, originOrDestination, verticalValue, horizontalValue) { | |
var isVertical = originOrDestination === 'up' || originOrDestination === 'down'; | |
var modifier = (isVertical && direction === 'out' ? -1 : 1) * (originOrDestination === 'down' || originOrDestination === 'left' ? -1 : 1); | |
return modifier * (isVertical ? verticalValue : horizontalValue); | |
} | |
// Animations starting with these keywords use element dimensions | |
// thus, any animation needs to be deferred until the element is measured | |
var LAYOUT_DEPENDENT_ANIMATIONS = ['slide', 'fade', 'wobble', 'lightSpeed']; | |
// These styles need to be nested in a transform array | |
var TRANSFORM_STYLE_PROPERTIES = ['rotate', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scaleX', 'scaleY', 'translateX', 'translateY', 'skewX', 'skewY']; | |
// These styles are not number based and thus needs to be interpolated | |
var INTERPOLATION_STYLE_PROPERTIES = [ | |
// Transform styles | |
'rotate', 'rotateX', 'rotateY', 'rotateZ', 'skewX', 'skewY', 'transformMatrix', | |
// View styles | |
'backgroundColor', 'borderColor', 'borderTopColor', 'borderRightColor', 'borderBottomColor', 'borderLeftColor', 'shadowColor', | |
// Text styles | |
'color', 'textDecorationColor']; | |
var EASING_FUNCTIONS = { | |
'linear': _reactNative.Easing.linear, | |
'ease': _reactNative.Easing.ease, | |
'ease-in': _reactNative.Easing.in(_reactNative.Easing.ease), | |
'ease-out': _reactNative.Easing.out(_reactNative.Easing.ease), | |
'ease-in-out': _reactNative.Easing.inOut(_reactNative.Easing.ease) | |
}; | |
// Transforms { translateX: 1 } to { transform: [{ translateX: 1 }]} | |
function wrapStyleTransforms(style) { | |
var wrapped = {}; | |
Object.keys(style).forEach(function (key) { | |
if (TRANSFORM_STYLE_PROPERTIES.indexOf(key) !== -1) { | |
if (!wrapped.transform) { | |
wrapped.transform = []; | |
} | |
wrapped.transform.push(_defineProperty({}, key, style[key])); | |
} else { | |
wrapped[key] = style[key]; | |
} | |
}); | |
return wrapped; | |
} | |
// Determine to what value the animation should tween to | |
function getAnimationTarget(iteration, direction) { | |
switch (direction) { | |
case 'reverse': | |
return 0; | |
case 'alternate': | |
return iteration % 2 ? 0 : 1; | |
case 'alternate-reverse': | |
return iteration % 2 ? 1 : 0; | |
case 'normal': | |
default: | |
return 1; | |
} | |
} | |
// Like getAnimationTarget but opposite | |
function getAnimationOrigin(iteration, direction) { | |
return getAnimationTarget(iteration, direction) ? 0 : 1; | |
} | |
function getDefaultStyleValue(key) { | |
if (key === 'backgroundColor') { | |
return 'rgba(0,0,0,0)'; | |
} | |
if (key === 'color' || key.indexOf('Color') !== -1) { | |
return 'rgba(0,0,0,1)'; | |
} | |
if (key.indexOf('rotate') !== -1 || key.indexOf('skew') !== -1) { | |
return '0deg'; | |
} | |
if (key === 'fontSize') { | |
return 14; | |
} | |
if (key === 'opacity') { | |
return 1; | |
} | |
return 0; | |
} | |
// Returns a flattened version of style with only `keys` values. | |
function getStyleValues(keys, style) { | |
if (!_reactNative.StyleSheet.flatten) { | |
throw new Error('StyleSheet.flatten not available, upgrade React Native or polyfill with StyleSheet.flatten = require(\'flattenStyle\');'); | |
} | |
var values = {}; | |
var flatStyle = Object.assign({}, _reactNative.StyleSheet.flatten(style)); | |
if (flatStyle.transform) { | |
flatStyle.transform.forEach(function (transform) { | |
var key = Object.keys(transform)[0]; | |
flatStyle[key] = transform[key]; | |
}); | |
delete flatStyle.transform; | |
} | |
(typeof keys === 'string' ? [keys] : keys).forEach(function (key) { | |
values[key] = key in flatStyle ? flatStyle[key] : getDefaultStyleValue(key); | |
}); | |
return values; | |
} | |
// Make (almost) any component animatable, similar to Animated.createAnimatedComponent | |
function createAnimatableComponent(component) { | |
var _class, _temp; | |
var Animatable = _reactNative.Animated.createAnimatedComponent(component); | |
return _temp = _class = function (_Component) { | |
_inherits(AnimatableComponent, _Component); | |
function AnimatableComponent(props) { | |
_classCallCheck(this, AnimatableComponent); | |
var _this = _possibleConstructorReturn(this, (AnimatableComponent.__proto__ || Object.getPrototypeOf(AnimatableComponent)).call(this, props)); | |
_this.state = { | |
animationValue: new _reactNative.Animated.Value(getAnimationOrigin(0, _this.props.direction)), | |
animationStyle: {}, | |
transitionStyle: {}, | |
transitionValues: {}, | |
currentTransitionValues: {} | |
}; | |
if (props.transition) { | |
_this.state = _extends({}, _this.state, _this.initializeTransitionState(props.transition)); | |
} | |
return _this; | |
} | |
_createClass(AnimatableComponent, [{ | |
key: 'initializeTransitionState', | |
value: function initializeTransitionState(transitionKeys) { | |
var transitionValues = {}; | |
var styleValues = {}; | |
var currentTransitionValues = getStyleValues(transitionKeys, this.props.style); | |
Object.keys(currentTransitionValues).forEach(function (key) { | |
var value = currentTransitionValues[key]; | |
if (INTERPOLATION_STYLE_PROPERTIES.indexOf(key) !== -1) { | |
transitionValues[key] = new _reactNative.Animated.Value(0); | |
styleValues[key] = value; | |
} else { | |
transitionValues[key] = styleValues[key] = new _reactNative.Animated.Value(value); | |
} | |
}); | |
return { | |
transitionStyle: styleValues, | |
transitionValues: transitionValues, | |
currentTransitionValues: currentTransitionValues | |
}; | |
} | |
}, { | |
key: 'getTransitionState', | |
value: function getTransitionState(keys) { | |
var _this2 = this; | |
var transitionKeys = typeof transitionKeys === 'string' ? [keys] : keys; | |
var _state = this.state, | |
transitionValues = _state.transitionValues, | |
currentTransitionValues = _state.currentTransitionValues, | |
transitionStyle = _state.transitionStyle; | |
var missingKeys = transitionKeys.filter(function (key) { | |
return !_this2.state.transitionValues[key]; | |
}); | |
if (missingKeys.length) { | |
var transitionState = this.initializeTransitionState(missingKeys); | |
transitionValues = _extends({}, transitionValues, transitionState.transitionValues); | |
currentTransitionValues = _extends({}, currentTransitionValues, transitionState.currentTransitionValues); | |
transitionStyle = _extends({}, transitionStyle, transitionState.transitionStyle); | |
} | |
return { transitionValues: transitionValues, currentTransitionValues: currentTransitionValues, transitionStyle: transitionStyle }; | |
} | |
}, { | |
key: 'setNativeProps', | |
value: function setNativeProps(nativeProps) { | |
if (this._root) { | |
this._root.setNativeProps(nativeProps); | |
} | |
} | |
}, { | |
key: 'componentDidMount', | |
value: function componentDidMount() { | |
var _this3 = this; | |
var _props = this.props, | |
animation = _props.animation, | |
duration = _props.duration, | |
delay = _props.delay, | |
onAnimationBegin = _props.onAnimationBegin, | |
onAnimationEnd = _props.onAnimationEnd; | |
if (animation) { | |
if (delay) { | |
this.setState({ scheduledAnimation: animation }); | |
this._timer = setTimeout(function () { | |
onAnimationBegin(); | |
_this3.setState({ scheduledAnimation: false }, function () { | |
return _this3[animation](duration).then(onAnimationEnd); | |
}); | |
_this3._timer = false; | |
}, delay); | |
return; | |
} | |
if (!this._layout) { | |
for (var i = LAYOUT_DEPENDENT_ANIMATIONS.length - 1; i >= 0; i--) { | |
if (animation.indexOf(LAYOUT_DEPENDENT_ANIMATIONS[i]) === 0) { | |
this.setState({ scheduledAnimation: animation }); | |
return; | |
} | |
} | |
} | |
onAnimationBegin(); | |
this[animation](duration).then(onAnimationEnd); | |
} | |
} | |
}, { | |
key: 'componentWillUnmount', | |
value: function componentWillUnmount() { | |
if (this._timer) { | |
clearTimeout(this._timer); | |
} | |
} | |
}, { | |
key: 'componentWillReceiveProps', | |
value: function componentWillReceiveProps(props) { | |
var animation = props.animation, | |
duration = props.duration, | |
easing = props.easing, | |
transition = props.transition, | |
onAnimationBegin = props.onAnimationBegin, | |
onAnimationEnd = props.onAnimationEnd; | |
if (transition) { | |
var values = getStyleValues(transition, props.style); | |
this.transitionTo(values, duration, easing); | |
} else if (animation !== this.props.animation) { | |
if (animation) { | |
if (this.state.scheduledAnimation) { | |
this.setState({ scheduledAnimation: animation }); | |
} else { | |
onAnimationBegin(); | |
this[animation](duration).then(onAnimationEnd); | |
} | |
} else { | |
this.stopAnimation(); | |
} | |
} | |
} | |
}, { | |
key: '_handleLayout', | |
value: function _handleLayout(event) { | |
var _this4 = this; | |
var _props2 = this.props, | |
duration = _props2.duration, | |
onLayout = _props2.onLayout, | |
onAnimationBegin = _props2.onAnimationBegin, | |
onAnimationEnd = _props2.onAnimationEnd; | |
var scheduledAnimation = this.state.scheduledAnimation; | |
this._layout = event.nativeEvent.layout; | |
if (onLayout) { | |
onLayout(event); | |
} | |
if (scheduledAnimation && !this._timer) { | |
onAnimationBegin(); | |
this.setState({ scheduledAnimation: false }, function () { | |
_this4[scheduledAnimation](duration).then(onAnimationEnd); | |
}); | |
} | |
} | |
}, { | |
key: 'animate', | |
value: function animate(duration, animationStyle) { | |
var _this5 = this; | |
return new Promise(function (resolve, reject) { | |
_this5.setState({ animationStyle: animationStyle }, function () { | |
_this5._startAnimation(duration, 0, resolve); | |
}); | |
}); | |
} | |
}, { | |
key: 'stopAnimation', | |
value: function stopAnimation() { | |
this.setState({ | |
scheduledAnimation: false, | |
animationStyle: {} | |
}); | |
this.state.animationValue.stopAnimation(); | |
if (this._timer) { | |
clearTimeout(this._timer); | |
this._timer = false; | |
} | |
} | |
}, { | |
key: '_startAnimation', | |
value: function _startAnimation(duration, iteration, callback) { | |
var _this6 = this; | |
var animationValue = this.state.animationValue; | |
var _props3 = this.props, | |
direction = _props3.direction, | |
iterationCount = _props3.iterationCount; | |
var easing = this.props.easing || 'ease-in-out'; | |
var currentIteration = iteration || 0; | |
var fromValue = getAnimationOrigin(currentIteration, direction); | |
var toValue = getAnimationTarget(currentIteration, direction); | |
animationValue.setValue(fromValue); | |
// This is on the way back reverse | |
if ((direction === 'reverse' || direction === 'alternate' && !toValue || direction === 'alternate-reverse' && !toValue) && easing.match(/^ease\-(in|out)$/)) { | |
if (easing.indexOf('-in') !== -1) { | |
easing = easing.replace('-in', '-out'); | |
} else { | |
easing = easing.replace('-out', '-in'); | |
} | |
} | |
_reactNative.Animated.timing(animationValue, { | |
toValue: toValue, | |
easing: EASING_FUNCTIONS[easing], | |
isInteraction: !iterationCount, | |
duration: duration || this.props.duration || 1000 | |
}).start(function (endState) { | |
currentIteration++; | |
if (endState.finished && _this6.props.animation && (iterationCount === 'infinite' || currentIteration < iterationCount)) { | |
_this6._startAnimation(duration, currentIteration, callback); | |
} else if (callback) { | |
callback(endState); | |
} | |
}); | |
} | |
}, { | |
key: 'transition', | |
value: function transition(fromValues, toValues, duration, easing) { | |
var _this7 = this; | |
var transitionKeys = Object.keys(toValues); | |
var _getTransitionState = this.getTransitionState(transitionKeys), | |
transitionValues = _getTransitionState.transitionValues, | |
currentTransitionValues = _getTransitionState.currentTransitionValues, | |
transitionStyle = _getTransitionState.transitionStyle; | |
transitionKeys.forEach(function (property) { | |
var fromValue = fromValues[property]; | |
var toValue = toValues[property]; | |
var transitionValue = transitionValues[property]; | |
if (!transitionValue) { | |
transitionValue = new _reactNative.Animated.Value(0); | |
} | |
transitionStyle[property] = transitionValue; | |
if (INTERPOLATION_STYLE_PROPERTIES.indexOf(property) !== -1) { | |
transitionValue.setValue(0); | |
transitionStyle[property] = transitionValue.interpolate({ | |
inputRange: [0, 1], | |
outputRange: [fromValue, toValue] | |
}); | |
currentTransitionValues[property] = toValue; | |
toValues[property] = 1; | |
} else { | |
transitionValue.setValue(fromValue); | |
} | |
}); | |
this.setState({ transitionValues: transitionValues, transitionStyle: transitionStyle, currentTransitionValues: currentTransitionValues }, function () { | |
_this7._transitionToValues(toValues, duration || _this7.props.duration, easing); | |
}); | |
} | |
}, { | |
key: 'transitionTo', | |
value: function transitionTo(toValues, duration, easing) { | |
var _this8 = this; | |
var currentTransitionValues = this.state.currentTransitionValues; | |
var transitions = { | |
from: {}, | |
to: {} | |
}; | |
Object.keys(toValues).forEach(function (property) { | |
var toValue = toValues[property]; | |
if (INTERPOLATION_STYLE_PROPERTIES.indexOf(property) === -1 && _this8.state.transitionStyle[property] && _this8.state.transitionStyle[property] === _this8.state.transitionValues[property]) { | |
return _this8._transitionToValue(_this8.state.transitionValues[property], toValue, duration, easing); | |
} | |
var currentTransitionValue = currentTransitionValues[property]; | |
if (typeof currentTransitionValue === 'undefined' && _this8.props.style) { | |
var style = getStyleValues(property, _this8.props.style); | |
currentTransitionValue = style[property]; | |
} | |
transitions.from[property] = currentTransitionValue; | |
transitions.to[property] = toValue; | |
}); | |
if (Object.keys(transitions.from).length) { | |
this.transition(transitions.from, transitions.to, duration, easing); | |
} | |
} | |
}, { | |
key: '_transitionToValues', | |
value: function _transitionToValues(toValues, duration, easing) { | |
var _this9 = this; | |
Object.keys(toValues).forEach(function (property) { | |
var transitionValue = _this9.state.transitionValues[property]; | |
var toValue = toValues[property]; | |
_this9._transitionToValue(transitionValue, toValue, duration, easing); | |
}); | |
} | |
}, { | |
key: '_transitionToValue', | |
value: function _transitionToValue(transitionValue, toValue, duration, easing) { | |
if (duration || easing) { | |
_reactNative.Animated.timing(transitionValue, { | |
toValue: toValue, | |
duration: duration || 1000, | |
easing: EASING_FUNCTIONS[easing || 'ease-in-out'] | |
}).start(); | |
} else { | |
_reactNative.Animated.spring(transitionValue, { | |
toValue: toValue | |
}).start(); | |
} | |
} | |
}, { | |
key: 'bounce', | |
value: function bounce(duration) { | |
return this.animate(duration, { | |
transform: [{ | |
translateY: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.2, 0.4, 0.43, 0.53, 0.7, 0.8, 0.9, 1], | |
outputRange: [0, 0, -30, -30, 0, -15, 0, -4, 0] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: 'flash', | |
value: function flash(duration) { | |
var times = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; | |
var inputRange = [0]; | |
var outputRange = [1]; | |
var totalTimes = times * 2; | |
for (var i = 1; i <= totalTimes; i++) { | |
inputRange.push(i / totalTimes); | |
outputRange.push(i % 2 ? 0 : 1); | |
} | |
return this.animate(duration, { | |
opacity: this.state.animationValue.interpolate({ | |
inputRange: inputRange, | |
outputRange: outputRange | |
}) | |
}); | |
} | |
}, { | |
key: 'jello', | |
value: function jello(duration) { | |
var skew = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 12.5; | |
var times = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 4; | |
var inputRange = [0]; | |
var outputRange = ['0 deg']; | |
var totalTimes = times * 2; | |
for (var i = 1; i < totalTimes; i++) { | |
inputRange.push(i / totalTimes); | |
outputRange.push(skew / i * (i % 2 ? -1 : 1) + ' deg'); | |
} | |
inputRange.push(1); | |
outputRange.push('0 deg'); | |
return this.animate(duration, { | |
transform: [{ | |
skewX: this.state.animationValue.interpolate({ inputRange: inputRange, outputRange: outputRange }) | |
}, { | |
skewY: this.state.animationValue.interpolate({ inputRange: inputRange, outputRange: outputRange }) | |
}] | |
}); | |
} | |
}, { | |
key: 'pulse', | |
value: function pulse(duration) { | |
return this.animate(duration, { | |
transform: [{ | |
scale: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.5, 1], | |
outputRange: [1, 1.05, 1] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: 'rotate', | |
value: function rotate(duration) { | |
return this.animate(duration, { | |
transform: [{ | |
rotate: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.25, 0.5, 0.75, 1], | |
outputRange: ['0 deg', '90 deg', '180 deg', '270 deg', '360 deg'] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: 'rubberBand', | |
value: function rubberBand(duration) { | |
return this.animate(duration, { | |
transform: [{ | |
scaleX: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.3, 0.4, 0.5, 0.65, 0.75, 1], | |
outputRange: [1, 1.25, 0.75, 1.15, 0.95, 1.05, 1] | |
}) | |
}, { | |
scaleY: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.3, 0.4, 0.5, 0.65, 0.75, 1], | |
outputRange: [1, 0.75, 1.25, 0.85, 1.05, 0.95, 1] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: 'shake', | |
value: function shake(duration) { | |
var distance = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10; | |
var times = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 5; | |
var inputRange = [0]; | |
var outputRange = [0]; | |
for (var i = 1; i <= times; i++) { | |
inputRange.push(i / times); | |
outputRange.push(i === times ? 0 : (i % 2 ? 1 : -1) * distance); | |
} | |
return this.animate(duration, { | |
transform: [{ | |
translateX: this.state.animationValue.interpolate({ | |
inputRange: inputRange, | |
outputRange: outputRange | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: 'swing', | |
value: function swing(duration) { | |
return this.animate(duration, { | |
transform: [{ | |
rotateZ: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.2, 0.4, 0.6, 0.8, 1], | |
outputRange: ['0 deg', '15 deg', '-10 deg', '5 deg', '-5 deg', '0 deg'] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: 'tada', | |
value: function tada(duration) { | |
return this.animate(duration, { | |
transform: [{ | |
scale: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.1, 0.2, 0.3, 0.9, 1], | |
outputRange: [1, 0.9, 0.9, 1.1, 1.1, 1] | |
}) | |
}, { | |
rotateZ: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1], | |
outputRange: ['0 deg', '-3 deg', '-3 deg', '3 deg', '-3 deg', '3 deg', '-3 deg', '3 deg', '-3 deg', '3 deg', '0 deg'] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: 'wobble', | |
value: function wobble(duration) { | |
var width = (this._layout || _reactNative.Dimensions.get('window')).width; | |
return this.animate(duration, { | |
transform: [{ | |
translateX: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.15, 0.3, 0.45, 0.6, 0.75, 1], | |
outputRange: [0, -0.25 * width, 0.2 * width, -0.15 * width, 0.1 * width, -0.05 * width, 1] | |
}) | |
}, { | |
rotateZ: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.15, 0.3, 0.45, 0.6, 0.75, 1], | |
outputRange: ['0 deg', '-5 deg', '3 deg', '-3 deg', '2 deg', '-1 deg', '0 deg'] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: '_bounce', | |
value: function _bounce(duration, direction, originOrDestination) { | |
var style = { | |
opacity: this.state.animationValue.interpolate({ | |
inputRange: direction === 'in' ? [0, 0.6, 1] : [0, 0.55, 1], | |
outputRange: direction === 'in' ? [0, 1, 1] : [1, 1, 0] | |
}) | |
}; | |
if (originOrDestination) { | |
style.transform = createKeyedArray(this._getBounceTransformation(direction, originOrDestination)); | |
} | |
return this.animate(duration, style); | |
} | |
}, { | |
key: '_getBounceTransformation', | |
value: function _getBounceTransformation(direction, originOrDestination) { | |
var windowSize = _reactNative.Dimensions.get('window'); | |
var animationValue = getAnimationValueForDirection(direction, originOrDestination, windowSize.height, windowSize.width); | |
var translateKey = originOrDestination === 'up' || originOrDestination === 'down' ? 'translateY' : 'translateX'; | |
var modifier = animationValue > 0 ? 1 : -1; | |
return _defineProperty({}, translateKey, this.state.animationValue.interpolate({ | |
inputRange: direction === 'in' ? [0, 0.6, 0.75, 0.9, 1] : [0, 0.2, 0.4, 0.45, 1], | |
outputRange: direction === 'in' ? [animationValue, 25 * modifier, -10 * modifier, 5 * modifier, 0] : [0, 10 * modifier, -20 * modifier, -20 * modifier, animationValue] | |
})); | |
} | |
}, { | |
key: 'bounceIn', | |
value: function bounceIn(duration) { | |
return this.animate(duration, { | |
opacity: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.6, 1], | |
outputRange: [0, 1, 1] | |
}), | |
transform: [{ | |
scale: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.2, 0.4, 0.6, 0.8, 1], | |
outputRange: [0.3, 1.1, 0.9, 1.03, 0.97, 1] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: 'bounceOut', | |
value: function bounceOut(duration) { | |
return this.animate(duration, { | |
opacity: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.55, 1], | |
outputRange: [1, 1, 0] | |
}), | |
transform: [{ | |
scale: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.2, 0.5, 0.55, 1], | |
outputRange: [1, 0.9, 1.1, 1.1, 0.3] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: 'bounceInDown', | |
value: function bounceInDown(duration) { | |
return this._bounce(duration, 'in', 'down'); | |
} | |
}, { | |
key: 'bounceInUp', | |
value: function bounceInUp(duration) { | |
return this._bounce(duration, 'in', 'up'); | |
} | |
}, { | |
key: 'bounceInLeft', | |
value: function bounceInLeft(duration) { | |
return this._bounce(duration, 'in', 'left'); | |
} | |
}, { | |
key: 'bounceInRight', | |
value: function bounceInRight(duration) { | |
return this._bounce(duration, 'in', 'right'); | |
} | |
}, { | |
key: 'bounceOutDown', | |
value: function bounceOutDown(duration) { | |
return this._bounce(duration, 'out', 'down'); | |
} | |
}, { | |
key: 'bounceOutUp', | |
value: function bounceOutUp(duration) { | |
return this._bounce(duration, 'out', 'up'); | |
} | |
}, { | |
key: 'bounceOutLeft', | |
value: function bounceOutLeft(duration) { | |
return this._bounce(duration, 'out', 'left'); | |
} | |
}, { | |
key: 'bounceOutRight', | |
value: function bounceOutRight(duration) { | |
return this._bounce(duration, 'out', 'right'); | |
} | |
}, { | |
key: 'flipInX', | |
value: function flipInX(duration) { | |
return this.animate(duration, { | |
opacity: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.6, 1], | |
outputRange: [0, 1, 1] | |
}), | |
transform: [{ | |
rotateX: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.4, 0.6, 0.8, 1], | |
outputRange: ['90 deg', '-20 deg', '10 deg', '-5 deg', '0 deg'] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: 'flipInY', | |
value: function flipInY(duration) { | |
return this.animate(duration, { | |
opacity: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.6, 1], | |
outputRange: [0, 1, 1] | |
}), | |
transform: [{ | |
rotateY: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.4, 0.6, 0.8, 1], | |
outputRange: ['90 deg', '-20 deg', '10 deg', '-5 deg', '0 deg'] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: 'flipOutX', | |
value: function flipOutX(duration) { | |
return this.animate(duration || 750, { | |
opacity: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.3, 1], | |
outputRange: [1, 1, 0] | |
}), | |
transform: [{ | |
rotateX: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.3, 1], | |
outputRange: ['0 deg', '-20 deg', '90 deg'] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: 'flipOutY', | |
value: function flipOutY(duration) { | |
return this.animate(duration || 750, { | |
opacity: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.3, 1], | |
outputRange: [1, 1, 0] | |
}), | |
transform: [{ | |
rotateY: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.3, 1], | |
outputRange: ['0 deg', '-20 deg', '90 deg'] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: 'lightSpeedIn', | |
value: function lightSpeedIn(duration) { | |
var width = (this._layout || _reactNative.Dimensions.get('window')).width; | |
return this.animate(duration, { | |
opacity: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.6, 1], | |
outputRange: [0, 1, 1] | |
}), | |
transform: [{ | |
translateX: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.6, 1], | |
outputRange: [width, 0, 0] | |
}) | |
}, { | |
skewX: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.6, 0.8, 1], | |
outputRange: ['-30 deg', '20 deg', '-5 deg', '0 deg'] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: 'lightSpeedOut', | |
value: function lightSpeedOut(duration) { | |
var width = (this._layout || _reactNative.Dimensions.get('window')).width; | |
return this.animate(duration, { | |
opacity: this.state.animationValue.interpolate({ | |
inputRange: [0, 1], | |
outputRange: [1, 0] | |
}), | |
transform: [{ | |
translateX: this.state.animationValue.interpolate({ | |
inputRange: [0, 1], | |
outputRange: [0, width] | |
}) | |
}, { | |
skewX: this.state.animationValue.interpolate({ | |
inputRange: [0, 1], | |
outputRange: ['0 deg', '30 deg'] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: '_fade', | |
value: function _fade(duration, direction, originOrDestination, isBig) { | |
var style = { | |
opacity: this.state.animationValue.interpolate({ | |
inputRange: [0, 1], | |
outputRange: direction === 'in' ? [0, 1] : [1, 0] | |
}) | |
}; | |
if (originOrDestination) { | |
style.transform = createKeyedArray(this._getSlideTransformation(direction, originOrDestination, isBig)); | |
} | |
return this.animate(duration, style); | |
} | |
}, { | |
key: 'fadeIn', | |
value: function fadeIn(duration) { | |
return this._fade(duration, 'in'); | |
} | |
}, { | |
key: 'fadeInDown', | |
value: function fadeInDown(duration) { | |
return this._fade(duration, 'in', 'down'); | |
} | |
}, { | |
key: 'fadeInUp', | |
value: function fadeInUp(duration) { | |
return this._fade(duration, 'in', 'up'); | |
} | |
}, { | |
key: 'fadeInLeft', | |
value: function fadeInLeft(duration) { | |
return this._fade(duration, 'in', 'left'); | |
} | |
}, { | |
key: 'fadeInRight', | |
value: function fadeInRight(duration) { | |
return this._fade(duration, 'in', 'right'); | |
} | |
}, { | |
key: 'fadeOut', | |
value: function fadeOut(duration) { | |
return this._fade(duration, 'out'); | |
} | |
}, { | |
key: 'fadeOutDown', | |
value: function fadeOutDown(duration) { | |
return this._fade(duration, 'out', 'down'); | |
} | |
}, { | |
key: 'fadeOutUp', | |
value: function fadeOutUp(duration) { | |
return this._fade(duration, 'out', 'up'); | |
} | |
}, { | |
key: 'fadeOutLeft', | |
value: function fadeOutLeft(duration) { | |
return this._fade(duration, 'out', 'left'); | |
} | |
}, { | |
key: 'fadeOutRight', | |
value: function fadeOutRight(duration) { | |
return this._fade(duration, 'out', 'right'); | |
} | |
}, { | |
key: 'fadeInDownBig', | |
value: function fadeInDownBig(duration) { | |
return this._fade(duration, 'in', 'down', true); | |
} | |
}, { | |
key: 'fadeInUpBig', | |
value: function fadeInUpBig(duration) { | |
return this._fade(duration, 'in', 'up', true); | |
} | |
}, { | |
key: 'fadeInLeftBig', | |
value: function fadeInLeftBig(duration) { | |
return this._fade(duration, 'in', 'left', true); | |
} | |
}, { | |
key: 'fadeInRightBig', | |
value: function fadeInRightBig(duration) { | |
return this._fade(duration, 'in', 'right', true); | |
} | |
}, { | |
key: 'fadeOutDownBig', | |
value: function fadeOutDownBig(duration) { | |
return this._fade(duration, 'out', 'down', true); | |
} | |
}, { | |
key: 'fadeOutUpBig', | |
value: function fadeOutUpBig(duration) { | |
return this._fade(duration, 'out', 'up', true); | |
} | |
}, { | |
key: 'fadeOutLeftBig', | |
value: function fadeOutLeftBig(duration) { | |
return this._fade(duration, 'out', 'left', true); | |
} | |
}, { | |
key: 'fadeOutRightBig', | |
value: function fadeOutRightBig(duration) { | |
return this._fade(duration, 'out', 'right', true); | |
} | |
}, { | |
key: '_getSlideTransformation', | |
value: function _getSlideTransformation(direction, originOrDestination, isBig) { | |
var size = isBig || !this._layout ? _reactNative.Dimensions.get('window') : this._layout; | |
var animationValue = getAnimationValueForDirection(direction, originOrDestination, size.height, size.width); | |
var translateKey = originOrDestination === 'up' || originOrDestination === 'down' ? 'translateY' : 'translateX'; | |
return _defineProperty({}, translateKey, this.state.animationValue.interpolate({ | |
inputRange: [0, 1], | |
outputRange: direction === 'in' ? [animationValue, 0] : [0, animationValue] | |
})); | |
} | |
}, { | |
key: '_slide', | |
value: function _slide(duration, direction, originOrDestination) { | |
return this.animate(duration, { | |
transform: createKeyedArray(this._getSlideTransformation(direction, originOrDestination)) | |
}); | |
} | |
}, { | |
key: 'slideInDown', | |
value: function slideInDown(duration) { | |
return this._slide(duration, 'in', 'down'); | |
} | |
}, { | |
key: 'slideInUp', | |
value: function slideInUp(duration) { | |
return this._slide(duration, 'in', 'up'); | |
} | |
}, { | |
key: 'slideInLeft', | |
value: function slideInLeft(duration) { | |
return this._slide(duration, 'in', 'left'); | |
} | |
}, { | |
key: 'slideInRight', | |
value: function slideInRight(duration) { | |
return this._slide(duration, 'in', 'right'); | |
} | |
}, { | |
key: 'slideOutDown', | |
value: function slideOutDown(duration) { | |
return this._slide(duration, 'out', 'down'); | |
} | |
}, { | |
key: 'slideOutUp', | |
value: function slideOutUp(duration) { | |
return this._slide(duration, 'out', 'up'); | |
} | |
}, { | |
key: 'slideOutLeft', | |
value: function slideOutLeft(duration) { | |
return this._slide(duration, 'out', 'left'); | |
} | |
}, { | |
key: 'slideOutRight', | |
value: function slideOutRight(duration) { | |
return this._slide(duration, 'out', 'right'); | |
} | |
}, { | |
key: '_zoom', | |
value: function _zoom(duration, direction, originOrDestination) { | |
var style = { | |
opacity: this.state.animationValue.interpolate({ | |
inputRange: direction === 'in' ? [0, 0.6, 1] : [0, 0.4, 1], | |
outputRange: direction === 'in' ? [0, 1, 1] : [1, 1, 0] | |
}) | |
}; | |
if (originOrDestination) { | |
style.transform = createKeyedArray(this._getZoomTransformation(direction, originOrDestination)); | |
} | |
return this.animate(duration, style); | |
} | |
}, { | |
key: '_getZoomTransformation', | |
value: function _getZoomTransformation(direction, originOrDestination) { | |
var windowSize = _reactNative.Dimensions.get('window'); | |
var animationValue = getAnimationValueForDirection(direction, originOrDestination, windowSize.height, windowSize.width); | |
var translateKey = originOrDestination === 'up' || originOrDestination === 'down' ? 'translateY' : 'translateX'; | |
var modifier = animationValue > 0 ? 1 : -1; | |
return _defineProperty({ | |
scale: this.state.animationValue.interpolate({ | |
inputRange: direction === 'in' ? [0, 0.6, 1] : [0, 0.4, 1], | |
outputRange: direction === 'in' ? [0.1, 0.457, 1] : [1, 0.457, 0.1] | |
}) | |
}, translateKey, this.state.animationValue.interpolate({ | |
inputRange: direction === 'in' ? [0, 0.6, 1] : [0, 0.4, 1], | |
outputRange: direction === 'in' ? [animationValue, -60 * modifier, 0] : [0, -60 * modifier, animationValue] | |
})); | |
} | |
}, { | |
key: 'zoomIn', | |
value: function zoomIn(duration) { | |
return this.animate(duration, { | |
opacity: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.5, 1], | |
outputRange: [0, 1, 1] | |
}), | |
transform: [{ | |
scale: this.state.animationValue.interpolate({ | |
inputRange: [0, 1], | |
outputRange: [0.3, 1] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: 'zoomOut', | |
value: function zoomOut(duration) { | |
return this.animate(duration, { | |
opacity: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.5, 1], | |
outputRange: [1, 1, 0] | |
}), | |
transform: [{ | |
scale: this.state.animationValue.interpolate({ | |
inputRange: [0, 0.5, 1], | |
outputRange: [1, 0.3, 0] | |
}) | |
}] | |
}); | |
} | |
}, { | |
key: 'zoomInDown', | |
value: function zoomInDown(duration) { | |
return this._zoom(duration, 'in', 'down'); | |
} | |
}, { | |
key: 'zoomInUp', | |
value: function zoomInUp(duration) { | |
return this._zoom(duration, 'in', 'up'); | |
} | |
}, { | |
key: 'zoomInLeft', | |
value: function zoomInLeft(duration) { | |
return this._zoom(duration, 'in', 'left'); | |
} | |
}, { | |
key: 'zoomInRight', | |
value: function zoomInRight(duration) { | |
return this._zoom(duration, 'in', 'right'); | |
} | |
}, { | |
key: 'zoomOutDown', | |
value: function zoomOutDown(duration) { | |
return this._zoom(duration, 'out', 'down'); | |
} | |
}, { | |
key: 'zoomOutUp', | |
value: function zoomOutUp(duration) { | |
return this._zoom(duration, 'out', 'up'); | |
} | |
}, { | |
key: 'zoomOutLeft', | |
value: function zoomOutLeft(duration) { | |
return this._zoom(duration, 'out', 'left'); | |
} | |
}, { | |
key: 'zoomOutRight', | |
value: function zoomOutRight(duration) { | |
return this._zoom(duration, 'out', 'right'); | |
} | |
}, { | |
key: 'render', | |
value: function render() { | |
var _this10 = this; | |
var _props4 = this.props, | |
style = _props4.style, | |
children = _props4.children, | |
onLayout = _props4.onLayout, | |
animation = _props4.animation, | |
duration = _props4.duration, | |
delay = _props4.delay, | |
transition = _props4.transition, | |
onAnimationBegin = _props4.onAnimationBegin, | |
onAnimationEnd = _props4.onAnimationEnd, | |
easing = _props4.easing, | |
iterationCount = _props4.iterationCount, | |
direction = _props4.direction, | |
props = _objectWithoutProperties(_props4, ['style', 'children', 'onLayout', 'animation', 'duration', 'delay', 'transition', 'onAnimationBegin', 'onAnimationEnd', 'easing', 'iterationCount', 'direction']); | |
if (animation && transition) { | |
throw new Error('You cannot combine animation and transition props'); | |
} | |
var scheduledAnimation = this.state.scheduledAnimation; | |
var hideStyle = scheduledAnimation && scheduledAnimation.indexOf('In') !== -1 ? { opacity: 0 } : false; | |
return _react2.default.createElement( | |
Animatable, | |
_extends({}, props, { | |
ref: function ref(element) { | |
return _this10._root = element; | |
}, | |
onLayout: function onLayout(event) { | |
return _this10._handleLayout(event); | |
}, | |
style: [style, this.state.animationStyle, wrapStyleTransforms(this.state.transitionStyle), hideStyle] | |
}), | |
children | |
); | |
} | |
}]); | |
return AnimatableComponent; | |
}(_react.Component), _class.propTypes = { | |
animation: _react.PropTypes.string, | |
duration: _react.PropTypes.number, | |
direction: _react.PropTypes.oneOf(['normal', 'reverse', 'alternate', 'alternate-reverse']), | |
delay: _react.PropTypes.number, | |
easing: _react.PropTypes.oneOf(Object.keys(EASING_FUNCTIONS)), | |
iterationCount: function iterationCount(props, propName, componentName) { | |
var val = props[propName]; | |
if (val !== 'infinite' && !(typeof val === 'number' && val >= 1)) { | |
return new Error('iterationCount must be a positive number or "infinite"'); | |
} | |
}, | |
onAnimationBegin: _react.PropTypes.func, | |
onAnimationEnd: _react.PropTypes.func, | |
transition: _react.PropTypes.oneOfType([_react.PropTypes.string, _react.PropTypes.arrayOf(_react.PropTypes.string)]) | |
}, _class.defaultProps = { | |
iterationCount: 1, | |
onAnimationBegin: function onAnimationBegin() {}, | |
onAnimationEnd: function onAnimationEnd() {} | |
}, _temp; | |
} | |
var View = exports.View = createAnimatableComponent(_reactNative2.default.View); | |
var Text = exports.Text = createAnimatableComponent(_reactNative2.default.Text); | |
var Image = exports.Image = createAnimatableComponent(_reactNative2.default.Image); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment