Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

3 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. 'use strict';
  2. exports.__esModule = true;
  3. 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; };
  4. 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; }; })();
  5. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  6. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
  7. 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; }
  8. var _mapToZero = require('./mapToZero');
  9. var _mapToZero2 = _interopRequireDefault(_mapToZero);
  10. var _stripStyle = require('./stripStyle');
  11. var _stripStyle2 = _interopRequireDefault(_stripStyle);
  12. var _stepper3 = require('./stepper');
  13. var _stepper4 = _interopRequireDefault(_stepper3);
  14. var _mergeDiff = require('./mergeDiff');
  15. var _mergeDiff2 = _interopRequireDefault(_mergeDiff);
  16. var _performanceNow = require('performance-now');
  17. var _performanceNow2 = _interopRequireDefault(_performanceNow);
  18. var _raf = require('raf');
  19. var _raf2 = _interopRequireDefault(_raf);
  20. var _shouldStopAnimation = require('./shouldStopAnimation');
  21. var _shouldStopAnimation2 = _interopRequireDefault(_shouldStopAnimation);
  22. var _react = require('react');
  23. var _react2 = _interopRequireDefault(_react);
  24. var _propTypes = require('prop-types');
  25. var _propTypes2 = _interopRequireDefault(_propTypes);
  26. var msPerFrame = 1000 / 60;
  27. // the children function & (potential) styles function asks as param an
  28. // Array<TransitionPlainStyle>, where each TransitionPlainStyle is of the format
  29. // {key: string, data?: any, style: PlainStyle}. However, the way we keep
  30. // internal states doesn't contain such a data structure (check the state and
  31. // TransitionMotionState). So when children function and others ask for such
  32. // data we need to generate them on the fly by combining mergedPropsStyles and
  33. // currentStyles/lastIdealStyles
  34. function rehydrateStyles(mergedPropsStyles, unreadPropStyles, plainStyles) {
  35. // Copy the value to a `const` so that Flow understands that the const won't
  36. // change and will be non-nullable in the callback below.
  37. var cUnreadPropStyles = unreadPropStyles;
  38. if (cUnreadPropStyles == null) {
  39. return mergedPropsStyles.map(function (mergedPropsStyle, i) {
  40. return {
  41. key: mergedPropsStyle.key,
  42. data: mergedPropsStyle.data,
  43. style: plainStyles[i]
  44. };
  45. });
  46. }
  47. return mergedPropsStyles.map(function (mergedPropsStyle, i) {
  48. for (var j = 0; j < cUnreadPropStyles.length; j++) {
  49. if (cUnreadPropStyles[j].key === mergedPropsStyle.key) {
  50. return {
  51. key: cUnreadPropStyles[j].key,
  52. data: cUnreadPropStyles[j].data,
  53. style: plainStyles[i]
  54. };
  55. }
  56. }
  57. return { key: mergedPropsStyle.key, data: mergedPropsStyle.data, style: plainStyles[i] };
  58. });
  59. }
  60. function shouldStopAnimationAll(currentStyles, destStyles, currentVelocities, mergedPropsStyles) {
  61. if (mergedPropsStyles.length !== destStyles.length) {
  62. return false;
  63. }
  64. for (var i = 0; i < mergedPropsStyles.length; i++) {
  65. if (mergedPropsStyles[i].key !== destStyles[i].key) {
  66. return false;
  67. }
  68. }
  69. // we have the invariant that mergedPropsStyles and
  70. // currentStyles/currentVelocities/last* are synced in terms of cells, see
  71. // mergeAndSync comment for more info
  72. for (var i = 0; i < mergedPropsStyles.length; i++) {
  73. if (!_shouldStopAnimation2['default'](currentStyles[i], destStyles[i].style, currentVelocities[i])) {
  74. return false;
  75. }
  76. }
  77. return true;
  78. }
  79. // core key merging logic
  80. // things to do: say previously merged style is {a, b}, dest style (prop) is {b,
  81. // c}, previous current (interpolating) style is {a, b}
  82. // **invariant**: current[i] corresponds to merged[i] in terms of key
  83. // steps:
  84. // turn merged style into {a?, b, c}
  85. // add c, value of c is destStyles.c
  86. // maybe remove a, aka call willLeave(a), then merged is either {b, c} or {a, b, c}
  87. // turn current (interpolating) style from {a, b} into {a?, b, c}
  88. // maybe remove a
  89. // certainly add c, value of c is willEnter(c)
  90. // loop over merged and construct new current
  91. // dest doesn't change, that's owner's
  92. function mergeAndSync(willEnter, willLeave, didLeave, oldMergedPropsStyles, destStyles, oldCurrentStyles, oldCurrentVelocities, oldLastIdealStyles, oldLastIdealVelocities) {
  93. var newMergedPropsStyles = _mergeDiff2['default'](oldMergedPropsStyles, destStyles, function (oldIndex, oldMergedPropsStyle) {
  94. var leavingStyle = willLeave(oldMergedPropsStyle);
  95. if (leavingStyle == null) {
  96. didLeave({ key: oldMergedPropsStyle.key, data: oldMergedPropsStyle.data });
  97. return null;
  98. }
  99. if (_shouldStopAnimation2['default'](oldCurrentStyles[oldIndex], leavingStyle, oldCurrentVelocities[oldIndex])) {
  100. didLeave({ key: oldMergedPropsStyle.key, data: oldMergedPropsStyle.data });
  101. return null;
  102. }
  103. return { key: oldMergedPropsStyle.key, data: oldMergedPropsStyle.data, style: leavingStyle };
  104. });
  105. var newCurrentStyles = [];
  106. var newCurrentVelocities = [];
  107. var newLastIdealStyles = [];
  108. var newLastIdealVelocities = [];
  109. for (var i = 0; i < newMergedPropsStyles.length; i++) {
  110. var newMergedPropsStyleCell = newMergedPropsStyles[i];
  111. var foundOldIndex = null;
  112. for (var j = 0; j < oldMergedPropsStyles.length; j++) {
  113. if (oldMergedPropsStyles[j].key === newMergedPropsStyleCell.key) {
  114. foundOldIndex = j;
  115. break;
  116. }
  117. }
  118. // TODO: key search code
  119. if (foundOldIndex == null) {
  120. var plainStyle = willEnter(newMergedPropsStyleCell);
  121. newCurrentStyles[i] = plainStyle;
  122. newLastIdealStyles[i] = plainStyle;
  123. var velocity = _mapToZero2['default'](newMergedPropsStyleCell.style);
  124. newCurrentVelocities[i] = velocity;
  125. newLastIdealVelocities[i] = velocity;
  126. } else {
  127. newCurrentStyles[i] = oldCurrentStyles[foundOldIndex];
  128. newLastIdealStyles[i] = oldLastIdealStyles[foundOldIndex];
  129. newCurrentVelocities[i] = oldCurrentVelocities[foundOldIndex];
  130. newLastIdealVelocities[i] = oldLastIdealVelocities[foundOldIndex];
  131. }
  132. }
  133. return [newMergedPropsStyles, newCurrentStyles, newCurrentVelocities, newLastIdealStyles, newLastIdealVelocities];
  134. }
  135. var TransitionMotion = (function (_React$Component) {
  136. _inherits(TransitionMotion, _React$Component);
  137. _createClass(TransitionMotion, null, [{
  138. key: 'propTypes',
  139. value: {
  140. defaultStyles: _propTypes2['default'].arrayOf(_propTypes2['default'].shape({
  141. key: _propTypes2['default'].string.isRequired,
  142. data: _propTypes2['default'].any,
  143. style: _propTypes2['default'].objectOf(_propTypes2['default'].number).isRequired
  144. })),
  145. styles: _propTypes2['default'].oneOfType([_propTypes2['default'].func, _propTypes2['default'].arrayOf(_propTypes2['default'].shape({
  146. key: _propTypes2['default'].string.isRequired,
  147. data: _propTypes2['default'].any,
  148. style: _propTypes2['default'].objectOf(_propTypes2['default'].oneOfType([_propTypes2['default'].number, _propTypes2['default'].object])).isRequired
  149. }))]).isRequired,
  150. children: _propTypes2['default'].func.isRequired,
  151. willEnter: _propTypes2['default'].func,
  152. willLeave: _propTypes2['default'].func,
  153. didLeave: _propTypes2['default'].func
  154. },
  155. enumerable: true
  156. }, {
  157. key: 'defaultProps',
  158. value: {
  159. willEnter: function willEnter(styleThatEntered) {
  160. return _stripStyle2['default'](styleThatEntered.style);
  161. },
  162. // recall: returning null makes the current unmounting TransitionStyle
  163. // disappear immediately
  164. willLeave: function willLeave() {
  165. return null;
  166. },
  167. didLeave: function didLeave() {}
  168. },
  169. enumerable: true
  170. }]);
  171. function TransitionMotion(props) {
  172. var _this = this;
  173. _classCallCheck(this, TransitionMotion);
  174. _React$Component.call(this, props);
  175. this.unmounting = false;
  176. this.animationID = null;
  177. this.prevTime = 0;
  178. this.accumulatedTime = 0;
  179. this.unreadPropStyles = null;
  180. this.clearUnreadPropStyle = function (unreadPropStyles) {
  181. 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);
  182. var mergedPropsStyles = _mergeAndSync[0];
  183. var currentStyles = _mergeAndSync[1];
  184. var currentVelocities = _mergeAndSync[2];
  185. var lastIdealStyles = _mergeAndSync[3];
  186. var lastIdealVelocities = _mergeAndSync[4];
  187. for (var i = 0; i < unreadPropStyles.length; i++) {
  188. var unreadPropStyle = unreadPropStyles[i].style;
  189. var dirty = false;
  190. for (var key in unreadPropStyle) {
  191. if (!Object.prototype.hasOwnProperty.call(unreadPropStyle, key)) {
  192. continue;
  193. }
  194. var styleValue = unreadPropStyle[key];
  195. if (typeof styleValue === 'number') {
  196. if (!dirty) {
  197. dirty = true;
  198. currentStyles[i] = _extends({}, currentStyles[i]);
  199. currentVelocities[i] = _extends({}, currentVelocities[i]);
  200. lastIdealStyles[i] = _extends({}, lastIdealStyles[i]);
  201. lastIdealVelocities[i] = _extends({}, lastIdealVelocities[i]);
  202. mergedPropsStyles[i] = {
  203. key: mergedPropsStyles[i].key,
  204. data: mergedPropsStyles[i].data,
  205. style: _extends({}, mergedPropsStyles[i].style)
  206. };
  207. }
  208. currentStyles[i][key] = styleValue;
  209. currentVelocities[i][key] = 0;
  210. lastIdealStyles[i][key] = styleValue;
  211. lastIdealVelocities[i][key] = 0;
  212. mergedPropsStyles[i].style[key] = styleValue;
  213. }
  214. }
  215. }
  216. // unlike the other 2 components, we can't detect staleness and optionally
  217. // opt out of setState here. each style object's data might contain new
  218. // stuff we're not/cannot compare
  219. _this.setState({
  220. currentStyles: currentStyles,
  221. currentVelocities: currentVelocities,
  222. mergedPropsStyles: mergedPropsStyles,
  223. lastIdealStyles: lastIdealStyles,
  224. lastIdealVelocities: lastIdealVelocities
  225. });
  226. };
  227. this.startAnimationIfNecessary = function () {
  228. if (_this.unmounting) {
  229. return;
  230. }
  231. // TODO: when config is {a: 10} and dest is {a: 10} do we raf once and
  232. // call cb? No, otherwise accidental parent rerender causes cb trigger
  233. _this.animationID = _raf2['default'](function (timestamp) {
  234. // https://github.com/chenglou/react-motion/pull/420
  235. // > if execution passes the conditional if (this.unmounting), then
  236. // executes async defaultRaf and after that component unmounts and after
  237. // that the callback of defaultRaf is called, then setState will be called
  238. // on unmounted component.
  239. if (_this.unmounting) {
  240. return;
  241. }
  242. var propStyles = _this.props.styles;
  243. var destStyles = typeof propStyles === 'function' ? propStyles(rehydrateStyles(_this.state.mergedPropsStyles, _this.unreadPropStyles, _this.state.lastIdealStyles)) : propStyles;
  244. // check if we need to animate in the first place
  245. if (shouldStopAnimationAll(_this.state.currentStyles, destStyles, _this.state.currentVelocities, _this.state.mergedPropsStyles)) {
  246. // no need to cancel animationID here; shouldn't have any in flight
  247. _this.animationID = null;
  248. _this.accumulatedTime = 0;
  249. return;
  250. }
  251. var currentTime = timestamp || _performanceNow2['default']();
  252. var timeDelta = currentTime - _this.prevTime;
  253. _this.prevTime = currentTime;
  254. _this.accumulatedTime = _this.accumulatedTime + timeDelta;
  255. // more than 10 frames? prolly switched browser tab. Restart
  256. if (_this.accumulatedTime > msPerFrame * 10) {
  257. _this.accumulatedTime = 0;
  258. }
  259. if (_this.accumulatedTime === 0) {
  260. // no need to cancel animationID here; shouldn't have any in flight
  261. _this.animationID = null;
  262. _this.startAnimationIfNecessary();
  263. return;
  264. }
  265. var currentFrameCompletion = (_this.accumulatedTime - Math.floor(_this.accumulatedTime / msPerFrame) * msPerFrame) / msPerFrame;
  266. var framesToCatchUp = Math.floor(_this.accumulatedTime / msPerFrame);
  267. 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);
  268. var newMergedPropsStyles = _mergeAndSync2[0];
  269. var newCurrentStyles = _mergeAndSync2[1];
  270. var newCurrentVelocities = _mergeAndSync2[2];
  271. var newLastIdealStyles = _mergeAndSync2[3];
  272. var newLastIdealVelocities = _mergeAndSync2[4];
  273. for (var i = 0; i < newMergedPropsStyles.length; i++) {
  274. var newMergedPropsStyle = newMergedPropsStyles[i].style;
  275. var newCurrentStyle = {};
  276. var newCurrentVelocity = {};
  277. var newLastIdealStyle = {};
  278. var newLastIdealVelocity = {};
  279. for (var key in newMergedPropsStyle) {
  280. if (!Object.prototype.hasOwnProperty.call(newMergedPropsStyle, key)) {
  281. continue;
  282. }
  283. var styleValue = newMergedPropsStyle[key];
  284. if (typeof styleValue === 'number') {
  285. newCurrentStyle[key] = styleValue;
  286. newCurrentVelocity[key] = 0;
  287. newLastIdealStyle[key] = styleValue;
  288. newLastIdealVelocity[key] = 0;
  289. } else {
  290. var newLastIdealStyleValue = newLastIdealStyles[i][key];
  291. var newLastIdealVelocityValue = newLastIdealVelocities[i][key];
  292. for (var j = 0; j < framesToCatchUp; j++) {
  293. var _stepper = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision);
  294. newLastIdealStyleValue = _stepper[0];
  295. newLastIdealVelocityValue = _stepper[1];
  296. }
  297. var _stepper2 = _stepper4['default'](msPerFrame / 1000, newLastIdealStyleValue, newLastIdealVelocityValue, styleValue.val, styleValue.stiffness, styleValue.damping, styleValue.precision);
  298. var nextIdealX = _stepper2[0];
  299. var nextIdealV = _stepper2[1];
  300. newCurrentStyle[key] = newLastIdealStyleValue + (nextIdealX - newLastIdealStyleValue) * currentFrameCompletion;
  301. newCurrentVelocity[key] = newLastIdealVelocityValue + (nextIdealV - newLastIdealVelocityValue) * currentFrameCompletion;
  302. newLastIdealStyle[key] = newLastIdealStyleValue;
  303. newLastIdealVelocity[key] = newLastIdealVelocityValue;
  304. }
  305. }
  306. newLastIdealStyles[i] = newLastIdealStyle;
  307. newLastIdealVelocities[i] = newLastIdealVelocity;
  308. newCurrentStyles[i] = newCurrentStyle;
  309. newCurrentVelocities[i] = newCurrentVelocity;
  310. }
  311. _this.animationID = null;
  312. // the amount we're looped over above
  313. _this.accumulatedTime -= framesToCatchUp * msPerFrame;
  314. _this.setState({
  315. currentStyles: newCurrentStyles,
  316. currentVelocities: newCurrentVelocities,
  317. lastIdealStyles: newLastIdealStyles,
  318. lastIdealVelocities: newLastIdealVelocities,
  319. mergedPropsStyles: newMergedPropsStyles
  320. });
  321. _this.unreadPropStyles = null;
  322. _this.startAnimationIfNecessary();
  323. });
  324. };
  325. this.state = this.defaultState();
  326. }
  327. TransitionMotion.prototype.defaultState = function defaultState() {
  328. var _props = this.props;
  329. var defaultStyles = _props.defaultStyles;
  330. var styles = _props.styles;
  331. var willEnter = _props.willEnter;
  332. var willLeave = _props.willLeave;
  333. var didLeave = _props.didLeave;
  334. var destStyles = typeof styles === 'function' ? styles(defaultStyles) : styles;
  335. // this is special. for the first time around, we don't have a comparison
  336. // between last (no last) and current merged props. we'll compute last so:
  337. // say default is {a, b} and styles (dest style) is {b, c}, we'll
  338. // fabricate last as {a, b}
  339. var oldMergedPropsStyles = undefined;
  340. if (defaultStyles == null) {
  341. oldMergedPropsStyles = destStyles;
  342. } else {
  343. oldMergedPropsStyles = defaultStyles.map(function (defaultStyleCell) {
  344. // TODO: key search code
  345. for (var i = 0; i < destStyles.length; i++) {
  346. if (destStyles[i].key === defaultStyleCell.key) {
  347. return destStyles[i];
  348. }
  349. }
  350. return defaultStyleCell;
  351. });
  352. }
  353. var oldCurrentStyles = defaultStyles == null ? destStyles.map(function (s) {
  354. return _stripStyle2['default'](s.style);
  355. }) : defaultStyles.map(function (s) {
  356. return _stripStyle2['default'](s.style);
  357. });
  358. var oldCurrentVelocities = defaultStyles == null ? destStyles.map(function (s) {
  359. return _mapToZero2['default'](s.style);
  360. }) : defaultStyles.map(function (s) {
  361. return _mapToZero2['default'](s.style);
  362. });
  363. var _mergeAndSync3 = mergeAndSync(
  364. // Because this is an old-style createReactClass component, Flow doesn't
  365. // understand that the willEnter and willLeave props have default values
  366. // and will always be present.
  367. willEnter, willLeave, didLeave, oldMergedPropsStyles, destStyles, oldCurrentStyles, oldCurrentVelocities, oldCurrentStyles, // oldLastIdealStyles really
  368. oldCurrentVelocities);
  369. var mergedPropsStyles = _mergeAndSync3[0];
  370. var currentStyles = _mergeAndSync3[1];
  371. var currentVelocities = _mergeAndSync3[2];
  372. var lastIdealStyles = _mergeAndSync3[3];
  373. var lastIdealVelocities = _mergeAndSync3[4];
  374. // oldLastIdealVelocities really
  375. return {
  376. currentStyles: currentStyles,
  377. currentVelocities: currentVelocities,
  378. lastIdealStyles: lastIdealStyles,
  379. lastIdealVelocities: lastIdealVelocities,
  380. mergedPropsStyles: mergedPropsStyles
  381. };
  382. };
  383. // after checking for unreadPropStyles != null, we manually go set the
  384. // non-interpolating values (those that are a number, without a spring
  385. // config)
  386. TransitionMotion.prototype.componentDidMount = function componentDidMount() {
  387. this.prevTime = _performanceNow2['default']();
  388. this.startAnimationIfNecessary();
  389. };
  390. TransitionMotion.prototype.componentWillReceiveProps = function componentWillReceiveProps(props) {
  391. if (this.unreadPropStyles) {
  392. // previous props haven't had the chance to be set yet; set them here
  393. this.clearUnreadPropStyle(this.unreadPropStyles);
  394. }
  395. var styles = props.styles;
  396. if (typeof styles === 'function') {
  397. this.unreadPropStyles = styles(rehydrateStyles(this.state.mergedPropsStyles, this.unreadPropStyles, this.state.lastIdealStyles));
  398. } else {
  399. this.unreadPropStyles = styles;
  400. }
  401. if (this.animationID == null) {
  402. this.prevTime = _performanceNow2['default']();
  403. this.startAnimationIfNecessary();
  404. }
  405. };
  406. TransitionMotion.prototype.componentWillUnmount = function componentWillUnmount() {
  407. this.unmounting = true;
  408. if (this.animationID != null) {
  409. _raf2['default'].cancel(this.animationID);
  410. this.animationID = null;
  411. }
  412. };
  413. TransitionMotion.prototype.render = function render() {
  414. var hydratedStyles = rehydrateStyles(this.state.mergedPropsStyles, this.unreadPropStyles, this.state.currentStyles);
  415. var renderedChildren = this.props.children(hydratedStyles);
  416. return renderedChildren && _react2['default'].Children.only(renderedChildren);
  417. };
  418. return TransitionMotion;
  419. })(_react2['default'].Component);
  420. exports['default'] = TransitionMotion;
  421. module.exports = exports['default'];
  422. // list of styles, each containing interpolating values. Part of what's passed
  423. // to children function. Notice that this is
  424. // Array<ActualInterpolatingStyleObject>, without the wrapper that is {key: ...,
  425. // data: ... style: ActualInterpolatingStyleObject}. Only mergedPropsStyles
  426. // contains the key & data info (so that we only have a single source of truth
  427. // for these, and to save space). Check the comment for `rehydrateStyles` to
  428. // see how we regenerate the entirety of what's passed to children function
  429. // the array that keeps track of currently rendered stuff! Including stuff
  430. // that you've unmounted but that's still animating. This is where it lives
  431. // it's possible that currentStyle's value is stale: if props is immediately
  432. // changed from 0 to 400 to spring(0) again, the async currentStyle is still
  433. // at 0 (didn't have time to tick and interpolate even once). If we naively
  434. // compare currentStyle with destVal it'll be 0 === 0 (no animation, stop).
  435. // In reality currentStyle should be 400