Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-motion

Package Overview
Dependencies
Maintainers
1
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-motion - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

lib/animationLoop.js

16

HISTORY.md
Legend:
- [I]: improvement
- [F]: fix
- [B]: fix
- [B]: Breaking
- [F]: Fix
- [I]: Improvement
### 0.2.0 (July 22th 2015)
- [B] `willLeave` returning `false` will now keep the key. Only `null` and `undefined` will serve as a signal to kill the disappeared key.
- [B] `willLeave` previously failed to expose the second argument `correspondingValueOfKeyThatJustLeft`. It's now exposed correctly.
- [F] Definitively fix the previous problem of mis-detecting React Element as object.
- [F] `willLeave` is now called only once per disappearing key. It was called more than once previously as a implementation detail. Though you should never have put side-effects in `willLeave`. It's still discouraged now.
- [F] If you have some `this.props.handlerThatSetStateAndUnmountsSpringInOwnerRender()` in `Spring`'s `endValue`, Spring's already scheduled `requestAnimationFrame` will no longer cause an extra `setState` since it's unmounted. But in general, _please_ don't put side-effect in `endValue`.
- [I] Stabilize the spring algorithm. No more erratic behavior with a big amount of animated items or tab switching (which usually slows down `requestAnimationFrame`). #57
- [I] Partial (total?) support for IE9 by using a `requestAnimationFrame` polyfill.
### 0.1.0 (July 14th 2015)
- [B] Breaking API: `TransitionSpring`'s `willEnter`'s callback signature is now `(keyThatEnters, correspondingValue, endValueYouJustSpecified, currentInterpolatedValue, currentSpeed)` (added `correspondingValue` as the second argument). Same for `willLeave`.
- [B] `Spring` is now no longer exposed as a default, but simply as "Spring": `require('react-motion').Spring`. Or `import {Spring} from 'react-motion'`.

@@ -9,0 +19,0 @@ - [B] `Spring` and `TransitionSpring`'s `children` function now expect a ReactElement. The components will no longer wrap the return value in a `div` for you. #44 #20

@@ -5,2 +5,8 @@ 'use strict';

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _reorderKeys = require('./reorderKeys');
var _reorderKeys2 = _interopRequireDefault(_reorderKeys);
var _Spring = require('./Spring');

@@ -10,2 +16,5 @@

exports.TransitionSpring = _Spring.TransitionSpring;
exports.utils = _Spring.utils;
var utils = {
reorderKeys: _reorderKeys2['default']
};
exports.utils = utils;

541

lib/Spring.js
'use strict';
exports.__esModule = true;
exports.updateCurrVals = updateCurrVals;
exports.updateCurrV = updateCurrV;
exports.noSpeed = noSpeed;
exports.updateCurrValue = updateCurrValue;
exports.updateCurrVelocity = updateCurrVelocity;

@@ -14,4 +13,10 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _utils = require('./utils');
var _mapTree = require('./mapTree');
var _mapTree2 = _interopRequireDefault(_mapTree);
var _lodashIsPlainObject = require('lodash.isPlainObject');
var _lodashIsPlainObject2 = _interopRequireDefault(_lodashIsPlainObject);
var _stepper = require('./stepper');

@@ -21,4 +26,23 @@

