react-motion
Advanced tools
Comparing version 0.4.8 to 0.5.0
@@ -14,3 +14,3 @@ { | ||
"dependencies": { | ||
"react": ">=0.13.2 || ^0.14 || ^15.0.0" | ||
"react": "^0.14.9 || ^15.3.0" | ||
}, | ||
@@ -17,0 +17,0 @@ "keywords": [ |
@@ -7,4 +7,10 @@ 'use strict'; | ||
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; }; })(); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
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; } | ||
var _mapToZero = require('./mapToZero'); | ||
@@ -42,182 +48,190 @@ | ||
var _createReactClass = require('create-react-class'); | ||
var msPerFrame = 1000 / 60; | ||
var _createReactClass2 = _interopRequireDefault(_createReactClass); | ||
var Motion = (function (_React$Component) { | ||
_inherits(Motion, _React$Component); | ||
var msPerFrame = 1000 / 60; | ||
_createClass(Motion, null, [{ | ||
key: 'propTypes', | ||
value: { | ||
// TOOD: warn against putting a config in here | ||
defaultStyle: _propTypes2['default'].objectOf(_propTypes2['default'].number), | ||
style: _propTypes2['default'].objectOf(_propTypes2['default'].oneOfType([_propTypes2['default'].number, _propTypes2['default'].object])).isRequired, | ||
children: _propTypes2['default'].func.isRequired, | ||
onRest: _propTypes2['default'].func | ||
}, | ||
enumerable: true | ||
}]); | ||
var Motion = _createReactClass2['default']({ | ||
propTypes: { | ||
// TOOD: warn against putting a config in here | ||
defaultStyle: _propTypes2['default'].objectOf(_propTypes2['default'].number), | ||
style: _propTypes2['default'].objectOf(_propTypes2['default'].oneOfType([_propTypes2['default'].number, _propTypes2['default'].object])).isRequired, | ||
children: _propTypes2['default'].func.isRequired, | ||
onRest: _propTypes2['default'].func | ||
}, | ||
function Motion(props) { | ||
var _this = this; | ||
getInitialState: function getInitialState() { | ||
var _props = this.props; | ||
var defaultStyle = _props.defaultStyle; | ||
var style = _props.style; | ||
_classCallCheck(this, Motion); | ||
var currentStyle = defaultStyle || _stripStyle2['default'](style); | ||
var currentVelocity = _mapToZero2['default'](currentStyle); | ||
return { | ||
currentStyle: currentStyle, | ||
currentVelocity: currentVelocity, | ||
lastIdealStyle: currentStyle, | ||
lastIdealVelocity: currentVelocity | ||
}; | ||
}, | ||
_React$Component.call(this, props); | ||
this.wasAnimating = false; | ||
this.animationID = null; | ||
this.prevTime = 0; | ||
this.accumulatedTime = 0; | ||
this.unreadPropStyle = null; | ||
wasAnimating: false, | ||
animationID: null, | ||
prevTime: 0, | ||
accumulatedTime: 0, | ||
// it's possible that currentStyle's value is stale: if props is immediately | ||
// changed from 0 to 400 to spring(0) again, the async currentStyle is still | ||
// at 0 (didn't have time to tick and interpolate even once). If we naively | ||
// compare currentStyle with destVal it'll be 0 === 0 (no animation, stop). | ||
// In reality currentStyle should be 400 | ||
unreadPropStyle: null, | ||
// after checking for unreadPropStyle != null, we manually go set the | ||
// non-interpolating values (those that are a number, without a spring | ||
// config) | ||
clearUnreadPropStyle: function clearUnreadPropStyle(destStyle) { | ||
var dirty = false; | ||
var _state = this.state; | ||
var currentStyle = _state.currentStyle; | ||
var currentVelocity = _state.currentVelocity; | ||
var lastIdealStyle = _state.lastIdealStyle; | ||
var lastIdealVelocity = _state.lastIdealVelocity; | ||
this.clearUnreadPropStyle = function (destStyle) { | ||
var dirty = false; | ||
var _state = _this.state; | ||
var currentStyle = _state.currentStyle; | ||
var currentVelocity = _state.currentVelocity; | ||
var lastIdealStyle = _state.lastIdealStyle; | ||
var lastIdealVelocity = _state.lastIdealVelocity; | ||
for (var key in destStyle) { | ||
if (!Object.prototype.hasOwnProperty.call(destStyle, key)) { | ||
continue; | ||
} | ||
for (var key in destStyle) { | ||
if (!Object.prototype.hasOwnProperty.call(destStyle, key)) { | ||
continue; | ||
} | ||
var styleValue = destStyle[key]; | ||
if (typeof styleValue === 'number') { | ||
if (!dirty) { | ||
dirty = true; | ||
currentStyle = _extends({}, currentStyle); | ||
currentVelocity = _extends({}, currentVelocity); | ||
lastIdealStyle = _extends({}, lastIdealStyle); | ||
lastIdealVelocity = _extends({}, lastIdealVelocity); | ||
var styleValue = destStyle[key]; | ||
if (typeof styleValue === 'number') { | ||
if (!dirty) { | ||
dirty = true; | ||
currentStyle = _extends({}, currentStyle); | ||
currentVelocity = _extends({}, currentVelocity); | ||
lastIdealStyle = _extends({}, lastIdealStyle); | ||
lastIdealVelocity = _extends({}, lastIdealVelocity); | ||
} | ||
currentStyle[key] = styleValue; | ||
currentVelocity[key] = 0; | ||
lastIdealStyle[key] = styleValue; | ||
lastIdealVelocity[key] = 0; | ||
} | ||
} | ||
currentStyle[key] = styleValue; | ||
currentVelocity[key] = 0; | ||
lastIdealStyle[key] = styleValue; | ||
lastIdealVelocity[key] = 0; | ||
if (dirty) { | ||
_this.setState({ currentStyle: currentStyle, currentVelocity: currentVelocity, lastIdealStyle: lastIdealStyle, lastIdealVelocity: lastIdealVelocity }); | ||
} | ||
} | ||
}; | ||
if (dirty) { | ||
this.setState({ currentStyle: currentStyle, currentVelocity: currentVelocity, lastIdealStyle: lastIdealStyle, lastIdealVelocity: lastIdealVelocity }); | ||
} | ||
}, | ||
this.startAnimationIfNecessary = function () { | ||
// TODO: when config is {a: 10} and dest is {a: 10} do we raf once and | ||
// call cb? No, otherwise accidental parent rerender causes cb trigger | ||
_this.animationID = _raf2['default'](function (timestamp) { | ||
// check if we need to animate in the first place | ||
var propsStyle = _this.props.style; | ||
if (_shouldStopAnimation2['default'](_this.state.currentStyle, propsStyle, _this.state.currentVelocity)) { | ||
if (_this.wasAnimating && _this.props.onRest) { | ||
_this.props.onRest(); | ||
} | ||
startAnimationIfNecessary: function startAnimationIfNecessary() { | ||
var _this = this; | ||
// no need to cancel animationID here; shouldn't have any in flight | ||
_this.animationID = null; | ||
_this.wasAnimating = false; | ||
_this.accumulatedTime = 0; | ||
return; | ||
} | ||
// TODO: when config is {a: 10} and dest is {a: 10} do we raf once and | ||
// call cb? No, otherwise accidental parent rerender causes cb trigger | ||
this.animationID = _raf2['default'](function (timestamp) { | ||
// check if we need to animate in the first place | ||
var propsStyle = _this.props.style; | ||
if (_shouldStopAnimation2['default'](_this.state.currentStyle, propsStyle, _this.state.currentVelocity)) { | ||
if (_this.wasAnimating && _this.props.onRest) { | ||
_this.props.onRest(); | ||
_this.wasAnimating = true; | ||
var currentTime = timestamp || _performanceNow2['default'](); | ||
var timeDelta = currentTime - _this.prevTime; | ||
_this.prevTime = currentTime; | ||
_this.accumulatedTime = _this.accumulatedTime + timeDelta; | ||
// more than 10 frames? prolly switched browser tab. Restart | ||
if (_this.accumulatedTime > msPerFrame * 10) { | ||
_this.accumulatedTime = 0; | ||
} | ||
// no need to cancel animationID here; shouldn't have any in flight | ||
_this.animationID = null; | ||
_this.wasAnimating = false; | ||
_this.accumulatedTime = 0; | ||
return; | ||
} | ||
if (_this.accumulatedTime === 0) { | ||
// no need to cancel animationID here; shouldn't have any in flight | ||
_this.animationID = null; | ||
_this.startAnimationIfNecessary(); | ||
return; | ||
} | ||
_this.wasAnimating = true; | ||
var currentFrameCompletion = (_this.accumulatedTime - Math.floor(_this.accumulatedTime / msPerFrame) * msPerFrame) / msPerFrame; | ||
var framesToCatchUp = Math.floor(_this.accumulatedTime / msPerFrame); | ||
var currentTime = timestamp || _performanceNow2['default'](); | ||
var timeDelta = currentTime - _this.prevTime; | ||
_this.prevTime = currentTime; | ||
_this.accumulatedTime = _this.accumulatedTime + timeDelta; | ||
// more than 10 frames? prolly switched browser tab. Restart | ||
if (_this.accumulatedTime > msPerFrame * 10) { | ||
_this.accumulatedTime = 0; | ||
} | ||
var newLastIdealStyle = {}; | ||
var newLastIdealVelocity = {}; | ||
var newCurrentStyle = {}; | ||
var newCurrentVelocity = {}; | ||
if (_this.accumulatedTime === 0) { | ||
// no need to cancel animationID here; shouldn't have any in flight | ||
_this.animationID = null; | ||
_this.startAnimationIfNecessary(); | ||
return; | ||
} | ||
for (var key in propsStyle) { | ||
if (!Object.prototype.hasOwnProperty.call(propsStyle, key)) { | ||
continue; | ||
} | ||
var currentFrameCompletion = (_this.accumulatedTime - Math.floor(_this.accumulatedTime / msPerFrame) * msPerFrame) / msPerFrame; | ||
var framesToCatchUp = Math.floor(_this.accumulatedTime / msPerFrame); | ||
var styleValue = propsStyle[key]; | ||
if (typeof styleValue === 'number') { | ||
newCurrentStyle[key] = styleValue; | ||
newCurrentVelocity[key] = 0; | ||
newLastIdealStyle[key] = styleValue; | ||
newLastIdealVelocity[key] = 0; | ||
} else { | ||
var newLastIdealStyleValue = _this.state.lastIdealStyle[key]; | ||
var newLastIdealVelocityValue = _this.state.lastIdealVelocity[key]; | ||
for (var i = 0; i < framesToCatchUp; i++) { | ||
var _stepper = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); | ||
var newLastIdealStyle = {}; | ||
var newLastIdealVelocity = {}; | ||
var newCurrentStyle = {}; | ||
var newCurrentVelocity = {}; | ||
newLastIdealStyleValue = _stepper[0]; | ||
newLastIdealVelocityValue = _stepper[1]; | ||
} | ||
for (var key in propsStyle) { | ||
if (!Object.prototype.hasOwnProperty.call(propsStyle, key)) { | ||
continue; | ||
} | ||
var _stepper2 = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); | ||
var styleValue = propsStyle[key]; | ||
if (typeof styleValue === 'number') { | ||
newCurrentStyle[key] = styleValue; | ||
newCurrentVelocity[key] = 0; | ||
newLastIdealStyle[key] = styleValue; | ||
newLastIdealVelocity[key] = 0; | ||
} else { | ||
var newLastIdealStyleValue = _this.state.lastIdealStyle[key]; | ||
var newLastIdealVelocityValue = _this.state.lastIdealVelocity[key]; | ||
for (var i = 0; i < framesToCatchUp; i++) { | ||
var _stepper = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); | ||
var nextIdealX = _stepper2[0]; | ||
var nextIdealV = _stepper2[1]; | ||
newLastIdealStyleValue = _stepper[0]; | ||
newLastIdealVelocityValue = _stepper[1]; | ||
newCurrentStyle[key] = newLastIdealStyleValue + (nextIdealX - newLastIdealStyleValue) * currentFrameCompletion; | ||
newCurrentVelocity[key] = newLastIdealVelocityValue + (nextIdealV - newLastIdealVelocityValue) * currentFrameCompletion; | ||
newLastIdealStyle[key] = newLastIdealStyleValue; | ||
newLastIdealVelocity[key] = newLastIdealVelocityValue; | ||
} | ||
} | ||
var _stepper2 = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); | ||
_this.animationID = null; | ||
// the amount we're looped over above | ||
_this.accumulatedTime -= framesToCatchUp * msPerFrame; | ||
var nextIdealX = _stepper2[0]; | ||
var nextIdealV = _stepper2[1]; | ||
_this.setState({ | ||
currentStyle: newCurrentStyle, | ||
currentVelocity: newCurrentVelocity, | ||
lastIdealStyle: newLastIdealStyle, | ||
lastIdealVelocity: newLastIdealVelocity | ||
}); | ||
newCurrentStyle[key] = newLastIdealStyleValue + (nextIdealX - newLastIdealStyleValue) * currentFrameCompletion; | ||
newCurrentVelocity[key] = newLastIdealVelocityValue + (nextIdealV - newLastIdealVelocityValue) * currentFrameCompletion; | ||
newLastIdealStyle[key] = newLastIdealStyleValue; | ||
newLastIdealVelocity[key] = newLastIdealVelocityValue; | ||
} | ||
} | ||
_this.unreadPropStyle = null; | ||
_this.animationID = null; | ||
// the amount we're looped over above | ||
_this.accumulatedTime -= framesToCatchUp * msPerFrame; | ||
_this.setState({ | ||
currentStyle: newCurrentStyle, | ||
currentVelocity: newCurrentVelocity, | ||
lastIdealStyle: newLastIdealStyle, | ||
lastIdealVelocity: newLastIdealVelocity | ||
_this.startAnimationIfNecessary(); | ||
}); | ||
}; | ||
_this.unreadPropStyle = null; | ||
this.state = this.defaultState(); | ||
} | ||
_this.startAnimationIfNecessary(); | ||
}); | ||
}, | ||
Motion.prototype.defaultState = function defaultState() { | ||
var _props = this.props; | ||
var defaultStyle = _props.defaultStyle; | ||
var style = _props.style; | ||
componentDidMount: function componentDidMount() { | ||
var currentStyle = defaultStyle || _stripStyle2['default'](style); | ||
var currentVelocity = _mapToZero2['default'](currentStyle); | ||
return { | ||
currentStyle: currentStyle, | ||
currentVelocity: currentVelocity, | ||
lastIdealStyle: currentStyle, | ||
lastIdealVelocity: currentVelocity | ||
}; | ||
}; | ||
// it's possible that currentStyle's value is stale: if props is immediately | ||
// changed from 0 to 400 to spring(0) again, the async currentStyle is still | ||
// at 0 (didn't have time to tick and interpolate even once). If we naively | ||
// compare currentStyle with destVal it'll be 0 === 0 (no animation, stop). | ||
// In reality currentStyle should be 400 | ||
Motion.prototype.componentDidMount = function componentDidMount() { | ||
this.prevTime = _performanceNow2['default'](); | ||
this.startAnimationIfNecessary(); | ||
}, | ||
}; | ||
componentWillReceiveProps: function componentWillReceiveProps(props) { | ||
Motion.prototype.componentWillReceiveProps = function componentWillReceiveProps(props) { | ||
if (this.unreadPropStyle != null) { | ||
@@ -233,5 +247,5 @@ // previous props haven't had the chance to be set yet; set them here | ||
} | ||
}, | ||
}; | ||
componentWillUnmount: function componentWillUnmount() { | ||
Motion.prototype.componentWillUnmount = function componentWillUnmount() { | ||
if (this.animationID != null) { | ||
@@ -241,11 +255,17 @@ _raf2['default'].cancel(this.animationID); | ||
} | ||
}, | ||
}; | ||
render: function render() { | ||
Motion.prototype.render = function render() { | ||
var renderedChildren = this.props.children(this.state.currentStyle); | ||
return renderedChildren && _react2['default'].Children.only(renderedChildren); | ||
} | ||
}); | ||
}; | ||
return Motion; | ||
})(_react2['default'].Component); | ||
exports['default'] = Motion; | ||
module.exports = exports['default']; | ||
module.exports = exports['default']; | ||
// after checking for unreadPropStyle != null, we manually go set the | ||
// non-interpolating values (those that are a number, without a spring | ||
// config) |
@@ -7,4 +7,10 @@ 'use strict'; | ||
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; }; })(); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
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; } | ||
var _mapToZero = require('./mapToZero'); | ||
@@ -42,6 +48,2 @@ | ||
var _createReactClass = require('create-react-class'); | ||
var _createReactClass2 = _interopRequireDefault(_createReactClass); | ||
var msPerFrame = 1000 / 60; | ||
@@ -58,188 +60,194 @@ | ||
var StaggeredMotion = _createReactClass2['default']({ | ||
propTypes: { | ||
// TOOD: warn against putting a config in here | ||
defaultStyles: _propTypes2['default'].arrayOf(_propTypes2['default'].objectOf(_propTypes2['default'].number)), | ||
styles: _propTypes2['default'].func.isRequired, | ||
children: _propTypes2['default'].func.isRequired | ||
}, | ||
var StaggeredMotion = (function (_React$Component) { | ||
_inherits(StaggeredMotion, _React$Component); | ||
getInitialState: function getInitialState() { | ||
var _props = this.props; | ||
var defaultStyles = _props.defaultStyles; | ||
var styles = _props.styles; | ||
_createClass(StaggeredMotion, null, [{ | ||
key: 'propTypes', | ||
value: { | ||
// TOOD: warn against putting a config in here | ||
defaultStyles: _propTypes2['default'].arrayOf(_propTypes2['default'].objectOf(_propTypes2['default'].number)), | ||
styles: _propTypes2['default'].func.isRequired, | ||
children: _propTypes2['default'].func.isRequired | ||
}, | ||
enumerable: true | ||
}]); | ||
var currentStyles = defaultStyles || styles().map(_stripStyle2['default']); | ||
var currentVelocities = currentStyles.map(function (currentStyle) { | ||
return _mapToZero2['default'](currentStyle); | ||
}); | ||
return { | ||
currentStyles: currentStyles, | ||
currentVelocities: currentVelocities, | ||
lastIdealStyles: currentStyles, | ||
lastIdealVelocities: currentVelocities | ||
}; | ||
}, | ||
function StaggeredMotion(props) { | ||
var _this = this; | ||
animationID: null, | ||
prevTime: 0, | ||
accumulatedTime: 0, | ||
// it's possible that currentStyle's value is stale: if props is immediately | ||
// changed from 0 to 400 to spring(0) again, the async currentStyle is still | ||
// at 0 (didn't have time to tick and interpolate even once). If we naively | ||
// compare currentStyle with destVal it'll be 0 === 0 (no animation, stop). | ||
// In reality currentStyle should be 400 | ||
unreadPropStyles: null, | ||
// after checking for unreadPropStyles != null, we manually go set the | ||
// non-interpolating values (those that are a number, without a spring | ||
// config) | ||
clearUnreadPropStyle: function clearUnreadPropStyle(unreadPropStyles) { | ||
var _state = this.state; | ||
var currentStyles = _state.currentStyles; | ||
var currentVelocities = _state.currentVelocities; | ||
var lastIdealStyles = _state.lastIdealStyles; | ||
var lastIdealVelocities = _state.lastIdealVelocities; | ||
_classCallCheck(this, StaggeredMotion); | ||
var someDirty = false; | ||
for (var i = 0; i < unreadPropStyles.length; i++) { | ||
var unreadPropStyle = unreadPropStyles[i]; | ||
var dirty = false; | ||
_React$Component.call(this, props); | ||
this.animationID = null; | ||
this.prevTime = 0; | ||
this.accumulatedTime = 0; | ||
this.unreadPropStyles = null; | ||
for (var key in unreadPropStyle) { | ||
if (!Object.prototype.hasOwnProperty.call(unreadPropStyle, key)) { | ||
continue; | ||
} | ||
this.clearUnreadPropStyle = function (unreadPropStyles) { | ||
var _state = _this.state; | ||
var currentStyles = _state.currentStyles; | ||
var currentVelocities = _state.currentVelocities; | ||
var lastIdealStyles = _state.lastIdealStyles; | ||
var lastIdealVelocities = _state.lastIdealVelocities; | ||
var styleValue = unreadPropStyle[key]; | ||
if (typeof styleValue === 'number') { | ||
if (!dirty) { | ||
dirty = true; | ||
someDirty = true; | ||
currentStyles[i] = _extends({}, currentStyles[i]); | ||
currentVelocities[i] = _extends({}, currentVelocities[i]); | ||
lastIdealStyles[i] = _extends({}, lastIdealStyles[i]); | ||
lastIdealVelocities[i] = _extends({}, lastIdealVelocities[i]); | ||
var someDirty = false; | ||
for (var i = 0; i < unreadPropStyles.length; i++) { | ||
var unreadPropStyle = unreadPropStyles[i]; | ||
var dirty = false; | ||
for (var key in unreadPropStyle) { | ||
if (!Object.prototype.hasOwnProperty.call(unreadPropStyle, key)) { | ||
continue; | ||
} | ||
currentStyles[i][key] = styleValue; | ||
currentVelocities[i][key] = 0; | ||
lastIdealStyles[i][key] = styleValue; | ||
lastIdealVelocities[i][key] = 0; | ||
var styleValue = unreadPropStyle[key]; | ||
if (typeof styleValue === 'number') { | ||
if (!dirty) { | ||
dirty = true; | ||
someDirty = true; | ||
currentStyles[i] = _extends({}, currentStyles[i]); | ||
currentVelocities[i] = _extends({}, currentVelocities[i]); | ||
lastIdealStyles[i] = _extends({}, lastIdealStyles[i]); | ||
lastIdealVelocities[i] = _extends({}, lastIdealVelocities[i]); | ||
} | ||
currentStyles[i][key] = styleValue; | ||
currentVelocities[i][key] = 0; | ||
lastIdealStyles[i][key] = styleValue; | ||
lastIdealVelocities[i][key] = 0; | ||
} | ||
} | ||
} | ||
} | ||
if (someDirty) { | ||
this.setState({ currentStyles: currentStyles, currentVelocities: currentVelocities, lastIdealStyles: lastIdealStyles, lastIdealVelocities: lastIdealVelocities }); | ||
} | ||
}, | ||
if (someDirty) { | ||
_this.setState({ currentStyles: currentStyles, currentVelocities: currentVelocities, lastIdealStyles: lastIdealStyles, lastIdealVelocities: lastIdealVelocities }); | ||
} | ||
}; | ||
startAnimationIfNecessary: function startAnimationIfNecessary() { | ||
var _this = this; | ||
this.startAnimationIfNecessary = function () { | ||
// TODO: when config is {a: 10} and dest is {a: 10} do we raf once and | ||
// call cb? No, otherwise accidental parent rerender causes cb trigger | ||
_this.animationID = _raf2['default'](function (timestamp) { | ||
var destStyles = _this.props.styles(_this.state.lastIdealStyles); | ||
// TODO: when config is {a: 10} and dest is {a: 10} do we raf once and | ||
// call cb? No, otherwise accidental parent rerender causes cb trigger | ||
this.animationID = _raf2['default'](function (timestamp) { | ||
var destStyles = _this.props.styles(_this.state.lastIdealStyles); | ||
// check if we need to animate in the first place | ||
if (shouldStopAnimationAll(_this.state.currentStyles, destStyles, _this.state.currentVelocities)) { | ||
// no need to cancel animationID here; shouldn't have any in flight | ||
_this.animationID = null; | ||
_this.accumulatedTime = 0; | ||
return; | ||
} | ||
// check if we need to animate in the first place | ||
if (shouldStopAnimationAll(_this.state.currentStyles, destStyles, _this.state.currentVelocities)) { | ||
// no need to cancel animationID here; shouldn't have any in flight | ||
_this.animationID = null; | ||
_this.accumulatedTime = 0; | ||
return; | ||
} | ||
var currentTime = timestamp || _performanceNow2['default'](); | ||
var timeDelta = currentTime - _this.prevTime; | ||
_this.prevTime = currentTime; | ||
_this.accumulatedTime = _this.accumulatedTime + timeDelta; | ||
// more than 10 frames? prolly switched browser tab. Restart | ||
if (_this.accumulatedTime > msPerFrame * 10) { | ||
_this.accumulatedTime = 0; | ||
} | ||
var currentTime = timestamp || _performanceNow2['default'](); | ||
var timeDelta = currentTime - _this.prevTime; | ||
_this.prevTime = currentTime; | ||
_this.accumulatedTime = _this.accumulatedTime + timeDelta; | ||
// more than 10 frames? prolly switched browser tab. Restart | ||
if (_this.accumulatedTime > msPerFrame * 10) { | ||
_this.accumulatedTime = 0; | ||
} | ||
if (_this.accumulatedTime === 0) { | ||
// no need to cancel animationID here; shouldn't have any in flight | ||
_this.animationID = null; | ||
_this.startAnimationIfNecessary(); | ||
return; | ||
} | ||
if (_this.accumulatedTime === 0) { | ||
// no need to cancel animationID here; shouldn't have any in flight | ||
_this.animationID = null; | ||
_this.startAnimationIfNecessary(); | ||
return; | ||
} | ||
var currentFrameCompletion = (_this.accumulatedTime - Math.floor(_this.accumulatedTime / msPerFrame) * msPerFrame) / msPerFrame; | ||
var framesToCatchUp = Math.floor(_this.accumulatedTime / msPerFrame); | ||
var currentFrameCompletion = (_this.accumulatedTime - Math.floor(_this.accumulatedTime / msPerFrame) * msPerFrame) / msPerFrame; | ||
var framesToCatchUp = Math.floor(_this.accumulatedTime / msPerFrame); | ||
var newLastIdealStyles = []; | ||
var newLastIdealVelocities = []; | ||
var newCurrentStyles = []; | ||
var newCurrentVelocities = []; | ||
var newLastIdealStyles = []; | ||
var newLastIdealVelocities = []; | ||
var newCurrentStyles = []; | ||
var newCurrentVelocities = []; | ||
for (var i = 0; i < destStyles.length; i++) { | ||
var destStyle = destStyles[i]; | ||
var newCurrentStyle = {}; | ||
var newCurrentVelocity = {}; | ||
var newLastIdealStyle = {}; | ||
var newLastIdealVelocity = {}; | ||
for (var i = 0; i < destStyles.length; i++) { | ||
var destStyle = destStyles[i]; | ||
var newCurrentStyle = {}; | ||
var newCurrentVelocity = {}; | ||
var newLastIdealStyle = {}; | ||
var newLastIdealVelocity = {}; | ||
for (var key in destStyle) { | ||
if (!Object.prototype.hasOwnProperty.call(destStyle, key)) { | ||
continue; | ||
} | ||
for (var key in destStyle) { | ||
if (!Object.prototype.hasOwnProperty.call(destStyle, key)) { | ||
continue; | ||
} | ||
var styleValue = destStyle[key]; | ||
if (typeof styleValue === 'number') { | ||
newCurrentStyle[key] = styleValue; | ||
newCurrentVelocity[key] = 0; | ||
newLastIdealStyle[key] = styleValue; | ||
newLastIdealVelocity[key] = 0; | ||
} else { | ||
var newLastIdealStyleValue = _this.state.lastIdealStyles[i][key]; | ||
var newLastIdealVelocityValue = _this.state.lastIdealVelocities[i][key]; | ||
for (var j = 0; j < framesToCatchUp; j++) { | ||
var _stepper = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); | ||
var styleValue = destStyle[key]; | ||
if (typeof styleValue === 'number') { | ||
newCurrentStyle[key] = styleValue; | ||
newCurrentVelocity[key] = 0; | ||
newLastIdealStyle[key] = styleValue; | ||
newLastIdealVelocity[key] = 0; | ||
} else { | ||
var newLastIdealStyleValue = _this.state.lastIdealStyles[i][key]; | ||
var newLastIdealVelocityValue = _this.state.lastIdealVelocities[i][key]; | ||
for (var j = 0; j < framesToCatchUp; j++) { | ||
var _stepper = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); | ||
newLastIdealStyleValue = _stepper[0]; | ||
newLastIdealVelocityValue = _stepper[1]; | ||
} | ||
newLastIdealStyleValue = _stepper[0]; | ||
newLastIdealVelocityValue = _stepper[1]; | ||
} | ||
var _stepper2 = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); | ||
var _stepper2 = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); | ||
var nextIdealX = _stepper2[0]; | ||
var nextIdealV = _stepper2[1]; | ||
var nextIdealX = _stepper2[0]; | ||
var nextIdealV = _stepper2[1]; | ||
newCurrentStyle[key] = newLastIdealStyleValue + (nextIdealX - newLastIdealStyleValue) * currentFrameCompletion; | ||
newCurrentVelocity[key] = newLastIdealVelocityValue + (nextIdealV - newLastIdealVelocityValue) * currentFrameCompletion; | ||
newLastIdealStyle[key] = newLastIdealStyleValue; | ||
newLastIdealVelocity[key] = newLastIdealVelocityValue; | ||
} | ||
} | ||
newCurrentStyle[key] = newLastIdealStyleValue + (nextIdealX - newLastIdealStyleValue) * currentFrameCompletion; | ||
newCurrentVelocity[key] = newLastIdealVelocityValue + (nextIdealV - newLastIdealVelocityValue) * currentFrameCompletion; | ||
newLastIdealStyle[key] = newLastIdealStyleValue; | ||
newLastIdealVelocity[key] = newLastIdealVelocityValue; | ||
} | ||
newCurrentStyles[i] = newCurrentStyle; | ||
newCurrentVelocities[i] = newCurrentVelocity; | ||
newLastIdealStyles[i] = newLastIdealStyle; | ||
newLastIdealVelocities[i] = newLastIdealVelocity; | ||
} | ||
newCurrentStyles[i] = newCurrentStyle; | ||
newCurrentVelocities[i] = newCurrentVelocity; | ||
newLastIdealStyles[i] = newLastIdealStyle; | ||
newLastIdealVelocities[i] = newLastIdealVelocity; | ||
} | ||
_this.animationID = null; | ||
// the amount we're looped over above | ||
_this.accumulatedTime -= framesToCatchUp * msPerFrame; | ||
_this.animationID = null; | ||
// the amount we're looped over above | ||
_this.accumulatedTime -= framesToCatchUp * msPerFrame; | ||
_this.setState({ | ||
currentStyles: newCurrentStyles, | ||
currentVelocities: newCurrentVelocities, | ||
lastIdealStyles: newLastIdealStyles, | ||
lastIdealVelocities: newLastIdealVelocities | ||
}); | ||
_this.setState({ | ||
currentStyles: newCurrentStyles, | ||
currentVelocities: newCurrentVelocities, | ||
lastIdealStyles: newLastIdealStyles, | ||
lastIdealVelocities: newLastIdealVelocities | ||
_this.unreadPropStyles = null; | ||
_this.startAnimationIfNecessary(); | ||
}); | ||
}; | ||
_this.unreadPropStyles = null; | ||
this.state = this.defaultState(); | ||
} | ||
_this.startAnimationIfNecessary(); | ||
StaggeredMotion.prototype.defaultState = function defaultState() { | ||
var _props = this.props; | ||
var defaultStyles = _props.defaultStyles; | ||
var styles = _props.styles; | ||
var currentStyles = defaultStyles || styles().map(_stripStyle2['default']); | ||
var currentVelocities = currentStyles.map(function (currentStyle) { | ||
return _mapToZero2['default'](currentStyle); | ||
}); | ||
}, | ||
return { | ||
currentStyles: currentStyles, | ||
currentVelocities: currentVelocities, | ||
lastIdealStyles: currentStyles, | ||
lastIdealVelocities: currentVelocities | ||
}; | ||
}; | ||
componentDidMount: function componentDidMount() { | ||
StaggeredMotion.prototype.componentDidMount = function componentDidMount() { | ||
this.prevTime = _performanceNow2['default'](); | ||
this.startAnimationIfNecessary(); | ||
}, | ||
}; | ||
componentWillReceiveProps: function componentWillReceiveProps(props) { | ||
StaggeredMotion.prototype.componentWillReceiveProps = function componentWillReceiveProps(props) { | ||
if (this.unreadPropStyles != null) { | ||
@@ -255,5 +263,5 @@ // previous props haven't had the chance to be set yet; set them here | ||
} | ||
}, | ||
}; | ||
componentWillUnmount: function componentWillUnmount() { | ||
StaggeredMotion.prototype.componentWillUnmount = function componentWillUnmount() { | ||
if (this.animationID != null) { | ||
@@ -263,11 +271,23 @@ _raf2['default'].cancel(this.animationID); | ||
} | ||
}, | ||
}; | ||
render: function render() { | ||
StaggeredMotion.prototype.render = function render() { | ||
var renderedChildren = this.props.children(this.state.currentStyles); | ||
return renderedChildren && _react2['default'].Children.only(renderedChildren); | ||
} | ||
}); | ||
}; | ||
return StaggeredMotion; | ||
})(_react2['default'].Component); | ||
exports['default'] = StaggeredMotion; | ||
module.exports = exports['default']; | ||
module.exports = exports['default']; | ||
// it's possible that currentStyle's value is stale: if props is immediately | ||
// changed from 0 to 400 to spring(0) again, the async currentStyle is still | ||
// at 0 (didn't have time to tick and interpolate even once). If we naively | ||
// compare currentStyle with destVal it'll be 0 === 0 (no animation, stop). | ||
// In reality currentStyle should be 400 | ||
// after checking for unreadPropStyles != null, we manually go set the | ||
// non-interpolating values (those that are a number, without a spring | ||
// config) |
@@ -7,4 +7,10 @@ 'use strict'; | ||
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; }; })(); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
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; } | ||
var _mapToZero = require('./mapToZero'); | ||
@@ -46,6 +52,2 @@ | ||
var _createReactClass = require('create-react-class'); | ||
var _createReactClass2 = _interopRequireDefault(_createReactClass); | ||
var msPerFrame = 1000 / 60; | ||
@@ -172,22 +174,27 @@ | ||
var TransitionMotion = _createReactClass2['default']({ | ||
propTypes: { | ||
defaultStyles: _propTypes2['default'].arrayOf(_propTypes2['default'].shape({ | ||
key: _propTypes2['default'].string.isRequired, | ||
data: _propTypes2['default'].any, | ||
style: _propTypes2['default'].objectOf(_propTypes2['default'].number).isRequired | ||
})), | ||
styles: _propTypes2['default'].oneOfType([_propTypes2['default'].func, _propTypes2['default'].arrayOf(_propTypes2['default'].shape({ | ||
key: _propTypes2['default'].string.isRequired, | ||
data: _propTypes2['default'].any, | ||
style: _propTypes2['default'].objectOf(_propTypes2['default'].oneOfType([_propTypes2['default'].number, _propTypes2['default'].object])).isRequired | ||
}))]).isRequired, | ||
children: _propTypes2['default'].func.isRequired, | ||
willEnter: _propTypes2['default'].func, | ||
willLeave: _propTypes2['default'].func, | ||
didLeave: _propTypes2['default'].func | ||
}, | ||
var TransitionMotion = (function (_React$Component) { | ||
_inherits(TransitionMotion, _React$Component); | ||
getDefaultProps: function getDefaultProps() { | ||
return { | ||
_createClass(TransitionMotion, null, [{ | ||
key: 'propTypes', | ||
value: { | ||
defaultStyles: _propTypes2['default'].arrayOf(_propTypes2['default'].shape({ | ||
key: _propTypes2['default'].string.isRequired, | ||
data: _propTypes2['default'].any, | ||
style: _propTypes2['default'].objectOf(_propTypes2['default'].number).isRequired | ||
})), | ||
styles: _propTypes2['default'].oneOfType([_propTypes2['default'].func, _propTypes2['default'].arrayOf(_propTypes2['default'].shape({ | ||
key: _propTypes2['default'].string.isRequired, | ||
data: _propTypes2['default'].any, | ||
style: _propTypes2['default'].objectOf(_propTypes2['default'].oneOfType([_propTypes2['default'].number, _propTypes2['default'].object])).isRequired | ||
}))]).isRequired, | ||
children: _propTypes2['default'].func.isRequired, | ||
willEnter: _propTypes2['default'].func, | ||
willLeave: _propTypes2['default'].func, | ||
didLeave: _propTypes2['default'].func | ||
}, | ||
enumerable: true | ||
}, { | ||
key: 'defaultProps', | ||
value: { | ||
willEnter: function willEnter(styleThatEntered) { | ||
@@ -202,6 +209,194 @@ return _stripStyle2['default'](styleThatEntered.style); | ||
didLeave: function didLeave() {} | ||
}, | ||
enumerable: true | ||
}]); | ||
function TransitionMotion(props) { | ||
var _this = this; | ||
_classCallCheck(this, TransitionMotion); | ||
_React$Component.call(this, props); | ||
this.unmounting = false; | ||
this.animationID = null; | ||
this.prevTime = 0; | ||
this.accumulatedTime = 0; | ||
this.unreadPropStyles = null; | ||
this.clearUnreadPropStyle = function (unreadPropStyles) { | ||
var _mergeAndSync = mergeAndSync(_this.props.willEnter, _this.props.willLeave, _this.props.didLeave, _this.state.mergedPropsStyles, unreadPropStyles, _this.state.currentStyles, _this.state.currentVelocities, _this.state.lastIdealStyles, _this.state.lastIdealVelocities); | ||
var mergedPropsStyles = _mergeAndSync[0]; | ||
var currentStyles = _mergeAndSync[1]; | ||
var currentVelocities = _mergeAndSync[2]; | ||
var lastIdealStyles = _mergeAndSync[3]; | ||
var lastIdealVelocities = _mergeAndSync[4]; | ||
for (var i = 0; i < unreadPropStyles.length; i++) { | ||
var unreadPropStyle = unreadPropStyles[i].style; | ||
var dirty = false; | ||
for (var key in unreadPropStyle) { | ||
if (!Object.prototype.hasOwnProperty.call(unreadPropStyle, key)) { | ||
continue; | ||
} | ||
var styleValue = unreadPropStyle[key]; | ||
if (typeof styleValue === 'number') { | ||
if (!dirty) { | ||
dirty = true; | ||
currentStyles[i] = _extends({}, currentStyles[i]); | ||
currentVelocities[i] = _extends({}, currentVelocities[i]); | ||
lastIdealStyles[i] = _extends({}, lastIdealStyles[i]); | ||
lastIdealVelocities[i] = _extends({}, lastIdealVelocities[i]); | ||
mergedPropsStyles[i] = { | ||
key: mergedPropsStyles[i].key, | ||
data: mergedPropsStyles[i].data, | ||
style: _extends({}, mergedPropsStyles[i].style) | ||
}; | ||
} | ||
currentStyles[i][key] = styleValue; | ||
currentVelocities[i][key] = 0; | ||
lastIdealStyles[i][key] = styleValue; | ||
lastIdealVelocities[i][key] = 0; | ||
mergedPropsStyles[i].style[key] = styleValue; | ||
} | ||
} | ||
} | ||
// unlike the other 2 components, we can't detect staleness and optionally | ||
// opt out of setState here. each style object's data might contain new | ||
// stuff we're not/cannot compare | ||
_this.setState({ | ||
currentStyles: currentStyles, | ||
currentVelocities: currentVelocities, | ||
mergedPropsStyles: mergedPropsStyles, | ||
lastIdealStyles: lastIdealStyles, | ||
lastIdealVelocities: lastIdealVelocities | ||
}); | ||
}; | ||
}, | ||
getInitialState: function getInitialState() { | ||
this.startAnimationIfNecessary = function () { | ||
if (_this.unmounting) { | ||
return; | ||
} | ||
// TODO: when config is {a: 10} and dest is {a: 10} do we raf once and | ||
// call cb? No, otherwise accidental parent rerender causes cb trigger | ||
_this.animationID = _raf2['default'](function (timestamp) { | ||
// https://github.com/chenglou/react-motion/pull/420 | ||
// > if execution passes the conditional if (this.unmounting), then | ||
// executes async defaultRaf and after that component unmounts and after | ||
// that the callback of defaultRaf is called, then setState will be called | ||
// on unmounted component. | ||
if (_this.unmounting) { | ||
return; | ||
} | ||
var propStyles = _this.props.styles; | ||
var destStyles = typeof propStyles === 'function' ? propStyles(rehydrateStyles(_this.state.mergedPropsStyles, _this.unreadPropStyles, _this.state.lastIdealStyles)) : propStyles; | ||
// check if we need to animate in the first place | ||
if (shouldStopAnimationAll(_this.state.currentStyles, destStyles, _this.state.currentVelocities, _this.state.mergedPropsStyles)) { | ||
// no need to cancel animationID here; shouldn't have any in flight | ||
_this.animationID = null; | ||
_this.accumulatedTime = 0; | ||
return; | ||
} | ||
var currentTime = timestamp || _performanceNow2['default'](); | ||
var timeDelta = currentTime - _this.prevTime; | ||
_this.prevTime = currentTime; | ||
_this.accumulatedTime = _this.accumulatedTime + timeDelta; | ||
// more than 10 frames? prolly switched browser tab. Restart | ||
if (_this.accumulatedTime > msPerFrame * 10) { | ||
_this.accumulatedTime = 0; | ||
} | ||
if (_this.accumulatedTime === 0) { | ||
// no need to cancel animationID here; shouldn't have any in flight | ||
_this.animationID = null; | ||
_this.startAnimationIfNecessary(); | ||
return; | ||
} | ||
var currentFrameCompletion = (_this.accumulatedTime - Math.floor(_this.accumulatedTime / msPerFrame) * msPerFrame) / msPerFrame; | ||
var framesToCatchUp = Math.floor(_this.accumulatedTime / msPerFrame); | ||
var _mergeAndSync2 = mergeAndSync(_this.props.willEnter, _this.props.willLeave, _this.props.didLeave, _this.state.mergedPropsStyles, destStyles, _this.state.currentStyles, _this.state.currentVelocities, _this.state.lastIdealStyles, _this.state.lastIdealVelocities); | ||
var newMergedPropsStyles = _mergeAndSync2[0]; | ||
var newCurrentStyles = _mergeAndSync2[1]; | ||
var newCurrentVelocities = _mergeAndSync2[2]; | ||
var newLastIdealStyles = _mergeAndSync2[3]; | ||
var newLastIdealVelocities = _mergeAndSync2[4]; | ||
for (var i = 0; i < newMergedPropsStyles.length; i++) { | ||
var newMergedPropsStyle = newMergedPropsStyles[i].style; | ||
var newCurrentStyle = {}; | ||
var newCurrentVelocity = {}; | ||
var newLastIdealStyle = {}; | ||
var newLastIdealVelocity = {}; | ||
for (var key in newMergedPropsStyle) { | ||
if (!Object.prototype.hasOwnProperty.call(newMergedPropsStyle, key)) { | ||
continue; | ||
} | ||
var styleValue = newMergedPropsStyle[key]; | ||
if (typeof styleValue === 'number') { | ||
newCurrentStyle[key] = styleValue; | ||
newCurrentVelocity[key] = 0; | ||
newLastIdealStyle[key] = styleValue; | ||
newLastIdealVelocity[key] = 0; | ||
} else { | ||
var newLastIdealStyleValue = newLastIdealStyles[i][key]; | ||
var newLastIdealVelocityValue = newLastIdealVelocities[i][key]; | ||
for (var j = 0; j < framesToCatchUp; j++) { | ||
var _stepper = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); | ||
newLastIdealStyleValue = _stepper[0]; | ||
newLastIdealVelocityValue = _stepper[1]; | ||
} | ||
var _stepper2 = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); | ||
var nextIdealX = _stepper2[0]; | ||
var nextIdealV = _stepper2[1]; | ||
newCurrentStyle[key] = newLastIdealStyleValue + (nextIdealX - newLastIdealStyleValue) * currentFrameCompletion; | ||
newCurrentVelocity[key] = newLastIdealVelocityValue + (nextIdealV - newLastIdealVelocityValue) * currentFrameCompletion; | ||
newLastIdealStyle[key] = newLastIdealStyleValue; | ||
newLastIdealVelocity[key] = newLastIdealVelocityValue; | ||
} | ||
} | ||
newLastIdealStyles[i] = newLastIdealStyle; | ||
newLastIdealVelocities[i] = newLastIdealVelocity; | ||
newCurrentStyles[i] = newCurrentStyle; | ||
newCurrentVelocities[i] = newCurrentVelocity; | ||
} | ||
_this.animationID = null; | ||
// the amount we're looped over above | ||
_this.accumulatedTime -= framesToCatchUp * msPerFrame; | ||
_this.setState({ | ||
currentStyles: newCurrentStyles, | ||
currentVelocities: newCurrentVelocities, | ||
lastIdealStyles: newLastIdealStyles, | ||
lastIdealVelocities: newLastIdealVelocities, | ||
mergedPropsStyles: newMergedPropsStyles | ||
}); | ||
_this.unreadPropStyles = null; | ||
_this.startAnimationIfNecessary(); | ||
}); | ||
}; | ||
this.state = this.defaultState(); | ||
} | ||
TransitionMotion.prototype.defaultState = function defaultState() { | ||
var _props = this.props; | ||
@@ -245,3 +440,3 @@ var defaultStyles = _props.defaultStyles; | ||
var _mergeAndSync = mergeAndSync( | ||
var _mergeAndSync3 = mergeAndSync( | ||
// Because this is an old-style createReactClass component, Flow doesn't | ||
@@ -253,7 +448,7 @@ // understand that the willEnter and willLeave props have default values | ||
var mergedPropsStyles = _mergeAndSync[0]; | ||
var currentStyles = _mergeAndSync[1]; | ||
var currentVelocities = _mergeAndSync[2]; | ||
var lastIdealStyles = _mergeAndSync[3]; | ||
var lastIdealVelocities = _mergeAndSync[4]; | ||
var mergedPropsStyles = _mergeAndSync3[0]; | ||
var currentStyles = _mergeAndSync3[1]; | ||
var currentVelocities = _mergeAndSync3[2]; | ||
var lastIdealStyles = _mergeAndSync3[3]; | ||
var lastIdealVelocities = _mergeAndSync3[4]; | ||
// oldLastIdealVelocities really | ||
@@ -268,197 +463,14 @@ | ||
}; | ||
}, | ||
}; | ||
unmounting: false, | ||
animationID: null, | ||
prevTime: 0, | ||
accumulatedTime: 0, | ||
// it's possible that currentStyle's value is stale: if props is immediately | ||
// changed from 0 to 400 to spring(0) again, the async currentStyle is still | ||
// at 0 (didn't have time to tick and interpolate even once). If we naively | ||
// compare currentStyle with destVal it'll be 0 === 0 (no animation, stop). | ||
// In reality currentStyle should be 400 | ||
unreadPropStyles: null, | ||
// after checking for unreadPropStyles != null, we manually go set the | ||
// non-interpolating values (those that are a number, without a spring | ||
// config) | ||
clearUnreadPropStyle: function clearUnreadPropStyle(unreadPropStyles) { | ||
var _mergeAndSync2 = mergeAndSync(this.props.willEnter, this.props.willLeave, this.props.didLeave, this.state.mergedPropsStyles, unreadPropStyles, this.state.currentStyles, this.state.currentVelocities, this.state.lastIdealStyles, this.state.lastIdealVelocities); | ||
var mergedPropsStyles = _mergeAndSync2[0]; | ||
var currentStyles = _mergeAndSync2[1]; | ||
var currentVelocities = _mergeAndSync2[2]; | ||
var lastIdealStyles = _mergeAndSync2[3]; | ||
var lastIdealVelocities = _mergeAndSync2[4]; | ||
for (var i = 0; i < unreadPropStyles.length; i++) { | ||
var unreadPropStyle = unreadPropStyles[i].style; | ||
var dirty = false; | ||
for (var key in unreadPropStyle) { | ||
if (!Object.prototype.hasOwnProperty.call(unreadPropStyle, key)) { | ||
continue; | ||
} | ||
var styleValue = unreadPropStyle[key]; | ||
if (typeof styleValue === 'number') { | ||
if (!dirty) { | ||
dirty = true; | ||
currentStyles[i] = _extends({}, currentStyles[i]); | ||
currentVelocities[i] = _extends({}, currentVelocities[i]); | ||
lastIdealStyles[i] = _extends({}, lastIdealStyles[i]); | ||
lastIdealVelocities[i] = _extends({}, lastIdealVelocities[i]); | ||
mergedPropsStyles[i] = { | ||
key: mergedPropsStyles[i].key, | ||
data: mergedPropsStyles[i].data, | ||
style: _extends({}, mergedPropsStyles[i].style) | ||
}; | ||
} | ||
currentStyles[i][key] = styleValue; | ||
currentVelocities[i][key] = 0; | ||
lastIdealStyles[i][key] = styleValue; | ||
lastIdealVelocities[i][key] = 0; | ||
mergedPropsStyles[i].style[key] = styleValue; | ||
} | ||
} | ||
} | ||
// unlike the other 2 components, we can't detect staleness and optionally | ||
// opt out of setState here. each style object's data might contain new | ||
// stuff we're not/cannot compare | ||
this.setState({ | ||
currentStyles: currentStyles, | ||
currentVelocities: currentVelocities, | ||
mergedPropsStyles: mergedPropsStyles, | ||
lastIdealStyles: lastIdealStyles, | ||
lastIdealVelocities: lastIdealVelocities | ||
}); | ||
}, | ||
startAnimationIfNecessary: function startAnimationIfNecessary() { | ||
var _this = this; | ||
if (this.unmounting) { | ||
return; | ||
} | ||
// TODO: when config is {a: 10} and dest is {a: 10} do we raf once and | ||
// call cb? No, otherwise accidental parent rerender causes cb trigger | ||
this.animationID = _raf2['default'](function (timestamp) { | ||
// https://github.com/chenglou/react-motion/pull/420 | ||
// > if execution passes the conditional if (this.unmounting), then | ||
// executes async defaultRaf and after that component unmounts and after | ||
// that the callback of defaultRaf is called, then setState will be called | ||
// on unmounted component. | ||
if (_this.unmounting) { | ||
return; | ||
} | ||
var propStyles = _this.props.styles; | ||
var destStyles = typeof propStyles === 'function' ? propStyles(rehydrateStyles(_this.state.mergedPropsStyles, _this.unreadPropStyles, _this.state.lastIdealStyles)) : propStyles; | ||
// check if we need to animate in the first place | ||
if (shouldStopAnimationAll(_this.state.currentStyles, destStyles, _this.state.currentVelocities, _this.state.mergedPropsStyles)) { | ||
// no need to cancel animationID here; shouldn't have any in flight | ||
_this.animationID = null; | ||
_this.accumulatedTime = 0; | ||
return; | ||
} | ||
var currentTime = timestamp || _performanceNow2['default'](); | ||
var timeDelta = currentTime - _this.prevTime; | ||
_this.prevTime = currentTime; | ||
_this.accumulatedTime = _this.accumulatedTime + timeDelta; | ||
// more than 10 frames? prolly switched browser tab. Restart | ||
if (_this.accumulatedTime > msPerFrame * 10) { | ||
_this.accumulatedTime = 0; | ||
} | ||
if (_this.accumulatedTime === 0) { | ||
// no need to cancel animationID here; shouldn't have any in flight | ||
_this.animationID = null; | ||
_this.startAnimationIfNecessary(); | ||
return; | ||
} | ||
var currentFrameCompletion = (_this.accumulatedTime - Math.floor(_this.accumulatedTime / msPerFrame) * msPerFrame) / msPerFrame; | ||
var framesToCatchUp = Math.floor(_this.accumulatedTime / msPerFrame); | ||
var _mergeAndSync3 = mergeAndSync(_this.props.willEnter, _this.props.willLeave, _this.props.didLeave, _this.state.mergedPropsStyles, destStyles, _this.state.currentStyles, _this.state.currentVelocities, _this.state.lastIdealStyles, _this.state.lastIdealVelocities); | ||
var newMergedPropsStyles = _mergeAndSync3[0]; | ||
var newCurrentStyles = _mergeAndSync3[1]; | ||
var newCurrentVelocities = _mergeAndSync3[2]; | ||
var newLastIdealStyles = _mergeAndSync3[3]; | ||
var newLastIdealVelocities = _mergeAndSync3[4]; | ||
for (var i = 0; i < newMergedPropsStyles.length; i++) { | ||
var newMergedPropsStyle = newMergedPropsStyles[i].style; | ||
var newCurrentStyle = {}; | ||
var newCurrentVelocity = {}; | ||
var newLastIdealStyle = {}; | ||
var newLastIdealVelocity = {}; | ||
for (var key in newMergedPropsStyle) { | ||
if (!Object.prototype.hasOwnProperty.call(newMergedPropsStyle, key)) { | ||
continue; | ||
} | ||
var styleValue = newMergedPropsStyle[key]; | ||
if (typeof styleValue === 'number') { | ||
newCurrentStyle[key] = styleValue; | ||
newCurrentVelocity[key] = 0; | ||
newLastIdealStyle[key] = styleValue; | ||
newLastIdealVelocity[key] = 0; | ||
} else { | ||
var newLastIdealStyleValue = newLastIdealStyles[i][key]; | ||
var newLastIdealVelocityValue = newLastIdealVelocities[i][key]; | ||
for (var j = 0; j < framesToCatchUp; j++) { | ||
var _stepper = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); | ||
newLastIdealStyleValue = _stepper[0]; | ||
newLastIdealVelocityValue = _stepper[1]; | ||
} | ||
var _stepper2 = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision); | ||
var nextIdealX = _stepper2[0]; | ||
var nextIdealV = _stepper2[1]; | ||
newCurrentStyle[key] = newLastIdealStyleValue + (nextIdealX - newLastIdealStyleValue) * currentFrameCompletion; | ||
newCurrentVelocity[key] = newLastIdealVelocityValue + (nextIdealV - newLastIdealVelocityValue) * currentFrameCompletion; | ||
newLastIdealStyle[key] = newLastIdealStyleValue; | ||
newLastIdealVelocity[key] = newLastIdealVelocityValue; | ||
} | ||
} | ||
newLastIdealStyles[i] = newLastIdealStyle; | ||
newLastIdealVelocities[i] = newLastIdealVelocity; | ||
newCurrentStyles[i] = newCurrentStyle; | ||
newCurrentVelocities[i] = newCurrentVelocity; | ||
} | ||
_this.animationID = null; | ||
// the amount we're looped over above | ||
_this.accumulatedTime -= framesToCatchUp * msPerFrame; | ||
_this.setState({ | ||
currentStyles: newCurrentStyles, | ||
currentVelocities: newCurrentVelocities, | ||
lastIdealStyles: newLastIdealStyles, | ||
lastIdealVelocities: newLastIdealVelocities, | ||
mergedPropsStyles: newMergedPropsStyles | ||
}); | ||
_this.unreadPropStyles = null; | ||
_this.startAnimationIfNecessary(); | ||
}); | ||
}, | ||
componentDidMount: function componentDidMount() { | ||
TransitionMotion.prototype.componentDidMount = function componentDidMount() { | ||
this.prevTime = _performanceNow2['default'](); | ||
this.startAnimationIfNecessary(); | ||
}, | ||
}; | ||
componentWillReceiveProps: function componentWillReceiveProps(props) { | ||
TransitionMotion.prototype.componentWillReceiveProps = function componentWillReceiveProps(props) { | ||
if (this.unreadPropStyles) { | ||
@@ -480,5 +492,5 @@ // previous props haven't had the chance to be set yet; set them here | ||
} | ||
}, | ||
}; | ||
componentWillUnmount: function componentWillUnmount() { | ||
TransitionMotion.prototype.componentWillUnmount = function componentWillUnmount() { | ||
this.unmounting = true; | ||
@@ -489,11 +501,13 @@ if (this.animationID != null) { | ||
} | ||
}, | ||
}; | ||
render: function render() { | ||
TransitionMotion.prototype.render = function render() { | ||
var hydratedStyles = rehydrateStyles(this.state.mergedPropsStyles, this.unreadPropStyles, this.state.currentStyles); | ||
var renderedChildren = this.props.children(hydratedStyles); | ||
return renderedChildren && _react2['default'].Children.only(renderedChildren); | ||
} | ||
}); | ||
}; | ||
return TransitionMotion; | ||
})(_react2['default'].Component); | ||
exports['default'] = TransitionMotion; | ||
@@ -511,2 +525,8 @@ module.exports = exports['default']; | ||
// the array that keeps track of currently rendered stuff! Including stuff | ||
// that you've unmounted but that's still animating. This is where it lives | ||
// that you've unmounted but that's still animating. This is where it lives | ||
// it's possible that currentStyle's value is stale: if props is immediately | ||
// changed from 0 to 400 to spring(0) again, the async currentStyle is still | ||
// at 0 (didn't have time to tick and interpolate even once). If we naively | ||
// compare currentStyle with destVal it'll be 0 === 0 (no animation, stop). | ||
// In reality currentStyle should be 400 |
{ | ||
"name": "react-motion", | ||
"version": "0.4.8", | ||
"version": "0.5.0", | ||
"description": "A spring that solves your animation problems.", | ||
"main": "lib/react-motion.js", | ||
"peerDependencies": { | ||
"react": ">=0.13.2 || ^0.14 || ^15.0.0" | ||
"react": "^0.14.9 || ^15.3.0" | ||
}, | ||
@@ -36,6 +36,5 @@ "devDependencies": { | ||
"phantomjs": "^1.9.17", | ||
"react": ">=15.0.1", | ||
"react-addons-test-utils": "^15.0.1", | ||
"react": ">=15.5.0", | ||
"react-codemirror": ">=0.1.2", | ||
"react-dom": ">=15.0.1", | ||
"react-dom": ">=15.5.0", | ||
"react-hot-loader": "^1.2.8", | ||
@@ -77,3 +76,2 @@ "style-loader": "^0.12.4", | ||
"dependencies": { | ||
"create-react-class": "^15.5.2", | ||
"performance-now": "^0.2.0", | ||
@@ -80,0 +78,0 @@ "prop-types": "^15.5.8", |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
4
33
11
0
368195
3352
+ Addedasap@2.0.6(transitive)
+ Addedcore-js@1.2.7(transitive)
+ Addedencoding@0.1.13(transitive)
+ Addedfbjs@0.8.18(transitive)
+ Addediconv-lite@0.6.3(transitive)
+ Addedis-stream@1.1.0(transitive)
+ Addedisomorphic-fetch@2.2.1(transitive)
+ Addednode-fetch@1.7.3(transitive)
+ Addedpromise@7.3.1(transitive)
+ Addedreact@15.7.0(transitive)
+ Addedsafer-buffer@2.1.2(transitive)
+ Addedsetimmediate@1.0.5(transitive)
+ Addedua-parser-js@0.7.39(transitive)
+ Addedwhatwg-fetch@3.6.20(transitive)
- Removedcreate-react-class@^15.5.2
- Removedreact@18.3.1(transitive)