var FRAME_RATE = 1 / 60;
var _noVelocity = require('./noVelocity');
var _noVelocity2 = _interopRequireDefault(_noVelocity);
var _mergeDiff = require('./mergeDiff');
var _mergeDiff2 = _interopRequireDefault(_mergeDiff);
var _animationLoop = require('./animationLoop');
var _animationLoop2 = _interopRequireDefault(_animationLoop);
var animationLoop = _animationLoop2['default']({
// Fixed time step in seconds.
timeStep: 1 / 60,
// Slow-mo anyone? Give 0.1 a try.
timeScale: 1,
// Pause if we have more than this many steps worth of accumulated time.
maxSteps: 10
});
function zero() {

@@ -28,93 +52,43 @@ return 0;

// TODO: test
function mergeDiff(_x, _x2, _x3, _x4) {
var _again = true;
_function: while (_again) {
var collA = _x,
collB = _x2,
onRemove = _x3,
accum = _x4;
a = aa = b = bb = undefined;
_again = false;
var a = collA[0];
var aa = collA.slice(1);
var b = collB[0];
var bb = collB.slice(1);
if (collA.length === 0 && collB.length === 0) {
return accum;
// TODO: refactor common logic with updateCurrValue and updateCurrVelocity
function interpolateValue(alpha, nextValue, prevValue) {
if (nextValue === null) {
return null;
}
if (prevValue == null) {
return nextValue;
}
if (typeof nextValue === 'number') {
// https://github.com/chenglou/react-motion/pull/57#issuecomment-121924628
return nextValue * alpha + prevValue * (1 - alpha);
}
if (nextValue.val != null && nextValue.config && nextValue.config.length === 0) {
return nextValue;
}
if (nextValue.val != null) {
var ret = {
val: interpolateValue(alpha, nextValue.val, prevValue.val)
};
if (nextValue.config) {
ret.config = nextValue.config;
}
if (collA.length === 0) {
return accum.concat(collB);
}
if (collB.length === 0) {
if (onRemove(a)) {
_x = aa;
_x2 = collB;
_x3 = onRemove;
_x4 = accum;
_again = true;
continue _function;
}
_x = aa;
_x2 = collB;
_x3 = onRemove;
_x4 = accum.concat(a);
_again = true;
continue _function;
}
if (a === b) {
// fails for ([undefined], [], () => true). but don't do that
_x = aa;
_x2 = bb;
_x3 = onRemove;
_x4 = accum.concat(a);
_again = true;
continue _function;
}
if (collB.indexOf(a) === -1) {
if (onRemove(a)) {
_x = aa;
_x2 = collB;
_x3 = onRemove;
_x4 = accum;
_again = true;
continue _function;
}
_x = aa;
_x2 = collB;
_x3 = onRemove;
_x4 = accum.concat(a);
_again = true;
continue _function;
}
_x = aa;
_x2 = collB;
_x3 = onRemove;
_x4 = accum;
_again = true;
continue _function;
return ret;
}
if (Array.isArray(nextValue)) {
return nextValue.map(function (_, i) {
return interpolateValue(alpha, nextValue[i], prevValue[i]);
});
}
if (_lodashIsPlainObject2['default'](nextValue)) {
return Object.keys(nextValue).reduce(function (ret, key) {
ret[key] = interpolateValue(alpha, nextValue[key], prevValue[key]);
return ret;
}, {});
}
return nextValue;
}
function mergeDiffObj(a, b, onRemove) {
var keys = mergeDiff(Object.keys(a), Object.keys(b), function (_a) {
return !onRemove(_a);
}, []);
var ret = {};
keys.forEach(function (key) {
if (b.hasOwnProperty(key)) {
ret[key] = b[key];
} else {
ret[key] = onRemove(key);
}
});
// TODO: refactor common logic with updateCurrVelocity
return ret;
}
// TODO: refactor common logic with updateCurrV
function updateCurrVals(frameRate, currVals, currV, endValue, k, b) {
function updateCurrValue(frameRate, currValue, currVelocity, endValue, k, b) {
if (endValue === null) {

@@ -128,3 +102,3 @@ return null;

// TODO: do something to stepper to make this not allocate (2 steppers?)
return _stepper2['default'](frameRate, currVals, currV, endValue, k, b)[0];
return _stepper2['default'](frameRate, currValue, currVelocity, endValue, k, b)[0];
}

@@ -141,3 +115,3 @@ if (endValue.val != null && endValue.config && endValue.config.length === 0) {

var ret = {
val: updateCurrVals(frameRate, currVals.val, currV.val, endValue.val, _k, _b)
val: updateCurrValue(frameRate, currValue.val, currVelocity.val, endValue.val, _k, _b)
};

@@ -151,17 +125,10 @@ if (endValue.config) {

return endValue.map(function (_, i) {
return updateCurrVals(frameRate, currVals[i], currV[i], endValue[i], k, b);
return updateCurrValue(frameRate, currValue[i], currVelocity[i], endValue[i], k, b);
});
}
if (_utils.isPlainObject(endValue)) {
var _ret = (function () {
var ret = {};
Object.keys(endValue).forEach(function (key) {
ret[key] = updateCurrVals(frameRate, currVals[key], currV[key], endValue[key], k, b);
});
return {
v: ret
};
})();
if (typeof _ret === 'object') return _ret.v;
if (_lodashIsPlainObject2['default'](endValue)) {
return Object.keys(endValue).reduce(function (ret, key) {
ret[key] = updateCurrValue(frameRate, currValue[key], currVelocity[key], endValue[key], k, b);
return ret;
}, {});
}

@@ -171,3 +138,3 @@ return endValue;

function updateCurrV(frameRate, currVals, currV, endValue, k, b) {
function updateCurrVelocity(frameRate, currValue, currVelocity, endValue, k, b) {
if (endValue === null) {

@@ -178,9 +145,9 @@ return null;

if (k == null || b == null) {
return _utils.mapTree(zero, currV);
return _mapTree2['default'](zero, currVelocity);
}
// TODO: do something to stepper to make this not allocate (2 steppers?)
return _stepper2['default'](frameRate, currVals, currV, endValue, k, b)[1];
return _stepper2['default'](frameRate, currValue, currVelocity, endValue, k, b)[1];
}
if (endValue.val != null && endValue.config && endValue.config.length === 0) {
return _utils.mapTree(zero, currV);
return _mapTree2['default'](zero, currVelocity);
}

@@ -194,3 +161,3 @@ if (endValue.val != null) {

var ret = {
val: updateCurrV(frameRate, currVals.val, currV.val, endValue.val, _k, _b)
val: updateCurrVelocity(frameRate, currValue.val, currVelocity.val, endValue.val, _k, _b)
};

@@ -204,33 +171,14 @@ if (endValue.config) {

return endValue.map(function (_, i) {
return updateCurrV(frameRate, currVals[i], currV[i], endValue[i], k, b);
return updateCurrVelocity(frameRate, currValue[i], currVelocity[i], endValue[i], k, b);
});
}
if (_utils.isPlainObject(endValue)) {
var _ret2 = (function () {
var ret = {};
Object.keys(endValue).forEach(function (key) {
ret[key] = updateCurrV(frameRate, currVals[key], currV[key], endValue[key], k, b);
});
return {
v: ret
};
})();
if (typeof _ret2 === 'object') return _ret2.v;
if (_lodashIsPlainObject2['default'](endValue)) {
return Object.keys(endValue).reduce(function (ret, key) {
ret[key] = updateCurrVelocity(frameRate, currValue[key], currVelocity[key], endValue[key], k, b);
return ret;
}, {});
}
return _utils.mapTree(zero, currV);
return _mapTree2['default'](zero, currVelocity);
}
function noSpeed(coll) {
if (Array.isArray(coll)) {
return coll.every(noSpeed);
}
if (_utils.isPlainObject(coll)) {
return Object.keys(coll).every(function (key) {
return key === 'config' ? true : noSpeed(coll[key]);
});
}
return typeof coll === 'number' ? coll === 0 : true;
}
var Spring = _react2['default'].createClass({

@@ -248,8 +196,8 @@ displayName: 'Spring',

if (typeof endValue === 'function') {
// TODO: provide warning for failing to provide base case
endValue = endValue();
}
return {
currVals: endValue,
currV: _utils.mapTree(zero, endValue),
now: null
currValue: endValue,
currVelocity: _mapTree2['default'](zero, endValue)
};

@@ -259,70 +207,73 @@ },

componentDidMount: function componentDidMount() {
this.raf(true, false);
this.startAnimating();
},
componentWillReceiveProps: function componentWillReceiveProps() {
this.raf(true, false);
this.startAnimating();
},
unsubscribeAnimation: null,
// used in animationRender
hasUnmounted: false,
componentWillUnmount: function componentWillUnmount() {
cancelAnimationFrame(this._rafID);
if (this.unsubscribeAnimation) {
this.unsubscribeAnimation();
this.unsubscribeAnimation = null;
}
this.hasUnmounted = true;
},
_rafID: null,
startAnimating: function startAnimating() {
if (!this.unsubscribeAnimation) {
// means we're not animating
this.unsubscribeAnimation = animationLoop.subscribe(this.animationStep, this.animationRender, this.state);
animationLoop.start();
}
},
raf: function raf(justStarted, isLastRaf) {
var _this = this;
animationStep: function animationStep(timeStep, state) {
var currValue = state.currValue;
var currVelocity = state.currVelocity;
var endValue = this.props.endValue;
if (justStarted && this._rafID != null) {
// already rafing
return;
if (typeof endValue === 'function') {
endValue = endValue(currValue);
}
this._rafID = requestAnimationFrame(function () {
var _state = _this.state;
var currVals = _state.currVals;
var currV = _state.currV;
var now = _state.now;
var endValue = _this.props.endValue;
if (typeof endValue === 'function') {
endValue = endValue(currVals);
var newCurrValue = updateCurrValue(timeStep, currValue, currVelocity, endValue);
var newCurrVelocity = updateCurrVelocity(timeStep, currValue, currVelocity, endValue);
if (_noVelocity2['default'](currVelocity) && _noVelocity2['default'](newCurrVelocity)) {
// check explanation in `animationRender`
if (!this.hasUnmounted) {
this.unsubscribeAnimation();
this.unsubscribeAnimation = null;
}
var frameRate = now && !justStarted ? (Date.now() - now) / 1000 : FRAME_RATE;
}
var newCurrVals = updateCurrVals(frameRate, currVals, currV, endValue);
var newCurrV = updateCurrV(frameRate, currVals, currV, endValue);
return {
currValue: newCurrValue,
currVelocity: newCurrVelocity
};
},
_this.setState(function () {
return {
currVals: newCurrVals,
currV: newCurrV,
now: Date.now()
};
animationRender: function animationRender(alpha, nextState, prevState) {
// `this.hasUnmounted` might be true in the following condition:
// user does some checks in `endValue` and calls an owner handler
// owner sets state in the callback, triggering a re-render
// re-render unmounts the Spring
if (!this.hasUnmounted) {
this.setState({
currValue: interpolateValue(alpha, nextState.currValue, prevState.currValue),
currVelocity: nextState.currVelocity
});
var stop = noSpeed(newCurrV);
if (stop && !justStarted) {
// this flag is necessary, because in `endValue` callback, the user
// might check that the current value has reached the destination, and
// decide to return a new destination value. However, since s/he's
// accessing the last tick's current value, and if we stop rafing after
// speed is 0, the next `endValue` is never called and we never detect
// the new chained animation. isLastRaf ensures that we raf a single
// more time in case the user wants to chain another animation at the
// end of this one
if (isLastRaf) {
_this._rafID = null;
} else {
_this.raf(false, true);
}
} else {
_this.raf(false, false);
}
});
}
},
render: function render() {
var currVals = this.state.currVals;
var currValue = this.state.currValue;
return _react2['default'].Children.only(this.props.children(currVals));
return _react2['default'].Children.only(this.props.children(currValue));
}

@@ -336,5 +287,20 @@ });

propTypes: {
endValue: _react.PropTypes.oneOfType([_react.PropTypes.func, _react.PropTypes.object]).isRequired,
willLeave: _react.PropTypes.oneOfType([_react.PropTypes.func, _react.PropTypes.object, _react.PropTypes.array]),
willEnter: _react.PropTypes.oneOfType([_react.PropTypes.func, _react.PropTypes.object, _react.PropTypes.array]),
endValue: _react.PropTypes.oneOfType([_react.PropTypes.func, _react.PropTypes.objectOf({
key: _react.PropTypes.any.isRequired
})]).
// coming soon
// PropTypes.arrayOf(PropTypes.shape({
// key: PropTypes.any.isRequired,
// })),
// PropTypes.arrayOf(PropTypes.element),
isRequired,
willLeave: _react.PropTypes.oneOfType([_react.PropTypes.func]),
// PropTypes.object,
// PropTypes.array,
// TODO: numbers? strings?
willEnter: _react.PropTypes.oneOfType([_react.PropTypes.func]),
// PropTypes.object,
// PropTypes.array,
children: _react.PropTypes.func.isRequired

@@ -361,5 +327,4 @@ },

return {
currVals: endValue,
currV: _utils.mapTree(zero, endValue),
now: null
currValue: endValue,
currVelocity: _mapTree2['default'](zero, endValue)
};

@@ -369,148 +334,92 @@ },

componentDidMount: function componentDidMount() {
this.raf(true, false);
this.startAnimating();
},
componentWillReceiveProps: function componentWillReceiveProps() {
this.raf(true, false);
this.startAnimating();
},
unsubscribeAnimation: null,
// used in animationRender
hasUnmounted: false,
componentWillUnmount: function componentWillUnmount() {
cancelAnimationFrame(this._rafID);
if (this.unsubscribeAnimation) {
this.unsubscribeAnimation();
this.unsubscribeAnimation = undefined;
}
},
_rafID: null,
startAnimating: function startAnimating() {
if (!this.unsubscribeAnimation) {
this.unsubscribeAnimation = animationLoop.subscribe(this.animationStep, this.animationRender, this.state);
animationLoop.start();
}
},
raf: function raf(justStarted, isLastRaf) {
var _this2 = this;
animationStep: function animationStep(timeStep, state) {
var currValue = state.currValue;
var currVelocity = state.currVelocity;
var endValue = this.props.endValue;
var _props = this.props;
var willEnter = _props.willEnter;
var willLeave = _props.willLeave;
if (justStarted && this._rafID != null) {
// already rafing
return;
if (typeof endValue === 'function') {
endValue = endValue(currValue);
}
this._rafID = requestAnimationFrame(function () {
var _state2 = _this2.state;
var currVals = _state2.currVals;
var currV = _state2.currV;
var now = _this2.state.now;
var endValue = _this2.props.endValue;
var _props = _this2.props;
var willEnter = _props.willEnter;
var willLeave = _props.willLeave;
if (typeof endValue === 'function') {
endValue = endValue(currVals);
}
var mergedValue = undefined;
// only other option is obj
mergedValue = _mergeDiff2['default'](currValue, endValue,
// TODO: stop allocating like crazy in this whole code path
function (key) {
return willLeave(key, currValue[key], endValue, currValue, currVelocity);
});
var mergedVals = undefined;
if (Array.isArray(endValue)) {
(function () {
var currValsObj = {};
currVals.forEach(function (objWithKey) {
currValsObj[objWithKey.key] = objWithKey;
});
var hasNewKey = false;
Object.keys(mergedValue).filter(function (key) {
return !currValue.hasOwnProperty(key);
}).forEach(function (key) {
hasNewKey = true;
var enterValue = willEnter(key, mergedValue[key], endValue, currValue, currVelocity);
currValue[key] = enterValue;
mergedValue[key] = enterValue;
currVelocity[key] = _mapTree2['default'](zero, currValue[key]);
});
var endValueObj = {};
endValue.forEach(function (objWithKey) {
endValueObj[objWithKey.key] = objWithKey;
});
var currVObj = {};
endValue.forEach(function (objWithKey) {
currVObj[objWithKey.key] = objWithKey;
});
var newCurrValue = updateCurrValue(timeStep, currValue, currVelocity, mergedValue);
var newCurrVelocity = updateCurrVelocity(timeStep, currValue, currVelocity, mergedValue);
var mergedValsObj = mergeDiffObj(currValsObj, endValueObj, function (key) {
return willLeave(key, endValue, currVals, currV);
});
var mergedValsKeys = Object.keys(mergedValsObj);
mergedVals = mergedValsKeys.map(function (key) {
return mergedValsObj[key];
});
mergedValsKeys.filter(function (key) {
return !currValsObj.hasOwnProperty(key);
}).forEach(function (key) {
currValsObj[key] = willEnter(key, mergedValsObj[key], endValue, currVals, currV);
currVObj[key] = _utils.mapTree(zero, currValsObj[key]);
});
currVals = Object.keys(currValsObj).map(function (key) {
return currValsObj[key];
});
currV = Object.keys(currVObj).map(function (key) {
return currVObj[key];
});
})();
} else {
// only other option is obj
mergedVals = mergeDiffObj(currVals, endValue,
// TODO: stop allocating like crazy in this whole code path
function (key) {
return willLeave(key, endValue, currVals, currV);
});
// TODO: check if this is necessary
currVals = _utils.clone(currVals);
currV = _utils.clone(currV);
Object.keys(mergedVals).filter(function (key) {
return !currVals.hasOwnProperty(key);
}).forEach(function (key) {
// TODO: param format changed, check other demos
currVals[key] = willEnter(key, mergedVals[key], endValue, currVals, currV);
currV[key] = _utils.mapTree(zero, currVals[key]);
});
if (_noVelocity2['default'](currVelocity) && _noVelocity2['default'](newCurrVelocity) && !hasNewKey) {
// check explanation in `Spring.animationRender`
if (!this.hasUnmounted) {
this.unsubscribeAnimation();
this.unsubscribeAnimation = undefined;
}
}
var frameRate = now && !justStarted ? (Date.now() - now) / 1000 : FRAME_RATE;
return {
currValue: newCurrValue,
currVelocity: newCurrVelocity
};
},
var newCurrVals = updateCurrVals(frameRate, currVals, currV, mergedVals);
var newCurrV = updateCurrV(frameRate, currVals, currV, mergedVals);
_this2.setState(function () {
return {
currVals: newCurrVals,
currV: newCurrV,
now: Date.now()
};
animationRender: function animationRender(alpha, nextState, prevState) {
// See comment in Spring.
if (!this.hasUnmounted) {
this.setState({
currValue: interpolateValue(alpha, nextState.currValue, prevState.currValue),
currVelocity: nextState.currVelocity
});
var stop = noSpeed(newCurrV);
if (stop && !justStarted) {
if (isLastRaf) {
_this2._rafID = null;
} else {
_this2.raf(false, true);
}
} else {
_this2.raf(false, false);
}
});
}
},
render: function render() {
var currVals = this.state.currVals;
var currValue = this.state.currValue;
return _react2['default'].Children.only(this.props.children(currVals));
return _react2['default'].Children.only(this.props.children(currValue));
}
});
exports.TransitionSpring = TransitionSpring;
function reorderKeys(obj, f) {
var ret = {};
f(Object.keys(obj)).forEach(function (key) {
ret[key] = obj[key];
});
return ret;
}
var utils = {
reorderKeys: reorderKeys
};
exports.utils = utils;
// coming soon
// PropTypes.arrayOf(PropTypes.shape({
// key: PropTypes.any.isRequired,
// })),
// PropTypes.arrayOf(PropTypes.element),
// TODO: numbers? strings?
exports.TransitionSpring = TransitionSpring;
{
"name": "react-motion",
"version": "0.1.0",
"version": "0.2.0",
"description": "A spring that solves your animation problems.",

@@ -20,2 +20,3 @@ "main": "lib/react-motion.js",

"isparta": "^3.0.3",
"lodash.range": "^3.0.1",
"mocha": "^2.2.5",

@@ -52,3 +53,8 @@ "react-hot-loader": "^1.2.8",

"author": "chenglou",
"license": "MIT"
"license": "MIT",
"dependencies": {
"lodash.isplainobject": "^3.2.0",
"performance-now": "^0.2.0",
"raf": "^3.1.0"
}
}

@@ -25,3 +25,3 @@ # React-Motion

[Check](https://cdn.rawgit.com/chenglou/react-motion/cffb3894f42e4825178d9c7c0313b2f4e9e65ab2/demo0/index.html) [Out](https://cdn.rawgit.com/chenglou/react-motion/cffb3894f42e4825178d9c7c0313b2f4e9e65ab2/demo1/index.html) [The](https://cdn.rawgit.com/chenglou/react-motion/cffb3894f42e4825178d9c7c0313b2f4e9e65ab2/demo2/index.html) [Cool](https://cdn.rawgit.com/chenglou/react-motion/cffb3894f42e4825178d9c7c0313b2f4e9e65ab2/demo3/index.html) [Demos](https://cdn.rawgit.com/chenglou/react-motion/072fef7b84b2d57187643baa4156ee2a7374655f/demo4/index.html).
[Check](https://cdn.rawgit.com/chenglou/react-motion/3b5be548cd08630a836562a053576ff91f94b93f/demo0/index.html) [Out](https://cdn.rawgit.com/chenglou/react-motion/3b5be548cd08630a836562a053576ff91f94b93f/demo1/index.html) [The](https://cdn.rawgit.com/chenglou/react-motion/3b5be548cd08630a836562a053576ff91f94b93f/demo2/index.html) [Cool](https://cdn.rawgit.com/chenglou/react-motion/3b5be548cd08630a836562a053576ff91f94b93f/demo3/index.html) [Demos](https://cdn.rawgit.com/chenglou/react-motion/3b5be548cd08630a836562a053576ff91f94b93f/demo4/index.html).

@@ -67,3 +67,3 @@ ## What does this library try to solve?

The library exports a default `Spring`, a `TransitionSpring` and `utils`.
The library exports a `Spring`, a `TransitionSpring` and `utils`.

@@ -189,9 +189,9 @@ ### <Spring />

### <TransitionSpring />
Like `Spring`, but can takes two other props: `willEnter` and `willLeave`. Throughout this section, please remember that ""
Like `Spring`, but can take two other props: `willEnter` and `willLeave`. Throughout this section, please remember that
`endValue`: now constrained to an object of the shape `{key => yourStuff}` (the data is constrained to this shape, but that doesn't mean the way you use your interpolated value has to be). When your the `endValue` provide differs from the current interpolated value by an added/removed key:
`endValue`: now constrained to an object (or a callback `currentValue -> object`) of the shape `{key => yourStuff}` (the data is constrained to this shape, but that doesn't mean the way you use your interpolated value has to be). When `endValue` differs from the current interpolated value by an added/removed key:
`willEnter`: a callback that's called **once** and is passed `(keyThatEnters, endValueYouJustSpecified, currentInterpolatedValue, currentSpeed)`. Return an object/array configuration that'll serve as the starting value of that new key. That configuration will be merged into `endValue`. The default value of `willEnter` is `(key, endValue) => endValue[key]`. It returns the same configuration as the one you just specified in `endValue`. In other words, the start and end are the same: no animation.
`willEnter`: a callback that's called **once** and is passed `(keyThatEnters, correspondingValueOfKey, endValueYouJustSpecified, currentInterpolatedValue, currentSpeed)`. Return an object/array configuration that'll serve as the starting value of that new key. That configuration will be merged into `endValue`. The default value of `willEnter` is `(key, endValue) => endValue[key]`. It returns the same configuration as the one you just specified in `endValue`. In other words, the start and end are the same: no animation.
`willLeave`: a callback that's called **many** times and is passed `(keyThatLeaves, endValueYouJustSpecified, currentInterpolatedValue, currentSpeed)`. Return an object/array configuration (which will serve as the new `endValue[keyThatLeaves]` and merged into `endValue`) to indicate you still want to keep the item around. Otherwise, return `null`.
`willLeave`: a callback that's called **many** times and is passed `(keyThatLeaves, correspondingValueOfKeyThatJustLeft, endValueYouJustSpecified, currentInterpolatedValue, currentSpeed)`. Return an object/array configuration (which will serve as the new `endValue[keyThatLeaves]` and merged into `endValue`) to indicate you still want to keep the item around. Otherwise, return `null`.

@@ -234,3 +234,3 @@ #### Sample Usage

willLeave(key, endValue, currentValue, currentSpeed) {
willLeave(key, value, endValue, currentValue, currentSpeed) {
if (currentValue[key].opacity.val === 0 && currentSpeed[key].opacity.val === 0) {

@@ -270,4 +270,5 @@ return null; // kill component when opacity reaches 0

);
})}}
})}
</div>
}
</TransitionSpring>

@@ -274,0 +275,0 @@ );

@@ -6,2 +6,3 @@ var webpack = require('webpack');

var config = {
devtool: 'sourcemap',
entry: {

@@ -8,0 +9,0 @@ index: './src/react-motion.js'

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc