5354 lines
133 KiB
JavaScript
5354 lines
133 KiB
JavaScript
module.exports = (function() {
|
|
var __MODS__ = {};
|
|
var __DEFINE__ = function(modId, func, req) { var m = { exports: {}, _tempexports: {} }; __MODS__[modId] = { status: 0, func: func, req: req, m: m }; };
|
|
var __REQUIRE__ = function(modId, source) { if(!__MODS__[modId]) return require(source); if(!__MODS__[modId].status) { var m = __MODS__[modId].m; m._exports = m._tempexports; var desp = Object.getOwnPropertyDescriptor(m, "exports"); if (desp && desp.configurable) Object.defineProperty(m, "exports", { set: function (val) { if(typeof val === "object" && val !== m._exports) { m._exports.__proto__ = val.__proto__; Object.keys(val).forEach(function (k) { m._exports[k] = val[k]; }); } m._tempexports = val }, get: function () { return m._tempexports; } }); __MODS__[modId].status = 1; __MODS__[modId].func(__MODS__[modId].req, m, m.exports); } return __MODS__[modId].m.exports; };
|
|
var __REQUIRE_WILDCARD__ = function(obj) { if(obj && obj.__esModule) { return obj; } else { var newObj = {}; if(obj != null) { for(var k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) newObj[k] = obj[k]; } } newObj.default = obj; return newObj; } };
|
|
var __REQUIRE_DEFAULT__ = function(obj) { return obj && obj.__esModule ? obj.default : obj; };
|
|
__DEFINE__(1656641689787, function(require, module, exports) {
|
|
|
|
|
|
if (process.env.NODE_ENV === "production") {
|
|
module.exports = require("./react-spring-core.cjs.prod.js");
|
|
} else {
|
|
module.exports = require("./react-spring-core.cjs.dev.js");
|
|
}
|
|
|
|
}, function(modId) {var map = {"./react-spring-core.cjs.prod.js":1656641689788,"./react-spring-core.cjs.dev.js":1656641689789}; return __REQUIRE__(map[modId], modId); })
|
|
__DEFINE__(1656641689788, function(require, module, exports) {
|
|
|
|
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
|
var shared = require('@react-spring/shared');
|
|
var React = require('react');
|
|
var animated$1 = require('@react-spring/animated');
|
|
var animated = require('@react-spring/types/animated');
|
|
var interpolation = require('@react-spring/types/interpolation');
|
|
|
|
function _interopNamespace(e) {
|
|
if (e && e.__esModule) return e;
|
|
var n = Object.create(null);
|
|
if (e) {
|
|
Object.keys(e).forEach(function (k) {
|
|
if (k !== 'default') {
|
|
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
Object.defineProperty(n, k, d.get ? d : {
|
|
enumerable: true,
|
|
get: function () {
|
|
return e[k];
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
n['default'] = e;
|
|
return Object.freeze(n);
|
|
}
|
|
|
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
|
|
function _extends() {
|
|
_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;
|
|
};
|
|
|
|
return _extends.apply(this, arguments);
|
|
}
|
|
|
|
function callProp(value, ...args) {
|
|
return shared.is.fun(value) ? value(...args) : value;
|
|
}
|
|
const matchProp = (value, key) => value === true || !!(key && value && (shared.is.fun(value) ? value(key) : shared.toArray(value).includes(key)));
|
|
const resolveProp = (prop, key) => shared.is.obj(prop) ? key && prop[key] : prop;
|
|
const getDefaultProp = (props, key) => props.default === true ? props[key] : props.default ? props.default[key] : undefined;
|
|
|
|
const noopTransform = value => value;
|
|
|
|
const getDefaultProps = (props, transform = noopTransform) => {
|
|
let keys = DEFAULT_PROPS;
|
|
|
|
if (props.default && props.default !== true) {
|
|
props = props.default;
|
|
keys = Object.keys(props);
|
|
}
|
|
|
|
const defaults = {};
|
|
|
|
for (const key of keys) {
|
|
const value = transform(props[key], key);
|
|
|
|
if (!shared.is.und(value)) {
|
|
defaults[key] = value;
|
|
}
|
|
}
|
|
|
|
return defaults;
|
|
};
|
|
const DEFAULT_PROPS = ['config', 'onProps', 'onStart', 'onChange', 'onPause', 'onResume', 'onRest'];
|
|
const RESERVED_PROPS = {
|
|
config: 1,
|
|
from: 1,
|
|
to: 1,
|
|
ref: 1,
|
|
loop: 1,
|
|
reset: 1,
|
|
pause: 1,
|
|
cancel: 1,
|
|
reverse: 1,
|
|
immediate: 1,
|
|
default: 1,
|
|
delay: 1,
|
|
onProps: 1,
|
|
onStart: 1,
|
|
onChange: 1,
|
|
onPause: 1,
|
|
onResume: 1,
|
|
onRest: 1,
|
|
onResolve: 1,
|
|
items: 1,
|
|
trail: 1,
|
|
sort: 1,
|
|
expires: 1,
|
|
initial: 1,
|
|
enter: 1,
|
|
update: 1,
|
|
leave: 1,
|
|
children: 1,
|
|
onDestroyed: 1,
|
|
keys: 1,
|
|
callId: 1,
|
|
parentId: 1
|
|
};
|
|
|
|
function getForwardProps(props) {
|
|
const forward = {};
|
|
let count = 0;
|
|
shared.eachProp(props, (value, prop) => {
|
|
if (!RESERVED_PROPS[prop]) {
|
|
forward[prop] = value;
|
|
count++;
|
|
}
|
|
});
|
|
|
|
if (count) {
|
|
return forward;
|
|
}
|
|
}
|
|
|
|
function inferTo(props) {
|
|
const to = getForwardProps(props);
|
|
|
|
if (to) {
|
|
const out = {
|
|
to
|
|
};
|
|
shared.eachProp(props, (val, key) => key in to || (out[key] = val));
|
|
return out;
|
|
}
|
|
|
|
return _extends({}, props);
|
|
}
|
|
function computeGoal(value) {
|
|
value = shared.getFluidValue(value);
|
|
return shared.is.arr(value) ? value.map(computeGoal) : shared.isAnimatedString(value) ? shared.Globals.createStringInterpolator({
|
|
range: [0, 1],
|
|
output: [value, value]
|
|
})(1) : value;
|
|
}
|
|
function hasProps(props) {
|
|
for (const _ in props) return true;
|
|
|
|
return false;
|
|
}
|
|
function isAsyncTo(to) {
|
|
return shared.is.fun(to) || shared.is.arr(to) && shared.is.obj(to[0]);
|
|
}
|
|
function detachRefs(ctrl, ref) {
|
|
var _ctrl$ref;
|
|
|
|
(_ctrl$ref = ctrl.ref) == null ? void 0 : _ctrl$ref.delete(ctrl);
|
|
ref == null ? void 0 : ref.delete(ctrl);
|
|
}
|
|
function replaceRef(ctrl, ref) {
|
|
if (ref && ctrl.ref !== ref) {
|
|
var _ctrl$ref2;
|
|
|
|
(_ctrl$ref2 = ctrl.ref) == null ? void 0 : _ctrl$ref2.delete(ctrl);
|
|
ref.add(ctrl);
|
|
ctrl.ref = ref;
|
|
}
|
|
}
|
|
|
|
function useChain(refs, timeSteps, timeFrame = 1000) {
|
|
shared.useLayoutEffect(() => {
|
|
if (timeSteps) {
|
|
let prevDelay = 0;
|
|
shared.each(refs, (ref, i) => {
|
|
const controllers = ref.current;
|
|
|
|
if (controllers.length) {
|
|
let delay = timeFrame * timeSteps[i];
|
|
if (isNaN(delay)) delay = prevDelay;else prevDelay = delay;
|
|
shared.each(controllers, ctrl => {
|
|
shared.each(ctrl.queue, props => {
|
|
const memoizedDelayProp = props.delay;
|
|
|
|
props.delay = key => delay + callProp(memoizedDelayProp || 0, key);
|
|
});
|
|
});
|
|
ref.start();
|
|
}
|
|
});
|
|
} else {
|
|
let p = Promise.resolve();
|
|
shared.each(refs, ref => {
|
|
const controllers = ref.current;
|
|
|
|
if (controllers.length) {
|
|
const queues = controllers.map(ctrl => {
|
|
const q = ctrl.queue;
|
|
ctrl.queue = [];
|
|
return q;
|
|
});
|
|
p = p.then(() => {
|
|
shared.each(controllers, (ctrl, i) => shared.each(queues[i] || [], update => ctrl.queue.push(update)));
|
|
return Promise.all(ref.start());
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
const config = {
|
|
default: {
|
|
tension: 170,
|
|
friction: 26
|
|
},
|
|
gentle: {
|
|
tension: 120,
|
|
friction: 14
|
|
},
|
|
wobbly: {
|
|
tension: 180,
|
|
friction: 12
|
|
},
|
|
stiff: {
|
|
tension: 210,
|
|
friction: 20
|
|
},
|
|
slow: {
|
|
tension: 280,
|
|
friction: 60
|
|
},
|
|
molasses: {
|
|
tension: 280,
|
|
friction: 120
|
|
}
|
|
};
|
|
const c1 = 1.70158;
|
|
const c2 = c1 * 1.525;
|
|
const c3 = c1 + 1;
|
|
const c4 = 2 * Math.PI / 3;
|
|
const c5 = 2 * Math.PI / 4.5;
|
|
|
|
const bounceOut = x => {
|
|
const n1 = 7.5625;
|
|
const d1 = 2.75;
|
|
|
|
if (x < 1 / d1) {
|
|
return n1 * x * x;
|
|
} else if (x < 2 / d1) {
|
|
return n1 * (x -= 1.5 / d1) * x + 0.75;
|
|
} else if (x < 2.5 / d1) {
|
|
return n1 * (x -= 2.25 / d1) * x + 0.9375;
|
|
} else {
|
|
return n1 * (x -= 2.625 / d1) * x + 0.984375;
|
|
}
|
|
};
|
|
|
|
const easings = {
|
|
linear: x => x,
|
|
easeInQuad: x => x * x,
|
|
easeOutQuad: x => 1 - (1 - x) * (1 - x),
|
|
easeInOutQuad: x => x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2,
|
|
easeInCubic: x => x * x * x,
|
|
easeOutCubic: x => 1 - Math.pow(1 - x, 3),
|
|
easeInOutCubic: x => x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2,
|
|
easeInQuart: x => x * x * x * x,
|
|
easeOutQuart: x => 1 - Math.pow(1 - x, 4),
|
|
easeInOutQuart: x => x < 0.5 ? 8 * x * x * x * x : 1 - Math.pow(-2 * x + 2, 4) / 2,
|
|
easeInQuint: x => x * x * x * x * x,
|
|
easeOutQuint: x => 1 - Math.pow(1 - x, 5),
|
|
easeInOutQuint: x => x < 0.5 ? 16 * x * x * x * x * x : 1 - Math.pow(-2 * x + 2, 5) / 2,
|
|
easeInSine: x => 1 - Math.cos(x * Math.PI / 2),
|
|
easeOutSine: x => Math.sin(x * Math.PI / 2),
|
|
easeInOutSine: x => -(Math.cos(Math.PI * x) - 1) / 2,
|
|
easeInExpo: x => x === 0 ? 0 : Math.pow(2, 10 * x - 10),
|
|
easeOutExpo: x => x === 1 ? 1 : 1 - Math.pow(2, -10 * x),
|
|
easeInOutExpo: x => x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? Math.pow(2, 20 * x - 10) / 2 : (2 - Math.pow(2, -20 * x + 10)) / 2,
|
|
easeInCirc: x => 1 - Math.sqrt(1 - Math.pow(x, 2)),
|
|
easeOutCirc: x => Math.sqrt(1 - Math.pow(x - 1, 2)),
|
|
easeInOutCirc: x => x < 0.5 ? (1 - Math.sqrt(1 - Math.pow(2 * x, 2))) / 2 : (Math.sqrt(1 - Math.pow(-2 * x + 2, 2)) + 1) / 2,
|
|
easeInBack: x => c3 * x * x * x - c1 * x * x,
|
|
easeOutBack: x => 1 + c3 * Math.pow(x - 1, 3) + c1 * Math.pow(x - 1, 2),
|
|
easeInOutBack: x => x < 0.5 ? Math.pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2) / 2 : (Math.pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2,
|
|
easeInElastic: x => x === 0 ? 0 : x === 1 ? 1 : -Math.pow(2, 10 * x - 10) * Math.sin((x * 10 - 10.75) * c4),
|
|
easeOutElastic: x => x === 0 ? 0 : x === 1 ? 1 : Math.pow(2, -10 * x) * Math.sin((x * 10 - 0.75) * c4) + 1,
|
|
easeInOutElastic: x => x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? -(Math.pow(2, 20 * x - 10) * Math.sin((20 * x - 11.125) * c5)) / 2 : Math.pow(2, -20 * x + 10) * Math.sin((20 * x - 11.125) * c5) / 2 + 1,
|
|
easeInBounce: x => 1 - bounceOut(1 - x),
|
|
easeOutBounce: bounceOut,
|
|
easeInOutBounce: x => x < 0.5 ? (1 - bounceOut(1 - 2 * x)) / 2 : (1 + bounceOut(2 * x - 1)) / 2
|
|
};
|
|
|
|
const defaults = _extends({}, config.default, {
|
|
mass: 1,
|
|
damping: 1,
|
|
easing: easings.linear,
|
|
clamp: false
|
|
});
|
|
|
|
class AnimationConfig {
|
|
constructor() {
|
|
this.tension = void 0;
|
|
this.friction = void 0;
|
|
this.frequency = void 0;
|
|
this.damping = void 0;
|
|
this.mass = void 0;
|
|
this.velocity = 0;
|
|
this.restVelocity = void 0;
|
|
this.precision = void 0;
|
|
this.progress = void 0;
|
|
this.duration = void 0;
|
|
this.easing = void 0;
|
|
this.clamp = void 0;
|
|
this.bounce = void 0;
|
|
this.decay = void 0;
|
|
this.round = void 0;
|
|
Object.assign(this, defaults);
|
|
}
|
|
|
|
}
|
|
function mergeConfig(config, newConfig, defaultConfig) {
|
|
if (defaultConfig) {
|
|
defaultConfig = _extends({}, defaultConfig);
|
|
sanitizeConfig(defaultConfig, newConfig);
|
|
newConfig = _extends({}, defaultConfig, newConfig);
|
|
}
|
|
|
|
sanitizeConfig(config, newConfig);
|
|
Object.assign(config, newConfig);
|
|
|
|
for (const key in defaults) {
|
|
if (config[key] == null) {
|
|
config[key] = defaults[key];
|
|
}
|
|
}
|
|
|
|
let {
|
|
mass,
|
|
frequency,
|
|
damping
|
|
} = config;
|
|
|
|
if (!shared.is.und(frequency)) {
|
|
if (frequency < 0.01) frequency = 0.01;
|
|
if (damping < 0) damping = 0;
|
|
config.tension = Math.pow(2 * Math.PI / frequency, 2) * mass;
|
|
config.friction = 4 * Math.PI * damping * mass / frequency;
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
function sanitizeConfig(config, props) {
|
|
if (!shared.is.und(props.decay)) {
|
|
config.duration = undefined;
|
|
} else {
|
|
const isTensionConfig = !shared.is.und(props.tension) || !shared.is.und(props.friction);
|
|
|
|
if (isTensionConfig || !shared.is.und(props.frequency) || !shared.is.und(props.damping) || !shared.is.und(props.mass)) {
|
|
config.duration = undefined;
|
|
config.decay = undefined;
|
|
}
|
|
|
|
if (isTensionConfig) {
|
|
config.frequency = undefined;
|
|
}
|
|
}
|
|
}
|
|
|
|
const emptyArray = [];
|
|
class Animation {
|
|
constructor() {
|
|
this.changed = false;
|
|
this.values = emptyArray;
|
|
this.toValues = null;
|
|
this.fromValues = emptyArray;
|
|
this.to = void 0;
|
|
this.from = void 0;
|
|
this.config = new AnimationConfig();
|
|
this.immediate = false;
|
|
}
|
|
|
|
}
|
|
|
|
function scheduleProps(callId, {
|
|
key,
|
|
props,
|
|
defaultProps,
|
|
state,
|
|
actions
|
|
}) {
|
|
return new Promise((resolve, reject) => {
|
|
var _props$cancel;
|
|
|
|
let delay;
|
|
let timeout;
|
|
let cancel = matchProp((_props$cancel = props.cancel) != null ? _props$cancel : defaultProps == null ? void 0 : defaultProps.cancel, key);
|
|
|
|
if (cancel) {
|
|
onStart();
|
|
} else {
|
|
if (!shared.is.und(props.pause)) {
|
|
state.paused = matchProp(props.pause, key);
|
|
}
|
|
|
|
let pause = defaultProps == null ? void 0 : defaultProps.pause;
|
|
|
|
if (pause !== true) {
|
|
pause = state.paused || matchProp(pause, key);
|
|
}
|
|
|
|
delay = callProp(props.delay || 0, key);
|
|
|
|
if (pause) {
|
|
state.resumeQueue.add(onResume);
|
|
actions.pause();
|
|
} else {
|
|
actions.resume();
|
|
onResume();
|
|
}
|
|
}
|
|
|
|
function onPause() {
|
|
state.resumeQueue.add(onResume);
|
|
state.timeouts.delete(timeout);
|
|
timeout.cancel();
|
|
delay = timeout.time - shared.raf.now();
|
|
}
|
|
|
|
function onResume() {
|
|
if (delay > 0 && !shared.Globals.skipAnimation) {
|
|
state.delayed = true;
|
|
timeout = shared.raf.setTimeout(onStart, delay);
|
|
state.pauseQueue.add(onPause);
|
|
state.timeouts.add(timeout);
|
|
} else {
|
|
onStart();
|
|
}
|
|
}
|
|
|
|
function onStart() {
|
|
if (state.delayed) {
|
|
state.delayed = false;
|
|
}
|
|
|
|
state.pauseQueue.delete(onPause);
|
|
state.timeouts.delete(timeout);
|
|
|
|
if (callId <= (state.cancelId || 0)) {
|
|
cancel = true;
|
|
}
|
|
|
|
try {
|
|
actions.start(_extends({}, props, {
|
|
callId,
|
|
cancel
|
|
}), resolve);
|
|
} catch (err) {
|
|
reject(err);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
const getCombinedResult = (target, results) => results.length == 1 ? results[0] : results.some(result => result.cancelled) ? getCancelledResult(target.get()) : results.every(result => result.noop) ? getNoopResult(target.get()) : getFinishedResult(target.get(), results.every(result => result.finished));
|
|
const getNoopResult = value => ({
|
|
value,
|
|
noop: true,
|
|
finished: true,
|
|
cancelled: false
|
|
});
|
|
const getFinishedResult = (value, finished, cancelled = false) => ({
|
|
value,
|
|
finished,
|
|
cancelled
|
|
});
|
|
const getCancelledResult = value => ({
|
|
value,
|
|
cancelled: true,
|
|
finished: false
|
|
});
|
|
|
|
function runAsync(to, props, state, target) {
|
|
const {
|
|
callId,
|
|
parentId,
|
|
onRest
|
|
} = props;
|
|
const {
|
|
asyncTo: prevTo,
|
|
promise: prevPromise
|
|
} = state;
|
|
|
|
if (!parentId && to === prevTo && !props.reset) {
|
|
return prevPromise;
|
|
}
|
|
|
|
return state.promise = (async () => {
|
|
state.asyncId = callId;
|
|
state.asyncTo = to;
|
|
const defaultProps = getDefaultProps(props, (value, key) => key === 'onRest' ? undefined : value);
|
|
let preventBail;
|
|
let bail;
|
|
const bailPromise = new Promise((resolve, reject) => (preventBail = resolve, bail = reject));
|
|
|
|
const bailIfEnded = bailSignal => {
|
|
const bailResult = callId <= (state.cancelId || 0) && getCancelledResult(target) || callId !== state.asyncId && getFinishedResult(target, false);
|
|
|
|
if (bailResult) {
|
|
bailSignal.result = bailResult;
|
|
bail(bailSignal);
|
|
throw bailSignal;
|
|
}
|
|
};
|
|
|
|
const animate = (arg1, arg2) => {
|
|
const bailSignal = new BailSignal();
|
|
const skipAnimationSignal = new SkipAniamtionSignal();
|
|
return (async () => {
|
|
if (shared.Globals.skipAnimation) {
|
|
stopAsync(state);
|
|
skipAnimationSignal.result = getFinishedResult(target, false);
|
|
bail(skipAnimationSignal);
|
|
throw skipAnimationSignal;
|
|
}
|
|
|
|
bailIfEnded(bailSignal);
|
|
const props = shared.is.obj(arg1) ? _extends({}, arg1) : _extends({}, arg2, {
|
|
to: arg1
|
|
});
|
|
props.parentId = callId;
|
|
shared.eachProp(defaultProps, (value, key) => {
|
|
if (shared.is.und(props[key])) {
|
|
props[key] = value;
|
|
}
|
|
});
|
|
const result = await target.start(props);
|
|
bailIfEnded(bailSignal);
|
|
|
|
if (state.paused) {
|
|
await new Promise(resume => {
|
|
state.resumeQueue.add(resume);
|
|
});
|
|
}
|
|
|
|
return result;
|
|
})();
|
|
};
|
|
|
|
let result;
|
|
|
|
if (shared.Globals.skipAnimation) {
|
|
stopAsync(state);
|
|
return getFinishedResult(target, false);
|
|
}
|
|
|
|
try {
|
|
let animating;
|
|
|
|
if (shared.is.arr(to)) {
|
|
animating = (async queue => {
|
|
for (const props of queue) {
|
|
await animate(props);
|
|
}
|
|
})(to);
|
|
} else {
|
|
animating = Promise.resolve(to(animate, target.stop.bind(target)));
|
|
}
|
|
|
|
await Promise.all([animating.then(preventBail), bailPromise]);
|
|
result = getFinishedResult(target.get(), true, false);
|
|
} catch (err) {
|
|
if (err instanceof BailSignal) {
|
|
result = err.result;
|
|
} else if (err instanceof SkipAniamtionSignal) {
|
|
result = err.result;
|
|
} else {
|
|
throw err;
|
|
}
|
|
} finally {
|
|
if (callId == state.asyncId) {
|
|
state.asyncId = parentId;
|
|
state.asyncTo = parentId ? prevTo : undefined;
|
|
state.promise = parentId ? prevPromise : undefined;
|
|
}
|
|
}
|
|
|
|
if (shared.is.fun(onRest)) {
|
|
shared.raf.batchedUpdates(() => {
|
|
onRest(result, target, target.item);
|
|
});
|
|
}
|
|
|
|
return result;
|
|
})();
|
|
}
|
|
function stopAsync(state, cancelId) {
|
|
shared.flush(state.timeouts, t => t.cancel());
|
|
state.pauseQueue.clear();
|
|
state.resumeQueue.clear();
|
|
state.asyncId = state.asyncTo = state.promise = undefined;
|
|
if (cancelId) state.cancelId = cancelId;
|
|
}
|
|
class BailSignal extends Error {
|
|
constructor() {
|
|
super('An async animation has been interrupted. You see this error because you ' + 'forgot to use `await` or `.catch(...)` on its returned promise.');
|
|
this.result = void 0;
|
|
}
|
|
|
|
}
|
|
class SkipAniamtionSignal extends Error {
|
|
constructor() {
|
|
super('SkipAnimationSignal');
|
|
this.result = void 0;
|
|
}
|
|
|
|
}
|
|
|
|
const isFrameValue = value => value instanceof FrameValue;
|
|
let nextId$1 = 1;
|
|
class FrameValue extends shared.FluidValue {
|
|
constructor(...args) {
|
|
super(...args);
|
|
this.id = nextId$1++;
|
|
this.key = void 0;
|
|
this._priority = 0;
|
|
}
|
|
|
|
get priority() {
|
|
return this._priority;
|
|
}
|
|
|
|
set priority(priority) {
|
|
if (this._priority != priority) {
|
|
this._priority = priority;
|
|
|
|
this._onPriorityChange(priority);
|
|
}
|
|
}
|
|
|
|
get() {
|
|
const node = animated$1.getAnimated(this);
|
|
return node && node.getValue();
|
|
}
|
|
|
|
to(...args) {
|
|
return shared.Globals.to(this, args);
|
|
}
|
|
|
|
interpolate(...args) {
|
|
shared.deprecateInterpolate();
|
|
return shared.Globals.to(this, args);
|
|
}
|
|
|
|
toJSON() {
|
|
return this.get();
|
|
}
|
|
|
|
observerAdded(count) {
|
|
if (count == 1) this._attach();
|
|
}
|
|
|
|
observerRemoved(count) {
|
|
if (count == 0) this._detach();
|
|
}
|
|
|
|
_attach() {}
|
|
|
|
_detach() {}
|
|
|
|
_onChange(value, idle = false) {
|
|
shared.callFluidObservers(this, {
|
|
type: 'change',
|
|
parent: this,
|
|
value,
|
|
idle
|
|
});
|
|
}
|
|
|
|
_onPriorityChange(priority) {
|
|
if (!this.idle) {
|
|
shared.frameLoop.sort(this);
|
|
}
|
|
|
|
shared.callFluidObservers(this, {
|
|
type: 'priority',
|
|
parent: this,
|
|
priority
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
const $P = Symbol.for('SpringPhase');
|
|
const HAS_ANIMATED = 1;
|
|
const IS_ANIMATING = 2;
|
|
const IS_PAUSED = 4;
|
|
const hasAnimated = target => (target[$P] & HAS_ANIMATED) > 0;
|
|
const isAnimating = target => (target[$P] & IS_ANIMATING) > 0;
|
|
const isPaused = target => (target[$P] & IS_PAUSED) > 0;
|
|
const setActiveBit = (target, active) => active ? target[$P] |= IS_ANIMATING | HAS_ANIMATED : target[$P] &= ~IS_ANIMATING;
|
|
const setPausedBit = (target, paused) => paused ? target[$P] |= IS_PAUSED : target[$P] &= ~IS_PAUSED;
|
|
|
|
class SpringValue extends FrameValue {
|
|
constructor(arg1, arg2) {
|
|
super();
|
|
this.key = void 0;
|
|
this.animation = new Animation();
|
|
this.queue = void 0;
|
|
this.defaultProps = {};
|
|
this._state = {
|
|
paused: false,
|
|
delayed: false,
|
|
pauseQueue: new Set(),
|
|
resumeQueue: new Set(),
|
|
timeouts: new Set()
|
|
};
|
|
this._pendingCalls = new Set();
|
|
this._lastCallId = 0;
|
|
this._lastToId = 0;
|
|
this._memoizedDuration = 0;
|
|
|
|
if (!shared.is.und(arg1) || !shared.is.und(arg2)) {
|
|
const props = shared.is.obj(arg1) ? _extends({}, arg1) : _extends({}, arg2, {
|
|
from: arg1
|
|
});
|
|
|
|
if (shared.is.und(props.default)) {
|
|
props.default = true;
|
|
}
|
|
|
|
this.start(props);
|
|
}
|
|
}
|
|
|
|
get idle() {
|
|
return !(isAnimating(this) || this._state.asyncTo) || isPaused(this);
|
|
}
|
|
|
|
get goal() {
|
|
return shared.getFluidValue(this.animation.to);
|
|
}
|
|
|
|
get velocity() {
|
|
const node = animated$1.getAnimated(this);
|
|
return node instanceof animated$1.AnimatedValue ? node.lastVelocity || 0 : node.getPayload().map(node => node.lastVelocity || 0);
|
|
}
|
|
|
|
get hasAnimated() {
|
|
return hasAnimated(this);
|
|
}
|
|
|
|
get isAnimating() {
|
|
return isAnimating(this);
|
|
}
|
|
|
|
get isPaused() {
|
|
return isPaused(this);
|
|
}
|
|
|
|
get isDelayed() {
|
|
return this._state.delayed;
|
|
}
|
|
|
|
advance(dt) {
|
|
let idle = true;
|
|
let changed = false;
|
|
const anim = this.animation;
|
|
let {
|
|
config,
|
|
toValues
|
|
} = anim;
|
|
const payload = animated$1.getPayload(anim.to);
|
|
|
|
if (!payload && shared.hasFluidValue(anim.to)) {
|
|
toValues = shared.toArray(shared.getFluidValue(anim.to));
|
|
}
|
|
|
|
anim.values.forEach((node, i) => {
|
|
if (node.done) return;
|
|
const to = node.constructor == animated$1.AnimatedString ? 1 : payload ? payload[i].lastPosition : toValues[i];
|
|
let finished = anim.immediate;
|
|
let position = to;
|
|
|
|
if (!finished) {
|
|
position = node.lastPosition;
|
|
|
|
if (config.tension <= 0) {
|
|
node.done = true;
|
|
return;
|
|
}
|
|
|
|
let elapsed = node.elapsedTime += dt;
|
|
const from = anim.fromValues[i];
|
|
const v0 = node.v0 != null ? node.v0 : node.v0 = shared.is.arr(config.velocity) ? config.velocity[i] : config.velocity;
|
|
let velocity;
|
|
|
|
if (!shared.is.und(config.duration)) {
|
|
let p = 1;
|
|
|
|
if (config.duration > 0) {
|
|
if (this._memoizedDuration !== config.duration) {
|
|
this._memoizedDuration = config.duration;
|
|
|
|
if (node.durationProgress > 0) {
|
|
node.elapsedTime = config.duration * node.durationProgress;
|
|
elapsed = node.elapsedTime += dt;
|
|
}
|
|
}
|
|
|
|
p = (config.progress || 0) + elapsed / this._memoizedDuration;
|
|
p = p > 1 ? 1 : p < 0 ? 0 : p;
|
|
node.durationProgress = p;
|
|
}
|
|
|
|
position = from + config.easing(p) * (to - from);
|
|
velocity = (position - node.lastPosition) / dt;
|
|
finished = p == 1;
|
|
} else if (config.decay) {
|
|
const decay = config.decay === true ? 0.998 : config.decay;
|
|
const e = Math.exp(-(1 - decay) * elapsed);
|
|
position = from + v0 / (1 - decay) * (1 - e);
|
|
finished = Math.abs(node.lastPosition - position) < 0.1;
|
|
velocity = v0 * e;
|
|
} else {
|
|
velocity = node.lastVelocity == null ? v0 : node.lastVelocity;
|
|
const precision = config.precision || (from == to ? 0.005 : Math.min(1, Math.abs(to - from) * 0.001));
|
|
const restVelocity = config.restVelocity || precision / 10;
|
|
const bounceFactor = config.clamp ? 0 : config.bounce;
|
|
const canBounce = !shared.is.und(bounceFactor);
|
|
const isGrowing = from == to ? node.v0 > 0 : from < to;
|
|
let isMoving;
|
|
let isBouncing = false;
|
|
const step = 1;
|
|
const numSteps = Math.ceil(dt / step);
|
|
|
|
for (let n = 0; n < numSteps; ++n) {
|
|
isMoving = Math.abs(velocity) > restVelocity;
|
|
|
|
if (!isMoving) {
|
|
finished = Math.abs(to - position) <= precision;
|
|
|
|
if (finished) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (canBounce) {
|
|
isBouncing = position == to || position > to == isGrowing;
|
|
|
|
if (isBouncing) {
|
|
velocity = -velocity * bounceFactor;
|
|
position = to;
|
|
}
|
|
}
|
|
|
|
const springForce = -config.tension * 0.000001 * (position - to);
|
|
const dampingForce = -config.friction * 0.001 * velocity;
|
|
const acceleration = (springForce + dampingForce) / config.mass;
|
|
velocity = velocity + acceleration * step;
|
|
position = position + velocity * step;
|
|
}
|
|
}
|
|
|
|
node.lastVelocity = velocity;
|
|
|
|
if (Number.isNaN(position)) {
|
|
console.warn(`Got NaN while animating:`, this);
|
|
finished = true;
|
|
}
|
|
}
|
|
|
|
if (payload && !payload[i].done) {
|
|
finished = false;
|
|
}
|
|
|
|
if (finished) {
|
|
node.done = true;
|
|
} else {
|
|
idle = false;
|
|
}
|
|
|
|
if (node.setValue(position, config.round)) {
|
|
changed = true;
|
|
}
|
|
});
|
|
const node = animated$1.getAnimated(this);
|
|
const currVal = node.getValue();
|
|
|
|
if (idle) {
|
|
const finalVal = shared.getFluidValue(anim.to);
|
|
|
|
if ((currVal !== finalVal || changed) && !config.decay) {
|
|
node.setValue(finalVal);
|
|
|
|
this._onChange(finalVal);
|
|
} else if (changed && config.decay) {
|
|
this._onChange(currVal);
|
|
}
|
|
|
|
this._stop();
|
|
} else if (changed) {
|
|
this._onChange(currVal);
|
|
}
|
|
}
|
|
|
|
set(value) {
|
|
shared.raf.batchedUpdates(() => {
|
|
this._stop();
|
|
|
|
this._focus(value);
|
|
|
|
this._set(value);
|
|
});
|
|
return this;
|
|
}
|
|
|
|
pause() {
|
|
this._update({
|
|
pause: true
|
|
});
|
|
}
|
|
|
|
resume() {
|
|
this._update({
|
|
pause: false
|
|
});
|
|
}
|
|
|
|
finish() {
|
|
if (isAnimating(this)) {
|
|
const {
|
|
to,
|
|
config
|
|
} = this.animation;
|
|
shared.raf.batchedUpdates(() => {
|
|
this._onStart();
|
|
|
|
if (!config.decay) {
|
|
this._set(to, false);
|
|
}
|
|
|
|
this._stop();
|
|
});
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
update(props) {
|
|
const queue = this.queue || (this.queue = []);
|
|
queue.push(props);
|
|
return this;
|
|
}
|
|
|
|
start(to, arg2) {
|
|
let queue;
|
|
|
|
if (!shared.is.und(to)) {
|
|
queue = [shared.is.obj(to) ? to : _extends({}, arg2, {
|
|
to
|
|
})];
|
|
} else {
|
|
queue = this.queue || [];
|
|
this.queue = [];
|
|
}
|
|
|
|
return Promise.all(queue.map(props => {
|
|
const up = this._update(props);
|
|
|
|
return up;
|
|
})).then(results => getCombinedResult(this, results));
|
|
}
|
|
|
|
stop(cancel) {
|
|
const {
|
|
to
|
|
} = this.animation;
|
|
|
|
this._focus(this.get());
|
|
|
|
stopAsync(this._state, cancel && this._lastCallId);
|
|
shared.raf.batchedUpdates(() => this._stop(to, cancel));
|
|
return this;
|
|
}
|
|
|
|
reset() {
|
|
this._update({
|
|
reset: true
|
|
});
|
|
}
|
|
|
|
eventObserved(event) {
|
|
if (event.type == 'change') {
|
|
this._start();
|
|
} else if (event.type == 'priority') {
|
|
this.priority = event.priority + 1;
|
|
}
|
|
}
|
|
|
|
_prepareNode(props) {
|
|
const key = this.key || '';
|
|
let {
|
|
to,
|
|
from
|
|
} = props;
|
|
to = shared.is.obj(to) ? to[key] : to;
|
|
|
|
if (to == null || isAsyncTo(to)) {
|
|
to = undefined;
|
|
}
|
|
|
|
from = shared.is.obj(from) ? from[key] : from;
|
|
|
|
if (from == null) {
|
|
from = undefined;
|
|
}
|
|
|
|
const range = {
|
|
to,
|
|
from
|
|
};
|
|
|
|
if (!hasAnimated(this)) {
|
|
if (props.reverse) [to, from] = [from, to];
|
|
from = shared.getFluidValue(from);
|
|
|
|
if (!shared.is.und(from)) {
|
|
this._set(from);
|
|
} else if (!animated$1.getAnimated(this)) {
|
|
this._set(to);
|
|
}
|
|
}
|
|
|
|
return range;
|
|
}
|
|
|
|
_update(_ref, isLoop) {
|
|
let props = _extends({}, _ref);
|
|
|
|
const {
|
|
key,
|
|
defaultProps
|
|
} = this;
|
|
if (props.default) Object.assign(defaultProps, getDefaultProps(props, (value, prop) => /^on/.test(prop) ? resolveProp(value, key) : value));
|
|
mergeActiveFn(this, props, 'onProps');
|
|
sendEvent(this, 'onProps', props, this);
|
|
|
|
const range = this._prepareNode(props);
|
|
|
|
if (Object.isFrozen(this)) {
|
|
throw Error('Cannot animate a `SpringValue` object that is frozen. ' + 'Did you forget to pass your component to `animated(...)` before animating its props?');
|
|
}
|
|
|
|
const state = this._state;
|
|
return scheduleProps(++this._lastCallId, {
|
|
key,
|
|
props,
|
|
defaultProps,
|
|
state,
|
|
actions: {
|
|
pause: () => {
|
|
if (!isPaused(this)) {
|
|
setPausedBit(this, true);
|
|
shared.flushCalls(state.pauseQueue);
|
|
sendEvent(this, 'onPause', getFinishedResult(this, checkFinished(this, this.animation.to)), this);
|
|
}
|
|
},
|
|
resume: () => {
|
|
if (isPaused(this)) {
|
|
setPausedBit(this, false);
|
|
|
|
if (isAnimating(this)) {
|
|
this._resume();
|
|
}
|
|
|
|
shared.flushCalls(state.resumeQueue);
|
|
sendEvent(this, 'onResume', getFinishedResult(this, checkFinished(this, this.animation.to)), this);
|
|
}
|
|
},
|
|
start: this._merge.bind(this, range)
|
|
}
|
|
}).then(result => {
|
|
if (props.loop && result.finished && !(isLoop && result.noop)) {
|
|
const nextProps = createLoopUpdate(props);
|
|
|
|
if (nextProps) {
|
|
return this._update(nextProps, true);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
});
|
|
}
|
|
|
|
_merge(range, props, resolve) {
|
|
if (props.cancel) {
|
|
this.stop(true);
|
|
return resolve(getCancelledResult(this));
|
|
}
|
|
|
|
const hasToProp = !shared.is.und(range.to);
|
|
const hasFromProp = !shared.is.und(range.from);
|
|
|
|
if (hasToProp || hasFromProp) {
|
|
if (props.callId > this._lastToId) {
|
|
this._lastToId = props.callId;
|
|
} else {
|
|
return resolve(getCancelledResult(this));
|
|
}
|
|
}
|
|
|
|
const {
|
|
key,
|
|
defaultProps,
|
|
animation: anim
|
|
} = this;
|
|
const {
|
|
to: prevTo,
|
|
from: prevFrom
|
|
} = anim;
|
|
let {
|
|
to = prevTo,
|
|
from = prevFrom
|
|
} = range;
|
|
|
|
if (hasFromProp && !hasToProp && (!props.default || shared.is.und(to))) {
|
|
to = from;
|
|
}
|
|
|
|
if (props.reverse) [to, from] = [from, to];
|
|
const hasFromChanged = !shared.isEqual(from, prevFrom);
|
|
|
|
if (hasFromChanged) {
|
|
anim.from = from;
|
|
}
|
|
|
|
from = shared.getFluidValue(from);
|
|
const hasToChanged = !shared.isEqual(to, prevTo);
|
|
|
|
if (hasToChanged) {
|
|
this._focus(to);
|
|
}
|
|
|
|
const hasAsyncTo = isAsyncTo(props.to);
|
|
const {
|
|
config
|
|
} = anim;
|
|
const {
|
|
decay,
|
|
velocity
|
|
} = config;
|
|
|
|
if (hasToProp || hasFromProp) {
|
|
config.velocity = 0;
|
|
}
|
|
|
|
if (props.config && !hasAsyncTo) {
|
|
mergeConfig(config, callProp(props.config, key), props.config !== defaultProps.config ? callProp(defaultProps.config, key) : void 0);
|
|
}
|
|
|
|
let node = animated$1.getAnimated(this);
|
|
|
|
if (!node || shared.is.und(to)) {
|
|
return resolve(getFinishedResult(this, true));
|
|
}
|
|
|
|
const reset = shared.is.und(props.reset) ? hasFromProp && !props.default : !shared.is.und(from) && matchProp(props.reset, key);
|
|
const value = reset ? from : this.get();
|
|
const goal = computeGoal(to);
|
|
const isAnimatable = shared.is.num(goal) || shared.is.arr(goal) || shared.isAnimatedString(goal);
|
|
const immediate = !hasAsyncTo && (!isAnimatable || matchProp(defaultProps.immediate || props.immediate, key));
|
|
|
|
if (hasToChanged) {
|
|
const nodeType = animated$1.getAnimatedType(to);
|
|
|
|
if (nodeType !== node.constructor) {
|
|
if (immediate) {
|
|
node = this._set(goal);
|
|
} else throw Error(`Cannot animate between ${node.constructor.name} and ${nodeType.name}, as the "to" prop suggests`);
|
|
}
|
|
}
|
|
|
|
const goalType = node.constructor;
|
|
let started = shared.hasFluidValue(to);
|
|
let finished = false;
|
|
|
|
if (!started) {
|
|
const hasValueChanged = reset || !hasAnimated(this) && hasFromChanged;
|
|
|
|
if (hasToChanged || hasValueChanged) {
|
|
finished = shared.isEqual(computeGoal(value), goal);
|
|
started = !finished;
|
|
}
|
|
|
|
if (!shared.isEqual(anim.immediate, immediate) && !immediate || !shared.isEqual(config.decay, decay) || !shared.isEqual(config.velocity, velocity)) {
|
|
started = true;
|
|
}
|
|
}
|
|
|
|
if (finished && isAnimating(this)) {
|
|
if (anim.changed && !reset) {
|
|
started = true;
|
|
} else if (!started) {
|
|
this._stop(prevTo);
|
|
}
|
|
}
|
|
|
|
if (!hasAsyncTo) {
|
|
if (started || shared.hasFluidValue(prevTo)) {
|
|
anim.values = node.getPayload();
|
|
anim.toValues = shared.hasFluidValue(to) ? null : goalType == animated$1.AnimatedString ? [1] : shared.toArray(goal);
|
|
}
|
|
|
|
if (anim.immediate != immediate) {
|
|
anim.immediate = immediate;
|
|
|
|
if (!immediate && !reset) {
|
|
this._set(prevTo);
|
|
}
|
|
}
|
|
|
|
if (started) {
|
|
const {
|
|
onRest
|
|
} = anim;
|
|
shared.each(ACTIVE_EVENTS, type => mergeActiveFn(this, props, type));
|
|
const result = getFinishedResult(this, checkFinished(this, prevTo));
|
|
shared.flushCalls(this._pendingCalls, result);
|
|
|
|
this._pendingCalls.add(resolve);
|
|
|
|
if (anim.changed) shared.raf.batchedUpdates(() => {
|
|
anim.changed = !reset;
|
|
onRest == null ? void 0 : onRest(result, this);
|
|
|
|
if (reset) {
|
|
callProp(defaultProps.onRest, result);
|
|
} else {
|
|
anim.onStart == null ? void 0 : anim.onStart(result, this);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
if (reset) {
|
|
this._set(value);
|
|
}
|
|
|
|
if (hasAsyncTo) {
|
|
resolve(runAsync(props.to, props, this._state, this));
|
|
} else if (started) {
|
|
this._start();
|
|
} else if (isAnimating(this) && !hasToChanged) {
|
|
this._pendingCalls.add(resolve);
|
|
} else {
|
|
resolve(getNoopResult(value));
|
|
}
|
|
}
|
|
|
|
_focus(value) {
|
|
const anim = this.animation;
|
|
|
|
if (value !== anim.to) {
|
|
if (shared.getFluidObservers(this)) {
|
|
this._detach();
|
|
}
|
|
|
|
anim.to = value;
|
|
|
|
if (shared.getFluidObservers(this)) {
|
|
this._attach();
|
|
}
|
|
}
|
|
}
|
|
|
|
_attach() {
|
|
let priority = 0;
|
|
const {
|
|
to
|
|
} = this.animation;
|
|
|
|
if (shared.hasFluidValue(to)) {
|
|
shared.addFluidObserver(to, this);
|
|
|
|
if (isFrameValue(to)) {
|
|
priority = to.priority + 1;
|
|
}
|
|
}
|
|
|
|
this.priority = priority;
|
|
}
|
|
|
|
_detach() {
|
|
const {
|
|
to
|
|
} = this.animation;
|
|
|
|
if (shared.hasFluidValue(to)) {
|
|
shared.removeFluidObserver(to, this);
|
|
}
|
|
}
|
|
|
|
_set(arg, idle = true) {
|
|
const value = shared.getFluidValue(arg);
|
|
|
|
if (!shared.is.und(value)) {
|
|
const oldNode = animated$1.getAnimated(this);
|
|
|
|
if (!oldNode || !shared.isEqual(value, oldNode.getValue())) {
|
|
const nodeType = animated$1.getAnimatedType(value);
|
|
|
|
if (!oldNode || oldNode.constructor != nodeType) {
|
|
animated$1.setAnimated(this, nodeType.create(value));
|
|
} else {
|
|
oldNode.setValue(value);
|
|
}
|
|
|
|
if (oldNode) {
|
|
shared.raf.batchedUpdates(() => {
|
|
this._onChange(value, idle);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
return animated$1.getAnimated(this);
|
|
}
|
|
|
|
_onStart() {
|
|
const anim = this.animation;
|
|
|
|
if (!anim.changed) {
|
|
anim.changed = true;
|
|
sendEvent(this, 'onStart', getFinishedResult(this, checkFinished(this, anim.to)), this);
|
|
}
|
|
}
|
|
|
|
_onChange(value, idle) {
|
|
if (!idle) {
|
|
this._onStart();
|
|
|
|
callProp(this.animation.onChange, value, this);
|
|
}
|
|
|
|
callProp(this.defaultProps.onChange, value, this);
|
|
|
|
super._onChange(value, idle);
|
|
}
|
|
|
|
_start() {
|
|
const anim = this.animation;
|
|
animated$1.getAnimated(this).reset(shared.getFluidValue(anim.to));
|
|
|
|
if (!anim.immediate) {
|
|
anim.fromValues = anim.values.map(node => node.lastPosition);
|
|
}
|
|
|
|
if (!isAnimating(this)) {
|
|
setActiveBit(this, true);
|
|
|
|
if (!isPaused(this)) {
|
|
this._resume();
|
|
}
|
|
}
|
|
}
|
|
|
|
_resume() {
|
|
if (shared.Globals.skipAnimation) {
|
|
this.finish();
|
|
} else {
|
|
shared.frameLoop.start(this);
|
|
}
|
|
}
|
|
|
|
_stop(goal, cancel) {
|
|
if (isAnimating(this)) {
|
|
setActiveBit(this, false);
|
|
const anim = this.animation;
|
|
shared.each(anim.values, node => {
|
|
node.done = true;
|
|
});
|
|
|
|
if (anim.toValues) {
|
|
anim.onChange = anim.onPause = anim.onResume = undefined;
|
|
}
|
|
|
|
shared.callFluidObservers(this, {
|
|
type: 'idle',
|
|
parent: this
|
|
});
|
|
const result = cancel ? getCancelledResult(this.get()) : getFinishedResult(this.get(), checkFinished(this, goal != null ? goal : anim.to));
|
|
shared.flushCalls(this._pendingCalls, result);
|
|
|
|
if (anim.changed) {
|
|
anim.changed = false;
|
|
sendEvent(this, 'onRest', result, this);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
function checkFinished(target, to) {
|
|
const goal = computeGoal(to);
|
|
const value = computeGoal(target.get());
|
|
return shared.isEqual(value, goal);
|
|
}
|
|
|
|
function createLoopUpdate(props, loop = props.loop, to = props.to) {
|
|
let loopRet = callProp(loop);
|
|
|
|
if (loopRet) {
|
|
const overrides = loopRet !== true && inferTo(loopRet);
|
|
const reverse = (overrides || props).reverse;
|
|
const reset = !overrides || overrides.reset;
|
|
return createUpdate(_extends({}, props, {
|
|
loop,
|
|
default: false,
|
|
pause: undefined,
|
|
to: !reverse || isAsyncTo(to) ? to : undefined,
|
|
from: reset ? props.from : undefined,
|
|
reset
|
|
}, overrides));
|
|
}
|
|
}
|
|
function createUpdate(props) {
|
|
const {
|
|
to,
|
|
from
|
|
} = props = inferTo(props);
|
|
const keys = new Set();
|
|
if (shared.is.obj(to)) findDefined(to, keys);
|
|
if (shared.is.obj(from)) findDefined(from, keys);
|
|
props.keys = keys.size ? Array.from(keys) : null;
|
|
return props;
|
|
}
|
|
function declareUpdate(props) {
|
|
const update = createUpdate(props);
|
|
|
|
if (shared.is.und(update.default)) {
|
|
update.default = getDefaultProps(update);
|
|
}
|
|
|
|
return update;
|
|
}
|
|
|
|
function findDefined(values, keys) {
|
|
shared.eachProp(values, (value, key) => value != null && keys.add(key));
|
|
}
|
|
|
|
const ACTIVE_EVENTS = ['onStart', 'onRest', 'onChange', 'onPause', 'onResume'];
|
|
|
|
function mergeActiveFn(target, props, type) {
|
|
target.animation[type] = props[type] !== getDefaultProp(props, type) ? resolveProp(props[type], target.key) : undefined;
|
|
}
|
|
|
|
function sendEvent(target, type, ...args) {
|
|
var _target$animation$typ, _target$animation, _target$defaultProps$, _target$defaultProps;
|
|
|
|
(_target$animation$typ = (_target$animation = target.animation)[type]) == null ? void 0 : _target$animation$typ.call(_target$animation, ...args);
|
|
(_target$defaultProps$ = (_target$defaultProps = target.defaultProps)[type]) == null ? void 0 : _target$defaultProps$.call(_target$defaultProps, ...args);
|
|
}
|
|
|
|
const BATCHED_EVENTS = ['onStart', 'onChange', 'onRest'];
|
|
let nextId = 1;
|
|
class Controller {
|
|
constructor(props, flush) {
|
|
this.id = nextId++;
|
|
this.springs = {};
|
|
this.queue = [];
|
|
this.ref = void 0;
|
|
this._flush = void 0;
|
|
this._initialProps = void 0;
|
|
this._lastAsyncId = 0;
|
|
this._active = new Set();
|
|
this._changed = new Set();
|
|
this._started = false;
|
|
this._item = void 0;
|
|
this._state = {
|
|
paused: false,
|
|
pauseQueue: new Set(),
|
|
resumeQueue: new Set(),
|
|
timeouts: new Set()
|
|
};
|
|
this._events = {
|
|
onStart: new Map(),
|
|
onChange: new Map(),
|
|
onRest: new Map()
|
|
};
|
|
this._onFrame = this._onFrame.bind(this);
|
|
|
|
if (flush) {
|
|
this._flush = flush;
|
|
}
|
|
|
|
if (props) {
|
|
this.start(_extends({
|
|
default: true
|
|
}, props));
|
|
}
|
|
}
|
|
|
|
get idle() {
|
|
return !this._state.asyncTo && Object.values(this.springs).every(spring => {
|
|
return spring.idle && !spring.isDelayed && !spring.isPaused;
|
|
});
|
|
}
|
|
|
|
get item() {
|
|
return this._item;
|
|
}
|
|
|
|
set item(item) {
|
|
this._item = item;
|
|
}
|
|
|
|
get() {
|
|
const values = {};
|
|
this.each((spring, key) => values[key] = spring.get());
|
|
return values;
|
|
}
|
|
|
|
set(values) {
|
|
for (const key in values) {
|
|
const value = values[key];
|
|
|
|
if (!shared.is.und(value)) {
|
|
this.springs[key].set(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
update(props) {
|
|
if (props) {
|
|
this.queue.push(createUpdate(props));
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
start(props) {
|
|
let {
|
|
queue
|
|
} = this;
|
|
|
|
if (props) {
|
|
queue = shared.toArray(props).map(createUpdate);
|
|
} else {
|
|
this.queue = [];
|
|
}
|
|
|
|
if (this._flush) {
|
|
return this._flush(this, queue);
|
|
}
|
|
|
|
prepareKeys(this, queue);
|
|
return flushUpdateQueue(this, queue);
|
|
}
|
|
|
|
stop(arg, keys) {
|
|
if (arg !== !!arg) {
|
|
keys = arg;
|
|
}
|
|
|
|
if (keys) {
|
|
const springs = this.springs;
|
|
shared.each(shared.toArray(keys), key => springs[key].stop(!!arg));
|
|
} else {
|
|
stopAsync(this._state, this._lastAsyncId);
|
|
this.each(spring => spring.stop(!!arg));
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
pause(keys) {
|
|
if (shared.is.und(keys)) {
|
|
this.start({
|
|
pause: true
|
|
});
|
|
} else {
|
|
const springs = this.springs;
|
|
shared.each(shared.toArray(keys), key => springs[key].pause());
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
resume(keys) {
|
|
if (shared.is.und(keys)) {
|
|
this.start({
|
|
pause: false
|
|
});
|
|
} else {
|
|
const springs = this.springs;
|
|
shared.each(shared.toArray(keys), key => springs[key].resume());
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
each(iterator) {
|
|
shared.eachProp(this.springs, iterator);
|
|
}
|
|
|
|
_onFrame() {
|
|
const {
|
|
onStart,
|
|
onChange,
|
|
onRest
|
|
} = this._events;
|
|
const active = this._active.size > 0;
|
|
const changed = this._changed.size > 0;
|
|
|
|
if (active && !this._started || changed && !this._started) {
|
|
this._started = true;
|
|
shared.flush(onStart, ([onStart, result]) => {
|
|
result.value = this.get();
|
|
onStart(result, this, this._item);
|
|
});
|
|
}
|
|
|
|
const idle = !active && this._started;
|
|
const values = changed || idle && onRest.size ? this.get() : null;
|
|
|
|
if (changed && onChange.size) {
|
|
shared.flush(onChange, ([onChange, result]) => {
|
|
result.value = values;
|
|
onChange(result, this, this._item);
|
|
});
|
|
}
|
|
|
|
if (idle) {
|
|
this._started = false;
|
|
shared.flush(onRest, ([onRest, result]) => {
|
|
result.value = values;
|
|
onRest(result, this, this._item);
|
|
});
|
|
}
|
|
}
|
|
|
|
eventObserved(event) {
|
|
if (event.type == 'change') {
|
|
this._changed.add(event.parent);
|
|
|
|
if (!event.idle) {
|
|
this._active.add(event.parent);
|
|
}
|
|
} else if (event.type == 'idle') {
|
|
this._active.delete(event.parent);
|
|
} else return;
|
|
|
|
shared.raf.onFrame(this._onFrame);
|
|
}
|
|
|
|
}
|
|
function flushUpdateQueue(ctrl, queue) {
|
|
return Promise.all(queue.map(props => flushUpdate(ctrl, props))).then(results => getCombinedResult(ctrl, results));
|
|
}
|
|
async function flushUpdate(ctrl, props, isLoop) {
|
|
const {
|
|
keys,
|
|
to,
|
|
from,
|
|
loop,
|
|
onRest,
|
|
onResolve
|
|
} = props;
|
|
const defaults = shared.is.obj(props.default) && props.default;
|
|
|
|
if (loop) {
|
|
props.loop = false;
|
|
}
|
|
|
|
if (to === false) props.to = null;
|
|
if (from === false) props.from = null;
|
|
const asyncTo = shared.is.arr(to) || shared.is.fun(to) ? to : undefined;
|
|
|
|
if (asyncTo) {
|
|
props.to = undefined;
|
|
props.onRest = undefined;
|
|
|
|
if (defaults) {
|
|
defaults.onRest = undefined;
|
|
}
|
|
} else {
|
|
shared.each(BATCHED_EVENTS, key => {
|
|
const handler = props[key];
|
|
|
|
if (shared.is.fun(handler)) {
|
|
const queue = ctrl['_events'][key];
|
|
|
|
props[key] = ({
|
|
finished,
|
|
cancelled
|
|
}) => {
|
|
const result = queue.get(handler);
|
|
|
|
if (result) {
|
|
if (!finished) result.finished = false;
|
|
if (cancelled) result.cancelled = true;
|
|
} else {
|
|
queue.set(handler, {
|
|
value: null,
|
|
finished: finished || false,
|
|
cancelled: cancelled || false
|
|
});
|
|
}
|
|
};
|
|
|
|
if (defaults) {
|
|
defaults[key] = props[key];
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
const state = ctrl['_state'];
|
|
|
|
if (props.pause === !state.paused) {
|
|
state.paused = props.pause;
|
|
shared.flushCalls(props.pause ? state.pauseQueue : state.resumeQueue);
|
|
} else if (state.paused) {
|
|
props.pause = true;
|
|
}
|
|
|
|
const promises = (keys || Object.keys(ctrl.springs)).map(key => ctrl.springs[key].start(props));
|
|
const cancel = props.cancel === true || getDefaultProp(props, 'cancel') === true;
|
|
|
|
if (asyncTo || cancel && state.asyncId) {
|
|
promises.push(scheduleProps(++ctrl['_lastAsyncId'], {
|
|
props,
|
|
state,
|
|
actions: {
|
|
pause: shared.noop,
|
|
resume: shared.noop,
|
|
|
|
start(props, resolve) {
|
|
if (cancel) {
|
|
stopAsync(state, ctrl['_lastAsyncId']);
|
|
resolve(getCancelledResult(ctrl));
|
|
} else {
|
|
props.onRest = onRest;
|
|
resolve(runAsync(asyncTo, props, state, ctrl));
|
|
}
|
|
}
|
|
|
|
}
|
|
}));
|
|
}
|
|
|
|
if (state.paused) {
|
|
await new Promise(resume => {
|
|
state.resumeQueue.add(resume);
|
|
});
|
|
}
|
|
|
|
const result = getCombinedResult(ctrl, await Promise.all(promises));
|
|
|
|
if (loop && result.finished && !(isLoop && result.noop)) {
|
|
const nextProps = createLoopUpdate(props, loop, to);
|
|
|
|
if (nextProps) {
|
|
prepareKeys(ctrl, [nextProps]);
|
|
return flushUpdate(ctrl, nextProps, true);
|
|
}
|
|
}
|
|
|
|
if (onResolve) {
|
|
shared.raf.batchedUpdates(() => onResolve(result, ctrl, ctrl.item));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
function getSprings(ctrl, props) {
|
|
const springs = _extends({}, ctrl.springs);
|
|
|
|
if (props) {
|
|
shared.each(shared.toArray(props), props => {
|
|
if (shared.is.und(props.keys)) {
|
|
props = createUpdate(props);
|
|
}
|
|
|
|
if (!shared.is.obj(props.to)) {
|
|
props = _extends({}, props, {
|
|
to: undefined
|
|
});
|
|
}
|
|
|
|
prepareSprings(springs, props, key => {
|
|
return createSpring(key);
|
|
});
|
|
});
|
|
}
|
|
|
|
setSprings(ctrl, springs);
|
|
return springs;
|
|
}
|
|
function setSprings(ctrl, springs) {
|
|
shared.eachProp(springs, (spring, key) => {
|
|
if (!ctrl.springs[key]) {
|
|
ctrl.springs[key] = spring;
|
|
shared.addFluidObserver(spring, ctrl);
|
|
}
|
|
});
|
|
}
|
|
|
|
function createSpring(key, observer) {
|
|
const spring = new SpringValue();
|
|
spring.key = key;
|
|
|
|
if (observer) {
|
|
shared.addFluidObserver(spring, observer);
|
|
}
|
|
|
|
return spring;
|
|
}
|
|
|
|
function prepareSprings(springs, props, create) {
|
|
if (props.keys) {
|
|
shared.each(props.keys, key => {
|
|
const spring = springs[key] || (springs[key] = create(key));
|
|
spring['_prepareNode'](props);
|
|
});
|
|
}
|
|
}
|
|
|
|
function prepareKeys(ctrl, queue) {
|
|
shared.each(queue, props => {
|
|
prepareSprings(ctrl.springs, props, key => {
|
|
return createSpring(key, ctrl);
|
|
});
|
|
});
|
|
}
|
|
|
|
function _objectWithoutPropertiesLoose(source, excluded) {
|
|
if (source == null) return {};
|
|
var target = {};
|
|
var sourceKeys = Object.keys(source);
|
|
var key, i;
|
|
|
|
for (i = 0; i < sourceKeys.length; i++) {
|
|
key = sourceKeys[i];
|
|
if (excluded.indexOf(key) >= 0) continue;
|
|
target[key] = source[key];
|
|
}
|
|
|
|
return target;
|
|
}
|
|
|
|
const _excluded$3 = ["children"];
|
|
const SpringContext = _ref => {
|
|
let {
|
|
children
|
|
} = _ref,
|
|
props = _objectWithoutPropertiesLoose(_ref, _excluded$3);
|
|
|
|
const inherited = React.useContext(ctx);
|
|
const pause = props.pause || !!inherited.pause,
|
|
immediate = props.immediate || !!inherited.immediate;
|
|
props = shared.useMemoOne(() => ({
|
|
pause,
|
|
immediate
|
|
}), [pause, immediate]);
|
|
const {
|
|
Provider
|
|
} = ctx;
|
|
return React__namespace.createElement(Provider, {
|
|
value: props
|
|
}, children);
|
|
};
|
|
const ctx = makeContext(SpringContext, {});
|
|
SpringContext.Provider = ctx.Provider;
|
|
SpringContext.Consumer = ctx.Consumer;
|
|
|
|
function makeContext(target, init) {
|
|
Object.assign(target, React__namespace.createContext(init));
|
|
target.Provider._context = target;
|
|
target.Consumer._context = target;
|
|
return target;
|
|
}
|
|
|
|
const SpringRef = () => {
|
|
const current = [];
|
|
|
|
const SpringRef = function SpringRef(props) {
|
|
shared.deprecateDirectCall();
|
|
const results = [];
|
|
shared.each(current, (ctrl, i) => {
|
|
if (shared.is.und(props)) {
|
|
results.push(ctrl.start());
|
|
} else {
|
|
const update = _getProps(props, ctrl, i);
|
|
|
|
if (update) {
|
|
results.push(ctrl.start(update));
|
|
}
|
|
}
|
|
});
|
|
return results;
|
|
};
|
|
|
|
SpringRef.current = current;
|
|
|
|
SpringRef.add = function (ctrl) {
|
|
if (!current.includes(ctrl)) {
|
|
current.push(ctrl);
|
|
}
|
|
};
|
|
|
|
SpringRef.delete = function (ctrl) {
|
|
const i = current.indexOf(ctrl);
|
|
if (~i) current.splice(i, 1);
|
|
};
|
|
|
|
SpringRef.pause = function () {
|
|
shared.each(current, ctrl => ctrl.pause(...arguments));
|
|
return this;
|
|
};
|
|
|
|
SpringRef.resume = function () {
|
|
shared.each(current, ctrl => ctrl.resume(...arguments));
|
|
return this;
|
|
};
|
|
|
|
SpringRef.set = function (values) {
|
|
shared.each(current, ctrl => ctrl.set(values));
|
|
};
|
|
|
|
SpringRef.start = function (props) {
|
|
const results = [];
|
|
shared.each(current, (ctrl, i) => {
|
|
if (shared.is.und(props)) {
|
|
results.push(ctrl.start());
|
|
} else {
|
|
const update = this._getProps(props, ctrl, i);
|
|
|
|
if (update) {
|
|
results.push(ctrl.start(update));
|
|
}
|
|
}
|
|
});
|
|
return results;
|
|
};
|
|
|
|
SpringRef.stop = function () {
|
|
shared.each(current, ctrl => ctrl.stop(...arguments));
|
|
return this;
|
|
};
|
|
|
|
SpringRef.update = function (props) {
|
|
shared.each(current, (ctrl, i) => ctrl.update(this._getProps(props, ctrl, i)));
|
|
return this;
|
|
};
|
|
|
|
const _getProps = function _getProps(arg, ctrl, index) {
|
|
return shared.is.fun(arg) ? arg(index, ctrl) : arg;
|
|
};
|
|
|
|
SpringRef._getProps = _getProps;
|
|
return SpringRef;
|
|
};
|
|
|
|
function useSprings(length, props, deps) {
|
|
const propsFn = shared.is.fun(props) && props;
|
|
if (propsFn && !deps) deps = [];
|
|
const ref = React.useMemo(() => propsFn || arguments.length == 3 ? SpringRef() : void 0, []);
|
|
const layoutId = React.useRef(0);
|
|
const forceUpdate = shared.useForceUpdate();
|
|
const state = React.useMemo(() => ({
|
|
ctrls: [],
|
|
queue: [],
|
|
|
|
flush(ctrl, updates) {
|
|
const springs = getSprings(ctrl, updates);
|
|
const canFlushSync = layoutId.current > 0 && !state.queue.length && !Object.keys(springs).some(key => !ctrl.springs[key]);
|
|
return canFlushSync ? flushUpdateQueue(ctrl, updates) : new Promise(resolve => {
|
|
setSprings(ctrl, springs);
|
|
state.queue.push(() => {
|
|
resolve(flushUpdateQueue(ctrl, updates));
|
|
});
|
|
forceUpdate();
|
|
});
|
|
}
|
|
|
|
}), []);
|
|
const ctrls = React.useRef([...state.ctrls]);
|
|
const updates = [];
|
|
const prevLength = shared.usePrev(length) || 0;
|
|
React.useMemo(() => {
|
|
shared.each(ctrls.current.slice(length, prevLength), ctrl => {
|
|
detachRefs(ctrl, ref);
|
|
ctrl.stop(true);
|
|
});
|
|
ctrls.current.length = length;
|
|
declareUpdates(prevLength, length);
|
|
}, [length]);
|
|
React.useMemo(() => {
|
|
declareUpdates(0, Math.min(prevLength, length));
|
|
}, deps);
|
|
|
|
function declareUpdates(startIndex, endIndex) {
|
|
for (let i = startIndex; i < endIndex; i++) {
|
|
const ctrl = ctrls.current[i] || (ctrls.current[i] = new Controller(null, state.flush));
|
|
const update = propsFn ? propsFn(i, ctrl) : props[i];
|
|
|
|
if (update) {
|
|
updates[i] = declareUpdate(update);
|
|
}
|
|
}
|
|
}
|
|
|
|
const springs = ctrls.current.map((ctrl, i) => getSprings(ctrl, updates[i]));
|
|
const context = React.useContext(SpringContext);
|
|
const prevContext = shared.usePrev(context);
|
|
const hasContext = context !== prevContext && hasProps(context);
|
|
shared.useLayoutEffect(() => {
|
|
layoutId.current++;
|
|
state.ctrls = ctrls.current;
|
|
const {
|
|
queue
|
|
} = state;
|
|
|
|
if (queue.length) {
|
|
state.queue = [];
|
|
shared.each(queue, cb => cb());
|
|
}
|
|
|
|
shared.each(ctrls.current, (ctrl, i) => {
|
|
ref == null ? void 0 : ref.add(ctrl);
|
|
|
|
if (hasContext) {
|
|
ctrl.start({
|
|
default: context
|
|
});
|
|
}
|
|
|
|
const update = updates[i];
|
|
|
|
if (update) {
|
|
replaceRef(ctrl, update.ref);
|
|
|
|
if (ctrl.ref) {
|
|
ctrl.queue.push(update);
|
|
} else {
|
|
ctrl.start(update);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
shared.useOnce(() => () => {
|
|
shared.each(state.ctrls, ctrl => ctrl.stop(true));
|
|
});
|
|
const values = springs.map(x => _extends({}, x));
|
|
return ref ? [values, ref] : values;
|
|
}
|
|
|
|
function useSpring(props, deps) {
|
|
const isFn = shared.is.fun(props);
|
|
const [[values], ref] = useSprings(1, isFn ? props : [props], isFn ? deps || [] : deps);
|
|
return isFn || arguments.length == 2 ? [values, ref] : values;
|
|
}
|
|
|
|
const initSpringRef = () => SpringRef();
|
|
|
|
const useSpringRef = () => React.useState(initSpringRef)[0];
|
|
|
|
function useTrail(length, propsArg, deps) {
|
|
var _passedRef;
|
|
|
|
const propsFn = shared.is.fun(propsArg) && propsArg;
|
|
if (propsFn && !deps) deps = [];
|
|
let reverse = true;
|
|
let passedRef = undefined;
|
|
const result = useSprings(length, (i, ctrl) => {
|
|
const props = propsFn ? propsFn(i, ctrl) : propsArg;
|
|
passedRef = props.ref;
|
|
reverse = reverse && props.reverse;
|
|
return props;
|
|
}, deps || [{}]);
|
|
const ref = (_passedRef = passedRef) != null ? _passedRef : result[1];
|
|
shared.useLayoutEffect(() => {
|
|
shared.each(ref.current, (ctrl, i) => {
|
|
const parent = ref.current[i + (reverse ? 1 : -1)];
|
|
|
|
if (parent) {
|
|
ctrl.start({
|
|
to: parent.springs
|
|
});
|
|
} else {
|
|
ctrl.start();
|
|
}
|
|
});
|
|
}, deps);
|
|
|
|
if (propsFn || arguments.length == 3) {
|
|
ref['_getProps'] = (propsArg, ctrl, i) => {
|
|
const props = shared.is.fun(propsArg) ? propsArg(i, ctrl) : propsArg;
|
|
|
|
if (props) {
|
|
const parent = ref.current[i + (props.reverse ? 1 : -1)];
|
|
if (parent) props.to = parent.springs;
|
|
return props;
|
|
}
|
|
};
|
|
|
|
return result;
|
|
}
|
|
|
|
ref['start'] = propsArg => {
|
|
const results = [];
|
|
shared.each(ref.current, (ctrl, i) => {
|
|
const props = shared.is.fun(propsArg) ? propsArg(i, ctrl) : propsArg;
|
|
const parent = ref.current[i + (reverse ? 1 : -1)];
|
|
|
|
if (parent) {
|
|
results.push(ctrl.start(_extends({}, props, {
|
|
to: parent.springs
|
|
})));
|
|
} else {
|
|
results.push(ctrl.start(_extends({}, props)));
|
|
}
|
|
});
|
|
return results;
|
|
};
|
|
|
|
return result[0];
|
|
}
|
|
|
|
let TransitionPhase;
|
|
|
|
(function (TransitionPhase) {
|
|
TransitionPhase["MOUNT"] = "mount";
|
|
TransitionPhase["ENTER"] = "enter";
|
|
TransitionPhase["UPDATE"] = "update";
|
|
TransitionPhase["LEAVE"] = "leave";
|
|
})(TransitionPhase || (TransitionPhase = {}));
|
|
|
|
function useTransition(data, props, deps) {
|
|
const propsFn = shared.is.fun(props) && props;
|
|
const {
|
|
reset,
|
|
sort,
|
|
trail = 0,
|
|
expires = true,
|
|
exitBeforeEnter = false,
|
|
onDestroyed,
|
|
ref: propsRef,
|
|
config: propsConfig
|
|
} = propsFn ? propsFn() : props;
|
|
const ref = React.useMemo(() => propsFn || arguments.length == 3 ? SpringRef() : void 0, []);
|
|
const items = shared.toArray(data);
|
|
const transitions = [];
|
|
const usedTransitions = React.useRef(null);
|
|
const prevTransitions = reset ? null : usedTransitions.current;
|
|
shared.useLayoutEffect(() => {
|
|
usedTransitions.current = transitions;
|
|
});
|
|
shared.useOnce(() => {
|
|
shared.each(usedTransitions.current, t => {
|
|
var _t$ctrl$ref;
|
|
|
|
(_t$ctrl$ref = t.ctrl.ref) == null ? void 0 : _t$ctrl$ref.add(t.ctrl);
|
|
const change = changes.get(t);
|
|
|
|
if (change) {
|
|
t.ctrl.start(change.payload);
|
|
}
|
|
});
|
|
return () => {
|
|
shared.each(usedTransitions.current, t => {
|
|
if (t.expired) {
|
|
clearTimeout(t.expirationId);
|
|
}
|
|
|
|
detachRefs(t.ctrl, ref);
|
|
t.ctrl.stop(true);
|
|
});
|
|
};
|
|
});
|
|
const keys = getKeys(items, propsFn ? propsFn() : props, prevTransitions);
|
|
const expired = reset && usedTransitions.current || [];
|
|
shared.useLayoutEffect(() => shared.each(expired, ({
|
|
ctrl,
|
|
item,
|
|
key
|
|
}) => {
|
|
detachRefs(ctrl, ref);
|
|
callProp(onDestroyed, item, key);
|
|
}));
|
|
const reused = [];
|
|
if (prevTransitions) shared.each(prevTransitions, (t, i) => {
|
|
if (t.expired) {
|
|
clearTimeout(t.expirationId);
|
|
expired.push(t);
|
|
} else {
|
|
i = reused[i] = keys.indexOf(t.key);
|
|
if (~i) transitions[i] = t;
|
|
}
|
|
});
|
|
shared.each(items, (item, i) => {
|
|
if (!transitions[i]) {
|
|
transitions[i] = {
|
|
key: keys[i],
|
|
item,
|
|
phase: TransitionPhase.MOUNT,
|
|
ctrl: new Controller()
|
|
};
|
|
transitions[i].ctrl.item = item;
|
|
}
|
|
});
|
|
|
|
if (reused.length) {
|
|
let i = -1;
|
|
const {
|
|
leave
|
|
} = propsFn ? propsFn() : props;
|
|
shared.each(reused, (keyIndex, prevIndex) => {
|
|
const t = prevTransitions[prevIndex];
|
|
|
|
if (~keyIndex) {
|
|
i = transitions.indexOf(t);
|
|
transitions[i] = _extends({}, t, {
|
|
item: items[keyIndex]
|
|
});
|
|
} else if (leave) {
|
|
transitions.splice(++i, 0, t);
|
|
}
|
|
});
|
|
}
|
|
|
|
if (shared.is.fun(sort)) {
|
|
transitions.sort((a, b) => sort(a.item, b.item));
|
|
}
|
|
|
|
let delay = -trail;
|
|
const forceUpdate = shared.useForceUpdate();
|
|
const defaultProps = getDefaultProps(props);
|
|
const changes = new Map();
|
|
const exitingTransitions = React.useRef(new Map());
|
|
const forceChange = React.useRef(false);
|
|
shared.each(transitions, (t, i) => {
|
|
const key = t.key;
|
|
const prevPhase = t.phase;
|
|
const p = propsFn ? propsFn() : props;
|
|
let to;
|
|
let phase;
|
|
let propsDelay = callProp(p.delay || 0, key);
|
|
|
|
if (prevPhase == TransitionPhase.MOUNT) {
|
|
to = p.enter;
|
|
phase = TransitionPhase.ENTER;
|
|
} else {
|
|
const isLeave = keys.indexOf(key) < 0;
|
|
|
|
if (prevPhase != TransitionPhase.LEAVE) {
|
|
if (isLeave) {
|
|
to = p.leave;
|
|
phase = TransitionPhase.LEAVE;
|
|
} else if (to = p.update) {
|
|
phase = TransitionPhase.UPDATE;
|
|
} else return;
|
|
} else if (!isLeave) {
|
|
to = p.enter;
|
|
phase = TransitionPhase.ENTER;
|
|
} else return;
|
|
}
|
|
|
|
to = callProp(to, t.item, i);
|
|
to = shared.is.obj(to) ? inferTo(to) : {
|
|
to
|
|
};
|
|
|
|
if (!to.config) {
|
|
const config = propsConfig || defaultProps.config;
|
|
to.config = callProp(config, t.item, i, phase);
|
|
}
|
|
|
|
delay += trail;
|
|
|
|
const payload = _extends({}, defaultProps, {
|
|
delay: propsDelay + delay,
|
|
ref: propsRef,
|
|
immediate: p.immediate,
|
|
reset: false
|
|
}, to);
|
|
|
|
if (phase == TransitionPhase.ENTER && shared.is.und(payload.from)) {
|
|
const _p = propsFn ? propsFn() : props;
|
|
|
|
const from = shared.is.und(_p.initial) || prevTransitions ? _p.from : _p.initial;
|
|
payload.from = callProp(from, t.item, i);
|
|
}
|
|
|
|
const {
|
|
onResolve
|
|
} = payload;
|
|
|
|
payload.onResolve = result => {
|
|
callProp(onResolve, result);
|
|
const transitions = usedTransitions.current;
|
|
const t = transitions.find(t => t.key === key);
|
|
if (!t) return;
|
|
|
|
if (result.cancelled && t.phase != TransitionPhase.UPDATE) {
|
|
return;
|
|
}
|
|
|
|
if (t.ctrl.idle) {
|
|
const idle = transitions.every(t => t.ctrl.idle);
|
|
|
|
if (t.phase == TransitionPhase.LEAVE) {
|
|
const expiry = callProp(expires, t.item);
|
|
|
|
if (expiry !== false) {
|
|
const expiryMs = expiry === true ? 0 : expiry;
|
|
t.expired = true;
|
|
|
|
if (!idle && expiryMs > 0) {
|
|
if (expiryMs <= 0x7fffffff) t.expirationId = setTimeout(forceUpdate, expiryMs);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (idle && transitions.some(t => t.expired)) {
|
|
exitingTransitions.current.delete(t);
|
|
|
|
if (exitBeforeEnter) {
|
|
forceChange.current = true;
|
|
}
|
|
|
|
forceUpdate();
|
|
}
|
|
}
|
|
};
|
|
|
|
const springs = getSprings(t.ctrl, payload);
|
|
|
|
if (phase === TransitionPhase.LEAVE && exitBeforeEnter) {
|
|
exitingTransitions.current.set(t, {
|
|
phase,
|
|
springs,
|
|
payload
|
|
});
|
|
} else {
|
|
changes.set(t, {
|
|
phase,
|
|
springs,
|
|
payload
|
|
});
|
|
}
|
|
});
|
|
const context = React.useContext(SpringContext);
|
|
const prevContext = shared.usePrev(context);
|
|
const hasContext = context !== prevContext && hasProps(context);
|
|
shared.useLayoutEffect(() => {
|
|
if (hasContext) {
|
|
shared.each(transitions, t => {
|
|
t.ctrl.start({
|
|
default: context
|
|
});
|
|
});
|
|
}
|
|
}, [context]);
|
|
shared.each(changes, (_, t) => {
|
|
if (exitingTransitions.current.size) {
|
|
const ind = transitions.findIndex(state => state.key === t.key);
|
|
transitions.splice(ind, 1);
|
|
}
|
|
});
|
|
shared.useLayoutEffect(() => {
|
|
shared.each(exitingTransitions.current.size ? exitingTransitions.current : changes, ({
|
|
phase,
|
|
payload
|
|
}, t) => {
|
|
const {
|
|
ctrl
|
|
} = t;
|
|
t.phase = phase;
|
|
ref == null ? void 0 : ref.add(ctrl);
|
|
|
|
if (hasContext && phase == TransitionPhase.ENTER) {
|
|
ctrl.start({
|
|
default: context
|
|
});
|
|
}
|
|
|
|
if (payload) {
|
|
replaceRef(ctrl, payload.ref);
|
|
|
|
if (ctrl.ref && !forceChange.current) {
|
|
ctrl.update(payload);
|
|
} else {
|
|
ctrl.start(payload);
|
|
|
|
if (forceChange.current) {
|
|
forceChange.current = false;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}, reset ? void 0 : deps);
|
|
|
|
const renderTransitions = render => React__namespace.createElement(React__namespace.Fragment, null, transitions.map((t, i) => {
|
|
const {
|
|
springs
|
|
} = changes.get(t) || t.ctrl;
|
|
const elem = render(_extends({}, springs), t.item, t, i);
|
|
return elem && elem.type ? React__namespace.createElement(elem.type, _extends({}, elem.props, {
|
|
key: shared.is.str(t.key) || shared.is.num(t.key) ? t.key : t.ctrl.id,
|
|
ref: elem.ref
|
|
})) : elem;
|
|
}));
|
|
|
|
return ref ? [renderTransitions, ref] : renderTransitions;
|
|
}
|
|
let nextKey = 1;
|
|
|
|
function getKeys(items, {
|
|
key,
|
|
keys = key
|
|
}, prevTransitions) {
|
|
if (keys === null) {
|
|
const reused = new Set();
|
|
return items.map(item => {
|
|
const t = prevTransitions && prevTransitions.find(t => t.item === item && t.phase !== TransitionPhase.LEAVE && !reused.has(t));
|
|
|
|
if (t) {
|
|
reused.add(t);
|
|
return t.key;
|
|
}
|
|
|
|
return nextKey++;
|
|
});
|
|
}
|
|
|
|
return shared.is.und(keys) ? items : shared.is.fun(keys) ? items.map(keys) : shared.toArray(keys);
|
|
}
|
|
|
|
const _excluded$2 = ["children"];
|
|
function Spring(_ref) {
|
|
let {
|
|
children
|
|
} = _ref,
|
|
props = _objectWithoutPropertiesLoose(_ref, _excluded$2);
|
|
|
|
return children(useSpring(props));
|
|
}
|
|
|
|
const _excluded$1 = ["items", "children"];
|
|
function Trail(_ref) {
|
|
let {
|
|
items,
|
|
children
|
|
} = _ref,
|
|
props = _objectWithoutPropertiesLoose(_ref, _excluded$1);
|
|
|
|
const trails = useTrail(items.length, props);
|
|
return items.map((item, index) => {
|
|
const result = children(item, index);
|
|
return shared.is.fun(result) ? result(trails[index]) : result;
|
|
});
|
|
}
|
|
|
|
const _excluded = ["items", "children"];
|
|
function Transition(_ref) {
|
|
let {
|
|
items,
|
|
children
|
|
} = _ref,
|
|
props = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
|
|
return useTransition(items, props)(children);
|
|
}
|
|
|
|
class Interpolation extends FrameValue {
|
|
constructor(source, args) {
|
|
super();
|
|
this.key = void 0;
|
|
this.idle = true;
|
|
this.calc = void 0;
|
|
this._active = new Set();
|
|
this.source = source;
|
|
this.calc = shared.createInterpolator(...args);
|
|
|
|
const value = this._get();
|
|
|
|
const nodeType = animated$1.getAnimatedType(value);
|
|
animated$1.setAnimated(this, nodeType.create(value));
|
|
}
|
|
|
|
advance(_dt) {
|
|
const value = this._get();
|
|
|
|
const oldValue = this.get();
|
|
|
|
if (!shared.isEqual(value, oldValue)) {
|
|
animated$1.getAnimated(this).setValue(value);
|
|
|
|
this._onChange(value, this.idle);
|
|
}
|
|
|
|
if (!this.idle && checkIdle(this._active)) {
|
|
becomeIdle(this);
|
|
}
|
|
}
|
|
|
|
_get() {
|
|
const inputs = shared.is.arr(this.source) ? this.source.map(shared.getFluidValue) : shared.toArray(shared.getFluidValue(this.source));
|
|
return this.calc(...inputs);
|
|
}
|
|
|
|
_start() {
|
|
if (this.idle && !checkIdle(this._active)) {
|
|
this.idle = false;
|
|
shared.each(animated$1.getPayload(this), node => {
|
|
node.done = false;
|
|
});
|
|
|
|
if (shared.Globals.skipAnimation) {
|
|
shared.raf.batchedUpdates(() => this.advance());
|
|
becomeIdle(this);
|
|
} else {
|
|
shared.frameLoop.start(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
_attach() {
|
|
let priority = 1;
|
|
shared.each(shared.toArray(this.source), source => {
|
|
if (shared.hasFluidValue(source)) {
|
|
shared.addFluidObserver(source, this);
|
|
}
|
|
|
|
if (isFrameValue(source)) {
|
|
if (!source.idle) {
|
|
this._active.add(source);
|
|
}
|
|
|
|
priority = Math.max(priority, source.priority + 1);
|
|
}
|
|
});
|
|
this.priority = priority;
|
|
|
|
this._start();
|
|
}
|
|
|
|
_detach() {
|
|
shared.each(shared.toArray(this.source), source => {
|
|
if (shared.hasFluidValue(source)) {
|
|
shared.removeFluidObserver(source, this);
|
|
}
|
|
});
|
|
|
|
this._active.clear();
|
|
|
|
becomeIdle(this);
|
|
}
|
|
|
|
eventObserved(event) {
|
|
if (event.type == 'change') {
|
|
if (event.idle) {
|
|
this.advance();
|
|
} else {
|
|
this._active.add(event.parent);
|
|
|
|
this._start();
|
|
}
|
|
} else if (event.type == 'idle') {
|
|
this._active.delete(event.parent);
|
|
} else if (event.type == 'priority') {
|
|
this.priority = shared.toArray(this.source).reduce((highest, parent) => Math.max(highest, (isFrameValue(parent) ? parent.priority : 0) + 1), 0);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
function isIdle(source) {
|
|
return source.idle !== false;
|
|
}
|
|
|
|
function checkIdle(active) {
|
|
return !active.size || Array.from(active).every(isIdle);
|
|
}
|
|
|
|
function becomeIdle(self) {
|
|
if (!self.idle) {
|
|
self.idle = true;
|
|
shared.each(animated$1.getPayload(self), node => {
|
|
node.done = true;
|
|
});
|
|
shared.callFluidObservers(self, {
|
|
type: 'idle',
|
|
parent: self
|
|
});
|
|
}
|
|
}
|
|
|
|
const to = (source, ...args) => new Interpolation(source, args);
|
|
const interpolate = (source, ...args) => (shared.deprecateInterpolate(), new Interpolation(source, args));
|
|
|
|
shared.Globals.assign({
|
|
createStringInterpolator: shared.createStringInterpolator,
|
|
to: (source, args) => new Interpolation(source, args)
|
|
});
|
|
const update = shared.frameLoop.advance;
|
|
|
|
Object.defineProperty(exports, 'Globals', {
|
|
enumerable: true,
|
|
get: function () {
|
|
return shared.Globals;
|
|
}
|
|
});
|
|
Object.defineProperty(exports, 'createInterpolator', {
|
|
enumerable: true,
|
|
get: function () {
|
|
return shared.createInterpolator;
|
|
}
|
|
});
|
|
exports.BailSignal = BailSignal;
|
|
exports.Controller = Controller;
|
|
exports.FrameValue = FrameValue;
|
|
exports.Interpolation = Interpolation;
|
|
exports.Spring = Spring;
|
|
exports.SpringContext = SpringContext;
|
|
exports.SpringRef = SpringRef;
|
|
exports.SpringValue = SpringValue;
|
|
exports.Trail = Trail;
|
|
exports.Transition = Transition;
|
|
exports.config = config;
|
|
exports.easings = easings;
|
|
exports.inferTo = inferTo;
|
|
exports.interpolate = interpolate;
|
|
exports.to = to;
|
|
exports.update = update;
|
|
exports.useChain = useChain;
|
|
exports.useSpring = useSpring;
|
|
exports.useSpringRef = useSpringRef;
|
|
exports.useSprings = useSprings;
|
|
exports.useTrail = useTrail;
|
|
exports.useTransition = useTransition;
|
|
Object.keys(animated).forEach(function (k) {
|
|
if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, {
|
|
enumerable: true,
|
|
get: function () {
|
|
return animated[k];
|
|
}
|
|
});
|
|
});
|
|
Object.keys(interpolation).forEach(function (k) {
|
|
if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, {
|
|
enumerable: true,
|
|
get: function () {
|
|
return interpolation[k];
|
|
}
|
|
});
|
|
});
|
|
|
|
}, function(modId) { var map = {}; return __REQUIRE__(map[modId], modId); })
|
|
__DEFINE__(1656641689789, function(require, module, exports) {
|
|
|
|
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
|
var shared = require('@react-spring/shared');
|
|
var React = require('react');
|
|
var animated$1 = require('@react-spring/animated');
|
|
var animated = require('@react-spring/types/animated');
|
|
var interpolation = require('@react-spring/types/interpolation');
|
|
|
|
function _interopNamespace(e) {
|
|
if (e && e.__esModule) return e;
|
|
var n = Object.create(null);
|
|
if (e) {
|
|
Object.keys(e).forEach(function (k) {
|
|
if (k !== 'default') {
|
|
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
Object.defineProperty(n, k, d.get ? d : {
|
|
enumerable: true,
|
|
get: function () {
|
|
return e[k];
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
n['default'] = e;
|
|
return Object.freeze(n);
|
|
}
|
|
|
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
|
|
function _extends() {
|
|
_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;
|
|
};
|
|
|
|
return _extends.apply(this, arguments);
|
|
}
|
|
|
|
function callProp(value, ...args) {
|
|
return shared.is.fun(value) ? value(...args) : value;
|
|
}
|
|
const matchProp = (value, key) => value === true || !!(key && value && (shared.is.fun(value) ? value(key) : shared.toArray(value).includes(key)));
|
|
const resolveProp = (prop, key) => shared.is.obj(prop) ? key && prop[key] : prop;
|
|
const getDefaultProp = (props, key) => props.default === true ? props[key] : props.default ? props.default[key] : undefined;
|
|
|
|
const noopTransform = value => value;
|
|
|
|
const getDefaultProps = (props, transform = noopTransform) => {
|
|
let keys = DEFAULT_PROPS;
|
|
|
|
if (props.default && props.default !== true) {
|
|
props = props.default;
|
|
keys = Object.keys(props);
|
|
}
|
|
|
|
const defaults = {};
|
|
|
|
for (const key of keys) {
|
|
const value = transform(props[key], key);
|
|
|
|
if (!shared.is.und(value)) {
|
|
defaults[key] = value;
|
|
}
|
|
}
|
|
|
|
return defaults;
|
|
};
|
|
const DEFAULT_PROPS = ['config', 'onProps', 'onStart', 'onChange', 'onPause', 'onResume', 'onRest'];
|
|
const RESERVED_PROPS = {
|
|
config: 1,
|
|
from: 1,
|
|
to: 1,
|
|
ref: 1,
|
|
loop: 1,
|
|
reset: 1,
|
|
pause: 1,
|
|
cancel: 1,
|
|
reverse: 1,
|
|
immediate: 1,
|
|
default: 1,
|
|
delay: 1,
|
|
onProps: 1,
|
|
onStart: 1,
|
|
onChange: 1,
|
|
onPause: 1,
|
|
onResume: 1,
|
|
onRest: 1,
|
|
onResolve: 1,
|
|
items: 1,
|
|
trail: 1,
|
|
sort: 1,
|
|
expires: 1,
|
|
initial: 1,
|
|
enter: 1,
|
|
update: 1,
|
|
leave: 1,
|
|
children: 1,
|
|
onDestroyed: 1,
|
|
keys: 1,
|
|
callId: 1,
|
|
parentId: 1
|
|
};
|
|
|
|
function getForwardProps(props) {
|
|
const forward = {};
|
|
let count = 0;
|
|
shared.eachProp(props, (value, prop) => {
|
|
if (!RESERVED_PROPS[prop]) {
|
|
forward[prop] = value;
|
|
count++;
|
|
}
|
|
});
|
|
|
|
if (count) {
|
|
return forward;
|
|
}
|
|
}
|
|
|
|
function inferTo(props) {
|
|
const to = getForwardProps(props);
|
|
|
|
if (to) {
|
|
const out = {
|
|
to
|
|
};
|
|
shared.eachProp(props, (val, key) => key in to || (out[key] = val));
|
|
return out;
|
|
}
|
|
|
|
return _extends({}, props);
|
|
}
|
|
function computeGoal(value) {
|
|
value = shared.getFluidValue(value);
|
|
return shared.is.arr(value) ? value.map(computeGoal) : shared.isAnimatedString(value) ? shared.Globals.createStringInterpolator({
|
|
range: [0, 1],
|
|
output: [value, value]
|
|
})(1) : value;
|
|
}
|
|
function hasProps(props) {
|
|
for (const _ in props) return true;
|
|
|
|
return false;
|
|
}
|
|
function isAsyncTo(to) {
|
|
return shared.is.fun(to) || shared.is.arr(to) && shared.is.obj(to[0]);
|
|
}
|
|
function detachRefs(ctrl, ref) {
|
|
var _ctrl$ref;
|
|
|
|
(_ctrl$ref = ctrl.ref) == null ? void 0 : _ctrl$ref.delete(ctrl);
|
|
ref == null ? void 0 : ref.delete(ctrl);
|
|
}
|
|
function replaceRef(ctrl, ref) {
|
|
if (ref && ctrl.ref !== ref) {
|
|
var _ctrl$ref2;
|
|
|
|
(_ctrl$ref2 = ctrl.ref) == null ? void 0 : _ctrl$ref2.delete(ctrl);
|
|
ref.add(ctrl);
|
|
ctrl.ref = ref;
|
|
}
|
|
}
|
|
|
|
function useChain(refs, timeSteps, timeFrame = 1000) {
|
|
shared.useLayoutEffect(() => {
|
|
if (timeSteps) {
|
|
let prevDelay = 0;
|
|
shared.each(refs, (ref, i) => {
|
|
const controllers = ref.current;
|
|
|
|
if (controllers.length) {
|
|
let delay = timeFrame * timeSteps[i];
|
|
if (isNaN(delay)) delay = prevDelay;else prevDelay = delay;
|
|
shared.each(controllers, ctrl => {
|
|
shared.each(ctrl.queue, props => {
|
|
const memoizedDelayProp = props.delay;
|
|
|
|
props.delay = key => delay + callProp(memoizedDelayProp || 0, key);
|
|
});
|
|
});
|
|
ref.start();
|
|
}
|
|
});
|
|
} else {
|
|
let p = Promise.resolve();
|
|
shared.each(refs, ref => {
|
|
const controllers = ref.current;
|
|
|
|
if (controllers.length) {
|
|
const queues = controllers.map(ctrl => {
|
|
const q = ctrl.queue;
|
|
ctrl.queue = [];
|
|
return q;
|
|
});
|
|
p = p.then(() => {
|
|
shared.each(controllers, (ctrl, i) => shared.each(queues[i] || [], update => ctrl.queue.push(update)));
|
|
return Promise.all(ref.start());
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
const config = {
|
|
default: {
|
|
tension: 170,
|
|
friction: 26
|
|
},
|
|
gentle: {
|
|
tension: 120,
|
|
friction: 14
|
|
},
|
|
wobbly: {
|
|
tension: 180,
|
|
friction: 12
|
|
},
|
|
stiff: {
|
|
tension: 210,
|
|
friction: 20
|
|
},
|
|
slow: {
|
|
tension: 280,
|
|
friction: 60
|
|
},
|
|
molasses: {
|
|
tension: 280,
|
|
friction: 120
|
|
}
|
|
};
|
|
const c1 = 1.70158;
|
|
const c2 = c1 * 1.525;
|
|
const c3 = c1 + 1;
|
|
const c4 = 2 * Math.PI / 3;
|
|
const c5 = 2 * Math.PI / 4.5;
|
|
|
|
const bounceOut = x => {
|
|
const n1 = 7.5625;
|
|
const d1 = 2.75;
|
|
|
|
if (x < 1 / d1) {
|
|
return n1 * x * x;
|
|
} else if (x < 2 / d1) {
|
|
return n1 * (x -= 1.5 / d1) * x + 0.75;
|
|
} else if (x < 2.5 / d1) {
|
|
return n1 * (x -= 2.25 / d1) * x + 0.9375;
|
|
} else {
|
|
return n1 * (x -= 2.625 / d1) * x + 0.984375;
|
|
}
|
|
};
|
|
|
|
const easings = {
|
|
linear: x => x,
|
|
easeInQuad: x => x * x,
|
|
easeOutQuad: x => 1 - (1 - x) * (1 - x),
|
|
easeInOutQuad: x => x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2,
|
|
easeInCubic: x => x * x * x,
|
|
easeOutCubic: x => 1 - Math.pow(1 - x, 3),
|
|
easeInOutCubic: x => x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2,
|
|
easeInQuart: x => x * x * x * x,
|
|
easeOutQuart: x => 1 - Math.pow(1 - x, 4),
|
|
easeInOutQuart: x => x < 0.5 ? 8 * x * x * x * x : 1 - Math.pow(-2 * x + 2, 4) / 2,
|
|
easeInQuint: x => x * x * x * x * x,
|
|
easeOutQuint: x => 1 - Math.pow(1 - x, 5),
|
|
easeInOutQuint: x => x < 0.5 ? 16 * x * x * x * x * x : 1 - Math.pow(-2 * x + 2, 5) / 2,
|
|
easeInSine: x => 1 - Math.cos(x * Math.PI / 2),
|
|
easeOutSine: x => Math.sin(x * Math.PI / 2),
|
|
easeInOutSine: x => -(Math.cos(Math.PI * x) - 1) / 2,
|
|
easeInExpo: x => x === 0 ? 0 : Math.pow(2, 10 * x - 10),
|
|
easeOutExpo: x => x === 1 ? 1 : 1 - Math.pow(2, -10 * x),
|
|
easeInOutExpo: x => x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? Math.pow(2, 20 * x - 10) / 2 : (2 - Math.pow(2, -20 * x + 10)) / 2,
|
|
easeInCirc: x => 1 - Math.sqrt(1 - Math.pow(x, 2)),
|
|
easeOutCirc: x => Math.sqrt(1 - Math.pow(x - 1, 2)),
|
|
easeInOutCirc: x => x < 0.5 ? (1 - Math.sqrt(1 - Math.pow(2 * x, 2))) / 2 : (Math.sqrt(1 - Math.pow(-2 * x + 2, 2)) + 1) / 2,
|
|
easeInBack: x => c3 * x * x * x - c1 * x * x,
|
|
easeOutBack: x => 1 + c3 * Math.pow(x - 1, 3) + c1 * Math.pow(x - 1, 2),
|
|
easeInOutBack: x => x < 0.5 ? Math.pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2) / 2 : (Math.pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2,
|
|
easeInElastic: x => x === 0 ? 0 : x === 1 ? 1 : -Math.pow(2, 10 * x - 10) * Math.sin((x * 10 - 10.75) * c4),
|
|
easeOutElastic: x => x === 0 ? 0 : x === 1 ? 1 : Math.pow(2, -10 * x) * Math.sin((x * 10 - 0.75) * c4) + 1,
|
|
easeInOutElastic: x => x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? -(Math.pow(2, 20 * x - 10) * Math.sin((20 * x - 11.125) * c5)) / 2 : Math.pow(2, -20 * x + 10) * Math.sin((20 * x - 11.125) * c5) / 2 + 1,
|
|
easeInBounce: x => 1 - bounceOut(1 - x),
|
|
easeOutBounce: bounceOut,
|
|
easeInOutBounce: x => x < 0.5 ? (1 - bounceOut(1 - 2 * x)) / 2 : (1 + bounceOut(2 * x - 1)) / 2
|
|
};
|
|
|
|
const defaults = _extends({}, config.default, {
|
|
mass: 1,
|
|
damping: 1,
|
|
easing: easings.linear,
|
|
clamp: false
|
|
});
|
|
|
|
class AnimationConfig {
|
|
constructor() {
|
|
this.tension = void 0;
|
|
this.friction = void 0;
|
|
this.frequency = void 0;
|
|
this.damping = void 0;
|
|
this.mass = void 0;
|
|
this.velocity = 0;
|
|
this.restVelocity = void 0;
|
|
this.precision = void 0;
|
|
this.progress = void 0;
|
|
this.duration = void 0;
|
|
this.easing = void 0;
|
|
this.clamp = void 0;
|
|
this.bounce = void 0;
|
|
this.decay = void 0;
|
|
this.round = void 0;
|
|
Object.assign(this, defaults);
|
|
}
|
|
|
|
}
|
|
function mergeConfig(config, newConfig, defaultConfig) {
|
|
if (defaultConfig) {
|
|
defaultConfig = _extends({}, defaultConfig);
|
|
sanitizeConfig(defaultConfig, newConfig);
|
|
newConfig = _extends({}, defaultConfig, newConfig);
|
|
}
|
|
|
|
sanitizeConfig(config, newConfig);
|
|
Object.assign(config, newConfig);
|
|
|
|
for (const key in defaults) {
|
|
if (config[key] == null) {
|
|
config[key] = defaults[key];
|
|
}
|
|
}
|
|
|
|
let {
|
|
mass,
|
|
frequency,
|
|
damping
|
|
} = config;
|
|
|
|
if (!shared.is.und(frequency)) {
|
|
if (frequency < 0.01) frequency = 0.01;
|
|
if (damping < 0) damping = 0;
|
|
config.tension = Math.pow(2 * Math.PI / frequency, 2) * mass;
|
|
config.friction = 4 * Math.PI * damping * mass / frequency;
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
function sanitizeConfig(config, props) {
|
|
if (!shared.is.und(props.decay)) {
|
|
config.duration = undefined;
|
|
} else {
|
|
const isTensionConfig = !shared.is.und(props.tension) || !shared.is.und(props.friction);
|
|
|
|
if (isTensionConfig || !shared.is.und(props.frequency) || !shared.is.und(props.damping) || !shared.is.und(props.mass)) {
|
|
config.duration = undefined;
|
|
config.decay = undefined;
|
|
}
|
|
|
|
if (isTensionConfig) {
|
|
config.frequency = undefined;
|
|
}
|
|
}
|
|
}
|
|
|
|
const emptyArray = [];
|
|
class Animation {
|
|
constructor() {
|
|
this.changed = false;
|
|
this.values = emptyArray;
|
|
this.toValues = null;
|
|
this.fromValues = emptyArray;
|
|
this.to = void 0;
|
|
this.from = void 0;
|
|
this.config = new AnimationConfig();
|
|
this.immediate = false;
|
|
}
|
|
|
|
}
|
|
|
|
function scheduleProps(callId, {
|
|
key,
|
|
props,
|
|
defaultProps,
|
|
state,
|
|
actions
|
|
}) {
|
|
return new Promise((resolve, reject) => {
|
|
var _props$cancel;
|
|
|
|
let delay;
|
|
let timeout;
|
|
let cancel = matchProp((_props$cancel = props.cancel) != null ? _props$cancel : defaultProps == null ? void 0 : defaultProps.cancel, key);
|
|
|
|
if (cancel) {
|
|
onStart();
|
|
} else {
|
|
if (!shared.is.und(props.pause)) {
|
|
state.paused = matchProp(props.pause, key);
|
|
}
|
|
|
|
let pause = defaultProps == null ? void 0 : defaultProps.pause;
|
|
|
|
if (pause !== true) {
|
|
pause = state.paused || matchProp(pause, key);
|
|
}
|
|
|
|
delay = callProp(props.delay || 0, key);
|
|
|
|
if (pause) {
|
|
state.resumeQueue.add(onResume);
|
|
actions.pause();
|
|
} else {
|
|
actions.resume();
|
|
onResume();
|
|
}
|
|
}
|
|
|
|
function onPause() {
|
|
state.resumeQueue.add(onResume);
|
|
state.timeouts.delete(timeout);
|
|
timeout.cancel();
|
|
delay = timeout.time - shared.raf.now();
|
|
}
|
|
|
|
function onResume() {
|
|
if (delay > 0 && !shared.Globals.skipAnimation) {
|
|
state.delayed = true;
|
|
timeout = shared.raf.setTimeout(onStart, delay);
|
|
state.pauseQueue.add(onPause);
|
|
state.timeouts.add(timeout);
|
|
} else {
|
|
onStart();
|
|
}
|
|
}
|
|
|
|
function onStart() {
|
|
if (state.delayed) {
|
|
state.delayed = false;
|
|
}
|
|
|
|
state.pauseQueue.delete(onPause);
|
|
state.timeouts.delete(timeout);
|
|
|
|
if (callId <= (state.cancelId || 0)) {
|
|
cancel = true;
|
|
}
|
|
|
|
try {
|
|
actions.start(_extends({}, props, {
|
|
callId,
|
|
cancel
|
|
}), resolve);
|
|
} catch (err) {
|
|
reject(err);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
const getCombinedResult = (target, results) => results.length == 1 ? results[0] : results.some(result => result.cancelled) ? getCancelledResult(target.get()) : results.every(result => result.noop) ? getNoopResult(target.get()) : getFinishedResult(target.get(), results.every(result => result.finished));
|
|
const getNoopResult = value => ({
|
|
value,
|
|
noop: true,
|
|
finished: true,
|
|
cancelled: false
|
|
});
|
|
const getFinishedResult = (value, finished, cancelled = false) => ({
|
|
value,
|
|
finished,
|
|
cancelled
|
|
});
|
|
const getCancelledResult = value => ({
|
|
value,
|
|
cancelled: true,
|
|
finished: false
|
|
});
|
|
|
|
function runAsync(to, props, state, target) {
|
|
const {
|
|
callId,
|
|
parentId,
|
|
onRest
|
|
} = props;
|
|
const {
|
|
asyncTo: prevTo,
|
|
promise: prevPromise
|
|
} = state;
|
|
|
|
if (!parentId && to === prevTo && !props.reset) {
|
|
return prevPromise;
|
|
}
|
|
|
|
return state.promise = (async () => {
|
|
state.asyncId = callId;
|
|
state.asyncTo = to;
|
|
const defaultProps = getDefaultProps(props, (value, key) => key === 'onRest' ? undefined : value);
|
|
let preventBail;
|
|
let bail;
|
|
const bailPromise = new Promise((resolve, reject) => (preventBail = resolve, bail = reject));
|
|
|
|
const bailIfEnded = bailSignal => {
|
|
const bailResult = callId <= (state.cancelId || 0) && getCancelledResult(target) || callId !== state.asyncId && getFinishedResult(target, false);
|
|
|
|
if (bailResult) {
|
|
bailSignal.result = bailResult;
|
|
bail(bailSignal);
|
|
throw bailSignal;
|
|
}
|
|
};
|
|
|
|
const animate = (arg1, arg2) => {
|
|
const bailSignal = new BailSignal();
|
|
const skipAnimationSignal = new SkipAniamtionSignal();
|
|
return (async () => {
|
|
if (shared.Globals.skipAnimation) {
|
|
stopAsync(state);
|
|
skipAnimationSignal.result = getFinishedResult(target, false);
|
|
bail(skipAnimationSignal);
|
|
throw skipAnimationSignal;
|
|
}
|
|
|
|
bailIfEnded(bailSignal);
|
|
const props = shared.is.obj(arg1) ? _extends({}, arg1) : _extends({}, arg2, {
|
|
to: arg1
|
|
});
|
|
props.parentId = callId;
|
|
shared.eachProp(defaultProps, (value, key) => {
|
|
if (shared.is.und(props[key])) {
|
|
props[key] = value;
|
|
}
|
|
});
|
|
const result = await target.start(props);
|
|
bailIfEnded(bailSignal);
|
|
|
|
if (state.paused) {
|
|
await new Promise(resume => {
|
|
state.resumeQueue.add(resume);
|
|
});
|
|
}
|
|
|
|
return result;
|
|
})();
|
|
};
|
|
|
|
let result;
|
|
|
|
if (shared.Globals.skipAnimation) {
|
|
stopAsync(state);
|
|
return getFinishedResult(target, false);
|
|
}
|
|
|
|
try {
|
|
let animating;
|
|
|
|
if (shared.is.arr(to)) {
|
|
animating = (async queue => {
|
|
for (const props of queue) {
|
|
await animate(props);
|
|
}
|
|
})(to);
|
|
} else {
|
|
animating = Promise.resolve(to(animate, target.stop.bind(target)));
|
|
}
|
|
|
|
await Promise.all([animating.then(preventBail), bailPromise]);
|
|
result = getFinishedResult(target.get(), true, false);
|
|
} catch (err) {
|
|
if (err instanceof BailSignal) {
|
|
result = err.result;
|
|
} else if (err instanceof SkipAniamtionSignal) {
|
|
result = err.result;
|
|
} else {
|
|
throw err;
|
|
}
|
|
} finally {
|
|
if (callId == state.asyncId) {
|
|
state.asyncId = parentId;
|
|
state.asyncTo = parentId ? prevTo : undefined;
|
|
state.promise = parentId ? prevPromise : undefined;
|
|
}
|
|
}
|
|
|
|
if (shared.is.fun(onRest)) {
|
|
shared.raf.batchedUpdates(() => {
|
|
onRest(result, target, target.item);
|
|
});
|
|
}
|
|
|
|
return result;
|
|
})();
|
|
}
|
|
function stopAsync(state, cancelId) {
|
|
shared.flush(state.timeouts, t => t.cancel());
|
|
state.pauseQueue.clear();
|
|
state.resumeQueue.clear();
|
|
state.asyncId = state.asyncTo = state.promise = undefined;
|
|
if (cancelId) state.cancelId = cancelId;
|
|
}
|
|
class BailSignal extends Error {
|
|
constructor() {
|
|
super('An async animation has been interrupted. You see this error because you ' + 'forgot to use `await` or `.catch(...)` on its returned promise.');
|
|
this.result = void 0;
|
|
}
|
|
|
|
}
|
|
class SkipAniamtionSignal extends Error {
|
|
constructor() {
|
|
super('SkipAnimationSignal');
|
|
this.result = void 0;
|
|
}
|
|
|
|
}
|
|
|
|
const isFrameValue = value => value instanceof FrameValue;
|
|
let nextId$1 = 1;
|
|
class FrameValue extends shared.FluidValue {
|
|
constructor(...args) {
|
|
super(...args);
|
|
this.id = nextId$1++;
|
|
this.key = void 0;
|
|
this._priority = 0;
|
|
}
|
|
|
|
get priority() {
|
|
return this._priority;
|
|
}
|
|
|
|
set priority(priority) {
|
|
if (this._priority != priority) {
|
|
this._priority = priority;
|
|
|
|
this._onPriorityChange(priority);
|
|
}
|
|
}
|
|
|
|
get() {
|
|
const node = animated$1.getAnimated(this);
|
|
return node && node.getValue();
|
|
}
|
|
|
|
to(...args) {
|
|
return shared.Globals.to(this, args);
|
|
}
|
|
|
|
interpolate(...args) {
|
|
shared.deprecateInterpolate();
|
|
return shared.Globals.to(this, args);
|
|
}
|
|
|
|
toJSON() {
|
|
return this.get();
|
|
}
|
|
|
|
observerAdded(count) {
|
|
if (count == 1) this._attach();
|
|
}
|
|
|
|
observerRemoved(count) {
|
|
if (count == 0) this._detach();
|
|
}
|
|
|
|
_attach() {}
|
|
|
|
_detach() {}
|
|
|
|
_onChange(value, idle = false) {
|
|
shared.callFluidObservers(this, {
|
|
type: 'change',
|
|
parent: this,
|
|
value,
|
|
idle
|
|
});
|
|
}
|
|
|
|
_onPriorityChange(priority) {
|
|
if (!this.idle) {
|
|
shared.frameLoop.sort(this);
|
|
}
|
|
|
|
shared.callFluidObservers(this, {
|
|
type: 'priority',
|
|
parent: this,
|
|
priority
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
const $P = Symbol.for('SpringPhase');
|
|
const HAS_ANIMATED = 1;
|
|
const IS_ANIMATING = 2;
|
|
const IS_PAUSED = 4;
|
|
const hasAnimated = target => (target[$P] & HAS_ANIMATED) > 0;
|
|
const isAnimating = target => (target[$P] & IS_ANIMATING) > 0;
|
|
const isPaused = target => (target[$P] & IS_PAUSED) > 0;
|
|
const setActiveBit = (target, active) => active ? target[$P] |= IS_ANIMATING | HAS_ANIMATED : target[$P] &= ~IS_ANIMATING;
|
|
const setPausedBit = (target, paused) => paused ? target[$P] |= IS_PAUSED : target[$P] &= ~IS_PAUSED;
|
|
|
|
class SpringValue extends FrameValue {
|
|
constructor(arg1, arg2) {
|
|
super();
|
|
this.key = void 0;
|
|
this.animation = new Animation();
|
|
this.queue = void 0;
|
|
this.defaultProps = {};
|
|
this._state = {
|
|
paused: false,
|
|
delayed: false,
|
|
pauseQueue: new Set(),
|
|
resumeQueue: new Set(),
|
|
timeouts: new Set()
|
|
};
|
|
this._pendingCalls = new Set();
|
|
this._lastCallId = 0;
|
|
this._lastToId = 0;
|
|
this._memoizedDuration = 0;
|
|
|
|
if (!shared.is.und(arg1) || !shared.is.und(arg2)) {
|
|
const props = shared.is.obj(arg1) ? _extends({}, arg1) : _extends({}, arg2, {
|
|
from: arg1
|
|
});
|
|
|
|
if (shared.is.und(props.default)) {
|
|
props.default = true;
|
|
}
|
|
|
|
this.start(props);
|
|
}
|
|
}
|
|
|
|
get idle() {
|
|
return !(isAnimating(this) || this._state.asyncTo) || isPaused(this);
|
|
}
|
|
|
|
get goal() {
|
|
return shared.getFluidValue(this.animation.to);
|
|
}
|
|
|
|
get velocity() {
|
|
const node = animated$1.getAnimated(this);
|
|
return node instanceof animated$1.AnimatedValue ? node.lastVelocity || 0 : node.getPayload().map(node => node.lastVelocity || 0);
|
|
}
|
|
|
|
get hasAnimated() {
|
|
return hasAnimated(this);
|
|
}
|
|
|
|
get isAnimating() {
|
|
return isAnimating(this);
|
|
}
|
|
|
|
get isPaused() {
|
|
return isPaused(this);
|
|
}
|
|
|
|
get isDelayed() {
|
|
return this._state.delayed;
|
|
}
|
|
|
|
advance(dt) {
|
|
let idle = true;
|
|
let changed = false;
|
|
const anim = this.animation;
|
|
let {
|
|
config,
|
|
toValues
|
|
} = anim;
|
|
const payload = animated$1.getPayload(anim.to);
|
|
|
|
if (!payload && shared.hasFluidValue(anim.to)) {
|
|
toValues = shared.toArray(shared.getFluidValue(anim.to));
|
|
}
|
|
|
|
anim.values.forEach((node, i) => {
|
|
if (node.done) return;
|
|
const to = node.constructor == animated$1.AnimatedString ? 1 : payload ? payload[i].lastPosition : toValues[i];
|
|
let finished = anim.immediate;
|
|
let position = to;
|
|
|
|
if (!finished) {
|
|
position = node.lastPosition;
|
|
|
|
if (config.tension <= 0) {
|
|
node.done = true;
|
|
return;
|
|
}
|
|
|
|
let elapsed = node.elapsedTime += dt;
|
|
const from = anim.fromValues[i];
|
|
const v0 = node.v0 != null ? node.v0 : node.v0 = shared.is.arr(config.velocity) ? config.velocity[i] : config.velocity;
|
|
let velocity;
|
|
|
|
if (!shared.is.und(config.duration)) {
|
|
let p = 1;
|
|
|
|
if (config.duration > 0) {
|
|
if (this._memoizedDuration !== config.duration) {
|
|
this._memoizedDuration = config.duration;
|
|
|
|
if (node.durationProgress > 0) {
|
|
node.elapsedTime = config.duration * node.durationProgress;
|
|
elapsed = node.elapsedTime += dt;
|
|
}
|
|
}
|
|
|
|
p = (config.progress || 0) + elapsed / this._memoizedDuration;
|
|
p = p > 1 ? 1 : p < 0 ? 0 : p;
|
|
node.durationProgress = p;
|
|
}
|
|
|
|
position = from + config.easing(p) * (to - from);
|
|
velocity = (position - node.lastPosition) / dt;
|
|
finished = p == 1;
|
|
} else if (config.decay) {
|
|
const decay = config.decay === true ? 0.998 : config.decay;
|
|
const e = Math.exp(-(1 - decay) * elapsed);
|
|
position = from + v0 / (1 - decay) * (1 - e);
|
|
finished = Math.abs(node.lastPosition - position) < 0.1;
|
|
velocity = v0 * e;
|
|
} else {
|
|
velocity = node.lastVelocity == null ? v0 : node.lastVelocity;
|
|
const precision = config.precision || (from == to ? 0.005 : Math.min(1, Math.abs(to - from) * 0.001));
|
|
const restVelocity = config.restVelocity || precision / 10;
|
|
const bounceFactor = config.clamp ? 0 : config.bounce;
|
|
const canBounce = !shared.is.und(bounceFactor);
|
|
const isGrowing = from == to ? node.v0 > 0 : from < to;
|
|
let isMoving;
|
|
let isBouncing = false;
|
|
const step = 1;
|
|
const numSteps = Math.ceil(dt / step);
|
|
|
|
for (let n = 0; n < numSteps; ++n) {
|
|
isMoving = Math.abs(velocity) > restVelocity;
|
|
|
|
if (!isMoving) {
|
|
finished = Math.abs(to - position) <= precision;
|
|
|
|
if (finished) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (canBounce) {
|
|
isBouncing = position == to || position > to == isGrowing;
|
|
|
|
if (isBouncing) {
|
|
velocity = -velocity * bounceFactor;
|
|
position = to;
|
|
}
|
|
}
|
|
|
|
const springForce = -config.tension * 0.000001 * (position - to);
|
|
const dampingForce = -config.friction * 0.001 * velocity;
|
|
const acceleration = (springForce + dampingForce) / config.mass;
|
|
velocity = velocity + acceleration * step;
|
|
position = position + velocity * step;
|
|
}
|
|
}
|
|
|
|
node.lastVelocity = velocity;
|
|
|
|
if (Number.isNaN(position)) {
|
|
console.warn(`Got NaN while animating:`, this);
|
|
finished = true;
|
|
}
|
|
}
|
|
|
|
if (payload && !payload[i].done) {
|
|
finished = false;
|
|
}
|
|
|
|
if (finished) {
|
|
node.done = true;
|
|
} else {
|
|
idle = false;
|
|
}
|
|
|
|
if (node.setValue(position, config.round)) {
|
|
changed = true;
|
|
}
|
|
});
|
|
const node = animated$1.getAnimated(this);
|
|
const currVal = node.getValue();
|
|
|
|
if (idle) {
|
|
const finalVal = shared.getFluidValue(anim.to);
|
|
|
|
if ((currVal !== finalVal || changed) && !config.decay) {
|
|
node.setValue(finalVal);
|
|
|
|
this._onChange(finalVal);
|
|
} else if (changed && config.decay) {
|
|
this._onChange(currVal);
|
|
}
|
|
|
|
this._stop();
|
|
} else if (changed) {
|
|
this._onChange(currVal);
|
|
}
|
|
}
|
|
|
|
set(value) {
|
|
shared.raf.batchedUpdates(() => {
|
|
this._stop();
|
|
|
|
this._focus(value);
|
|
|
|
this._set(value);
|
|
});
|
|
return this;
|
|
}
|
|
|
|
pause() {
|
|
this._update({
|
|
pause: true
|
|
});
|
|
}
|
|
|
|
resume() {
|
|
this._update({
|
|
pause: false
|
|
});
|
|
}
|
|
|
|
finish() {
|
|
if (isAnimating(this)) {
|
|
const {
|
|
to,
|
|
config
|
|
} = this.animation;
|
|
shared.raf.batchedUpdates(() => {
|
|
this._onStart();
|
|
|
|
if (!config.decay) {
|
|
this._set(to, false);
|
|
}
|
|
|
|
this._stop();
|
|
});
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
update(props) {
|
|
const queue = this.queue || (this.queue = []);
|
|
queue.push(props);
|
|
return this;
|
|
}
|
|
|
|
start(to, arg2) {
|
|
let queue;
|
|
|
|
if (!shared.is.und(to)) {
|
|
queue = [shared.is.obj(to) ? to : _extends({}, arg2, {
|
|
to
|
|
})];
|
|
} else {
|
|
queue = this.queue || [];
|
|
this.queue = [];
|
|
}
|
|
|
|
return Promise.all(queue.map(props => {
|
|
const up = this._update(props);
|
|
|
|
return up;
|
|
})).then(results => getCombinedResult(this, results));
|
|
}
|
|
|
|
stop(cancel) {
|
|
const {
|
|
to
|
|
} = this.animation;
|
|
|
|
this._focus(this.get());
|
|
|
|
stopAsync(this._state, cancel && this._lastCallId);
|
|
shared.raf.batchedUpdates(() => this._stop(to, cancel));
|
|
return this;
|
|
}
|
|
|
|
reset() {
|
|
this._update({
|
|
reset: true
|
|
});
|
|
}
|
|
|
|
eventObserved(event) {
|
|
if (event.type == 'change') {
|
|
this._start();
|
|
} else if (event.type == 'priority') {
|
|
this.priority = event.priority + 1;
|
|
}
|
|
}
|
|
|
|
_prepareNode(props) {
|
|
const key = this.key || '';
|
|
let {
|
|
to,
|
|
from
|
|
} = props;
|
|
to = shared.is.obj(to) ? to[key] : to;
|
|
|
|
if (to == null || isAsyncTo(to)) {
|
|
to = undefined;
|
|
}
|
|
|
|
from = shared.is.obj(from) ? from[key] : from;
|
|
|
|
if (from == null) {
|
|
from = undefined;
|
|
}
|
|
|
|
const range = {
|
|
to,
|
|
from
|
|
};
|
|
|
|
if (!hasAnimated(this)) {
|
|
if (props.reverse) [to, from] = [from, to];
|
|
from = shared.getFluidValue(from);
|
|
|
|
if (!shared.is.und(from)) {
|
|
this._set(from);
|
|
} else if (!animated$1.getAnimated(this)) {
|
|
this._set(to);
|
|
}
|
|
}
|
|
|
|
return range;
|
|
}
|
|
|
|
_update(_ref, isLoop) {
|
|
let props = _extends({}, _ref);
|
|
|
|
const {
|
|
key,
|
|
defaultProps
|
|
} = this;
|
|
if (props.default) Object.assign(defaultProps, getDefaultProps(props, (value, prop) => /^on/.test(prop) ? resolveProp(value, key) : value));
|
|
mergeActiveFn(this, props, 'onProps');
|
|
sendEvent(this, 'onProps', props, this);
|
|
|
|
const range = this._prepareNode(props);
|
|
|
|
if (Object.isFrozen(this)) {
|
|
throw Error('Cannot animate a `SpringValue` object that is frozen. ' + 'Did you forget to pass your component to `animated(...)` before animating its props?');
|
|
}
|
|
|
|
const state = this._state;
|
|
return scheduleProps(++this._lastCallId, {
|
|
key,
|
|
props,
|
|
defaultProps,
|
|
state,
|
|
actions: {
|
|
pause: () => {
|
|
if (!isPaused(this)) {
|
|
setPausedBit(this, true);
|
|
shared.flushCalls(state.pauseQueue);
|
|
sendEvent(this, 'onPause', getFinishedResult(this, checkFinished(this, this.animation.to)), this);
|
|
}
|
|
},
|
|
resume: () => {
|
|
if (isPaused(this)) {
|
|
setPausedBit(this, false);
|
|
|
|
if (isAnimating(this)) {
|
|
this._resume();
|
|
}
|
|
|
|
shared.flushCalls(state.resumeQueue);
|
|
sendEvent(this, 'onResume', getFinishedResult(this, checkFinished(this, this.animation.to)), this);
|
|
}
|
|
},
|
|
start: this._merge.bind(this, range)
|
|
}
|
|
}).then(result => {
|
|
if (props.loop && result.finished && !(isLoop && result.noop)) {
|
|
const nextProps = createLoopUpdate(props);
|
|
|
|
if (nextProps) {
|
|
return this._update(nextProps, true);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
});
|
|
}
|
|
|
|
_merge(range, props, resolve) {
|
|
if (props.cancel) {
|
|
this.stop(true);
|
|
return resolve(getCancelledResult(this));
|
|
}
|
|
|
|
const hasToProp = !shared.is.und(range.to);
|
|
const hasFromProp = !shared.is.und(range.from);
|
|
|
|
if (hasToProp || hasFromProp) {
|
|
if (props.callId > this._lastToId) {
|
|
this._lastToId = props.callId;
|
|
} else {
|
|
return resolve(getCancelledResult(this));
|
|
}
|
|
}
|
|
|
|
const {
|
|
key,
|
|
defaultProps,
|
|
animation: anim
|
|
} = this;
|
|
const {
|
|
to: prevTo,
|
|
from: prevFrom
|
|
} = anim;
|
|
let {
|
|
to = prevTo,
|
|
from = prevFrom
|
|
} = range;
|
|
|
|
if (hasFromProp && !hasToProp && (!props.default || shared.is.und(to))) {
|
|
to = from;
|
|
}
|
|
|
|
if (props.reverse) [to, from] = [from, to];
|
|
const hasFromChanged = !shared.isEqual(from, prevFrom);
|
|
|
|
if (hasFromChanged) {
|
|
anim.from = from;
|
|
}
|
|
|
|
from = shared.getFluidValue(from);
|
|
const hasToChanged = !shared.isEqual(to, prevTo);
|
|
|
|
if (hasToChanged) {
|
|
this._focus(to);
|
|
}
|
|
|
|
const hasAsyncTo = isAsyncTo(props.to);
|
|
const {
|
|
config
|
|
} = anim;
|
|
const {
|
|
decay,
|
|
velocity
|
|
} = config;
|
|
|
|
if (hasToProp || hasFromProp) {
|
|
config.velocity = 0;
|
|
}
|
|
|
|
if (props.config && !hasAsyncTo) {
|
|
mergeConfig(config, callProp(props.config, key), props.config !== defaultProps.config ? callProp(defaultProps.config, key) : void 0);
|
|
}
|
|
|
|
let node = animated$1.getAnimated(this);
|
|
|
|
if (!node || shared.is.und(to)) {
|
|
return resolve(getFinishedResult(this, true));
|
|
}
|
|
|
|
const reset = shared.is.und(props.reset) ? hasFromProp && !props.default : !shared.is.und(from) && matchProp(props.reset, key);
|
|
const value = reset ? from : this.get();
|
|
const goal = computeGoal(to);
|
|
const isAnimatable = shared.is.num(goal) || shared.is.arr(goal) || shared.isAnimatedString(goal);
|
|
const immediate = !hasAsyncTo && (!isAnimatable || matchProp(defaultProps.immediate || props.immediate, key));
|
|
|
|
if (hasToChanged) {
|
|
const nodeType = animated$1.getAnimatedType(to);
|
|
|
|
if (nodeType !== node.constructor) {
|
|
if (immediate) {
|
|
node = this._set(goal);
|
|
} else throw Error(`Cannot animate between ${node.constructor.name} and ${nodeType.name}, as the "to" prop suggests`);
|
|
}
|
|
}
|
|
|
|
const goalType = node.constructor;
|
|
let started = shared.hasFluidValue(to);
|
|
let finished = false;
|
|
|
|
if (!started) {
|
|
const hasValueChanged = reset || !hasAnimated(this) && hasFromChanged;
|
|
|
|
if (hasToChanged || hasValueChanged) {
|
|
finished = shared.isEqual(computeGoal(value), goal);
|
|
started = !finished;
|
|
}
|
|
|
|
if (!shared.isEqual(anim.immediate, immediate) && !immediate || !shared.isEqual(config.decay, decay) || !shared.isEqual(config.velocity, velocity)) {
|
|
started = true;
|
|
}
|
|
}
|
|
|
|
if (finished && isAnimating(this)) {
|
|
if (anim.changed && !reset) {
|
|
started = true;
|
|
} else if (!started) {
|
|
this._stop(prevTo);
|
|
}
|
|
}
|
|
|
|
if (!hasAsyncTo) {
|
|
if (started || shared.hasFluidValue(prevTo)) {
|
|
anim.values = node.getPayload();
|
|
anim.toValues = shared.hasFluidValue(to) ? null : goalType == animated$1.AnimatedString ? [1] : shared.toArray(goal);
|
|
}
|
|
|
|
if (anim.immediate != immediate) {
|
|
anim.immediate = immediate;
|
|
|
|
if (!immediate && !reset) {
|
|
this._set(prevTo);
|
|
}
|
|
}
|
|
|
|
if (started) {
|
|
const {
|
|
onRest
|
|
} = anim;
|
|
shared.each(ACTIVE_EVENTS, type => mergeActiveFn(this, props, type));
|
|
const result = getFinishedResult(this, checkFinished(this, prevTo));
|
|
shared.flushCalls(this._pendingCalls, result);
|
|
|
|
this._pendingCalls.add(resolve);
|
|
|
|
if (anim.changed) shared.raf.batchedUpdates(() => {
|
|
anim.changed = !reset;
|
|
onRest == null ? void 0 : onRest(result, this);
|
|
|
|
if (reset) {
|
|
callProp(defaultProps.onRest, result);
|
|
} else {
|
|
anim.onStart == null ? void 0 : anim.onStart(result, this);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
if (reset) {
|
|
this._set(value);
|
|
}
|
|
|
|
if (hasAsyncTo) {
|
|
resolve(runAsync(props.to, props, this._state, this));
|
|
} else if (started) {
|
|
this._start();
|
|
} else if (isAnimating(this) && !hasToChanged) {
|
|
this._pendingCalls.add(resolve);
|
|
} else {
|
|
resolve(getNoopResult(value));
|
|
}
|
|
}
|
|
|
|
_focus(value) {
|
|
const anim = this.animation;
|
|
|
|
if (value !== anim.to) {
|
|
if (shared.getFluidObservers(this)) {
|
|
this._detach();
|
|
}
|
|
|
|
anim.to = value;
|
|
|
|
if (shared.getFluidObservers(this)) {
|
|
this._attach();
|
|
}
|
|
}
|
|
}
|
|
|
|
_attach() {
|
|
let priority = 0;
|
|
const {
|
|
to
|
|
} = this.animation;
|
|
|
|
if (shared.hasFluidValue(to)) {
|
|
shared.addFluidObserver(to, this);
|
|
|
|
if (isFrameValue(to)) {
|
|
priority = to.priority + 1;
|
|
}
|
|
}
|
|
|
|
this.priority = priority;
|
|
}
|
|
|
|
_detach() {
|
|
const {
|
|
to
|
|
} = this.animation;
|
|
|
|
if (shared.hasFluidValue(to)) {
|
|
shared.removeFluidObserver(to, this);
|
|
}
|
|
}
|
|
|
|
_set(arg, idle = true) {
|
|
const value = shared.getFluidValue(arg);
|
|
|
|
if (!shared.is.und(value)) {
|
|
const oldNode = animated$1.getAnimated(this);
|
|
|
|
if (!oldNode || !shared.isEqual(value, oldNode.getValue())) {
|
|
const nodeType = animated$1.getAnimatedType(value);
|
|
|
|
if (!oldNode || oldNode.constructor != nodeType) {
|
|
animated$1.setAnimated(this, nodeType.create(value));
|
|
} else {
|
|
oldNode.setValue(value);
|
|
}
|
|
|
|
if (oldNode) {
|
|
shared.raf.batchedUpdates(() => {
|
|
this._onChange(value, idle);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
return animated$1.getAnimated(this);
|
|
}
|
|
|
|
_onStart() {
|
|
const anim = this.animation;
|
|
|
|
if (!anim.changed) {
|
|
anim.changed = true;
|
|
sendEvent(this, 'onStart', getFinishedResult(this, checkFinished(this, anim.to)), this);
|
|
}
|
|
}
|
|
|
|
_onChange(value, idle) {
|
|
if (!idle) {
|
|
this._onStart();
|
|
|
|
callProp(this.animation.onChange, value, this);
|
|
}
|
|
|
|
callProp(this.defaultProps.onChange, value, this);
|
|
|
|
super._onChange(value, idle);
|
|
}
|
|
|
|
_start() {
|
|
const anim = this.animation;
|
|
animated$1.getAnimated(this).reset(shared.getFluidValue(anim.to));
|
|
|
|
if (!anim.immediate) {
|
|
anim.fromValues = anim.values.map(node => node.lastPosition);
|
|
}
|
|
|
|
if (!isAnimating(this)) {
|
|
setActiveBit(this, true);
|
|
|
|
if (!isPaused(this)) {
|
|
this._resume();
|
|
}
|
|
}
|
|
}
|
|
|
|
_resume() {
|
|
if (shared.Globals.skipAnimation) {
|
|
this.finish();
|
|
} else {
|
|
shared.frameLoop.start(this);
|
|
}
|
|
}
|
|
|
|
_stop(goal, cancel) {
|
|
if (isAnimating(this)) {
|
|
setActiveBit(this, false);
|
|
const anim = this.animation;
|
|
shared.each(anim.values, node => {
|
|
node.done = true;
|
|
});
|
|
|
|
if (anim.toValues) {
|
|
anim.onChange = anim.onPause = anim.onResume = undefined;
|
|
}
|
|
|
|
shared.callFluidObservers(this, {
|
|
type: 'idle',
|
|
parent: this
|
|
});
|
|
const result = cancel ? getCancelledResult(this.get()) : getFinishedResult(this.get(), checkFinished(this, goal != null ? goal : anim.to));
|
|
shared.flushCalls(this._pendingCalls, result);
|
|
|
|
if (anim.changed) {
|
|
anim.changed = false;
|
|
sendEvent(this, 'onRest', result, this);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
function checkFinished(target, to) {
|
|
const goal = computeGoal(to);
|
|
const value = computeGoal(target.get());
|
|
return shared.isEqual(value, goal);
|
|
}
|
|
|
|
function createLoopUpdate(props, loop = props.loop, to = props.to) {
|
|
let loopRet = callProp(loop);
|
|
|
|
if (loopRet) {
|
|
const overrides = loopRet !== true && inferTo(loopRet);
|
|
const reverse = (overrides || props).reverse;
|
|
const reset = !overrides || overrides.reset;
|
|
return createUpdate(_extends({}, props, {
|
|
loop,
|
|
default: false,
|
|
pause: undefined,
|
|
to: !reverse || isAsyncTo(to) ? to : undefined,
|
|
from: reset ? props.from : undefined,
|
|
reset
|
|
}, overrides));
|
|
}
|
|
}
|
|
function createUpdate(props) {
|
|
const {
|
|
to,
|
|
from
|
|
} = props = inferTo(props);
|
|
const keys = new Set();
|
|
if (shared.is.obj(to)) findDefined(to, keys);
|
|
if (shared.is.obj(from)) findDefined(from, keys);
|
|
props.keys = keys.size ? Array.from(keys) : null;
|
|
return props;
|
|
}
|
|
function declareUpdate(props) {
|
|
const update = createUpdate(props);
|
|
|
|
if (shared.is.und(update.default)) {
|
|
update.default = getDefaultProps(update);
|
|
}
|
|
|
|
return update;
|
|
}
|
|
|
|
function findDefined(values, keys) {
|
|
shared.eachProp(values, (value, key) => value != null && keys.add(key));
|
|
}
|
|
|
|
const ACTIVE_EVENTS = ['onStart', 'onRest', 'onChange', 'onPause', 'onResume'];
|
|
|
|
function mergeActiveFn(target, props, type) {
|
|
target.animation[type] = props[type] !== getDefaultProp(props, type) ? resolveProp(props[type], target.key) : undefined;
|
|
}
|
|
|
|
function sendEvent(target, type, ...args) {
|
|
var _target$animation$typ, _target$animation, _target$defaultProps$, _target$defaultProps;
|
|
|
|
(_target$animation$typ = (_target$animation = target.animation)[type]) == null ? void 0 : _target$animation$typ.call(_target$animation, ...args);
|
|
(_target$defaultProps$ = (_target$defaultProps = target.defaultProps)[type]) == null ? void 0 : _target$defaultProps$.call(_target$defaultProps, ...args);
|
|
}
|
|
|
|
const BATCHED_EVENTS = ['onStart', 'onChange', 'onRest'];
|
|
let nextId = 1;
|
|
class Controller {
|
|
constructor(props, flush) {
|
|
this.id = nextId++;
|
|
this.springs = {};
|
|
this.queue = [];
|
|
this.ref = void 0;
|
|
this._flush = void 0;
|
|
this._initialProps = void 0;
|
|
this._lastAsyncId = 0;
|
|
this._active = new Set();
|
|
this._changed = new Set();
|
|
this._started = false;
|
|
this._item = void 0;
|
|
this._state = {
|
|
paused: false,
|
|
pauseQueue: new Set(),
|
|
resumeQueue: new Set(),
|
|
timeouts: new Set()
|
|
};
|
|
this._events = {
|
|
onStart: new Map(),
|
|
onChange: new Map(),
|
|
onRest: new Map()
|
|
};
|
|
this._onFrame = this._onFrame.bind(this);
|
|
|
|
if (flush) {
|
|
this._flush = flush;
|
|
}
|
|
|
|
if (props) {
|
|
this.start(_extends({
|
|
default: true
|
|
}, props));
|
|
}
|
|
}
|
|
|
|
get idle() {
|
|
return !this._state.asyncTo && Object.values(this.springs).every(spring => {
|
|
return spring.idle && !spring.isDelayed && !spring.isPaused;
|
|
});
|
|
}
|
|
|
|
get item() {
|
|
return this._item;
|
|
}
|
|
|
|
set item(item) {
|
|
this._item = item;
|
|
}
|
|
|
|
get() {
|
|
const values = {};
|
|
this.each((spring, key) => values[key] = spring.get());
|
|
return values;
|
|
}
|
|
|
|
set(values) {
|
|
for (const key in values) {
|
|
const value = values[key];
|
|
|
|
if (!shared.is.und(value)) {
|
|
this.springs[key].set(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
update(props) {
|
|
if (props) {
|
|
this.queue.push(createUpdate(props));
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
start(props) {
|
|
let {
|
|
queue
|
|
} = this;
|
|
|
|
if (props) {
|
|
queue = shared.toArray(props).map(createUpdate);
|
|
} else {
|
|
this.queue = [];
|
|
}
|
|
|
|
if (this._flush) {
|
|
return this._flush(this, queue);
|
|
}
|
|
|
|
prepareKeys(this, queue);
|
|
return flushUpdateQueue(this, queue);
|
|
}
|
|
|
|
stop(arg, keys) {
|
|
if (arg !== !!arg) {
|
|
keys = arg;
|
|
}
|
|
|
|
if (keys) {
|
|
const springs = this.springs;
|
|
shared.each(shared.toArray(keys), key => springs[key].stop(!!arg));
|
|
} else {
|
|
stopAsync(this._state, this._lastAsyncId);
|
|
this.each(spring => spring.stop(!!arg));
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
pause(keys) {
|
|
if (shared.is.und(keys)) {
|
|
this.start({
|
|
pause: true
|
|
});
|
|
} else {
|
|
const springs = this.springs;
|
|
shared.each(shared.toArray(keys), key => springs[key].pause());
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
resume(keys) {
|
|
if (shared.is.und(keys)) {
|
|
this.start({
|
|
pause: false
|
|
});
|
|
} else {
|
|
const springs = this.springs;
|
|
shared.each(shared.toArray(keys), key => springs[key].resume());
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
each(iterator) {
|
|
shared.eachProp(this.springs, iterator);
|
|
}
|
|
|
|
_onFrame() {
|
|
const {
|
|
onStart,
|
|
onChange,
|
|
onRest
|
|
} = this._events;
|
|
const active = this._active.size > 0;
|
|
const changed = this._changed.size > 0;
|
|
|
|
if (active && !this._started || changed && !this._started) {
|
|
this._started = true;
|
|
shared.flush(onStart, ([onStart, result]) => {
|
|
result.value = this.get();
|
|
onStart(result, this, this._item);
|
|
});
|
|
}
|
|
|
|
const idle = !active && this._started;
|
|
const values = changed || idle && onRest.size ? this.get() : null;
|
|
|
|
if (changed && onChange.size) {
|
|
shared.flush(onChange, ([onChange, result]) => {
|
|
result.value = values;
|
|
onChange(result, this, this._item);
|
|
});
|
|
}
|
|
|
|
if (idle) {
|
|
this._started = false;
|
|
shared.flush(onRest, ([onRest, result]) => {
|
|
result.value = values;
|
|
onRest(result, this, this._item);
|
|
});
|
|
}
|
|
}
|
|
|
|
eventObserved(event) {
|
|
if (event.type == 'change') {
|
|
this._changed.add(event.parent);
|
|
|
|
if (!event.idle) {
|
|
this._active.add(event.parent);
|
|
}
|
|
} else if (event.type == 'idle') {
|
|
this._active.delete(event.parent);
|
|
} else return;
|
|
|
|
shared.raf.onFrame(this._onFrame);
|
|
}
|
|
|
|
}
|
|
function flushUpdateQueue(ctrl, queue) {
|
|
return Promise.all(queue.map(props => flushUpdate(ctrl, props))).then(results => getCombinedResult(ctrl, results));
|
|
}
|
|
async function flushUpdate(ctrl, props, isLoop) {
|
|
const {
|
|
keys,
|
|
to,
|
|
from,
|
|
loop,
|
|
onRest,
|
|
onResolve
|
|
} = props;
|
|
const defaults = shared.is.obj(props.default) && props.default;
|
|
|
|
if (loop) {
|
|
props.loop = false;
|
|
}
|
|
|
|
if (to === false) props.to = null;
|
|
if (from === false) props.from = null;
|
|
const asyncTo = shared.is.arr(to) || shared.is.fun(to) ? to : undefined;
|
|
|
|
if (asyncTo) {
|
|
props.to = undefined;
|
|
props.onRest = undefined;
|
|
|
|
if (defaults) {
|
|
defaults.onRest = undefined;
|
|
}
|
|
} else {
|
|
shared.each(BATCHED_EVENTS, key => {
|
|
const handler = props[key];
|
|
|
|
if (shared.is.fun(handler)) {
|
|
const queue = ctrl['_events'][key];
|
|
|
|
props[key] = ({
|
|
finished,
|
|
cancelled
|
|
}) => {
|
|
const result = queue.get(handler);
|
|
|
|
if (result) {
|
|
if (!finished) result.finished = false;
|
|
if (cancelled) result.cancelled = true;
|
|
} else {
|
|
queue.set(handler, {
|
|
value: null,
|
|
finished: finished || false,
|
|
cancelled: cancelled || false
|
|
});
|
|
}
|
|
};
|
|
|
|
if (defaults) {
|
|
defaults[key] = props[key];
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
const state = ctrl['_state'];
|
|
|
|
if (props.pause === !state.paused) {
|
|
state.paused = props.pause;
|
|
shared.flushCalls(props.pause ? state.pauseQueue : state.resumeQueue);
|
|
} else if (state.paused) {
|
|
props.pause = true;
|
|
}
|
|
|
|
const promises = (keys || Object.keys(ctrl.springs)).map(key => ctrl.springs[key].start(props));
|
|
const cancel = props.cancel === true || getDefaultProp(props, 'cancel') === true;
|
|
|
|
if (asyncTo || cancel && state.asyncId) {
|
|
promises.push(scheduleProps(++ctrl['_lastAsyncId'], {
|
|
props,
|
|
state,
|
|
actions: {
|
|
pause: shared.noop,
|
|
resume: shared.noop,
|
|
|
|
start(props, resolve) {
|
|
if (cancel) {
|
|
stopAsync(state, ctrl['_lastAsyncId']);
|
|
resolve(getCancelledResult(ctrl));
|
|
} else {
|
|
props.onRest = onRest;
|
|
resolve(runAsync(asyncTo, props, state, ctrl));
|
|
}
|
|
}
|
|
|
|
}
|
|
}));
|
|
}
|
|
|
|
if (state.paused) {
|
|
await new Promise(resume => {
|
|
state.resumeQueue.add(resume);
|
|
});
|
|
}
|
|
|
|
const result = getCombinedResult(ctrl, await Promise.all(promises));
|
|
|
|
if (loop && result.finished && !(isLoop && result.noop)) {
|
|
const nextProps = createLoopUpdate(props, loop, to);
|
|
|
|
if (nextProps) {
|
|
prepareKeys(ctrl, [nextProps]);
|
|
return flushUpdate(ctrl, nextProps, true);
|
|
}
|
|
}
|
|
|
|
if (onResolve) {
|
|
shared.raf.batchedUpdates(() => onResolve(result, ctrl, ctrl.item));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
function getSprings(ctrl, props) {
|
|
const springs = _extends({}, ctrl.springs);
|
|
|
|
if (props) {
|
|
shared.each(shared.toArray(props), props => {
|
|
if (shared.is.und(props.keys)) {
|
|
props = createUpdate(props);
|
|
}
|
|
|
|
if (!shared.is.obj(props.to)) {
|
|
props = _extends({}, props, {
|
|
to: undefined
|
|
});
|
|
}
|
|
|
|
prepareSprings(springs, props, key => {
|
|
return createSpring(key);
|
|
});
|
|
});
|
|
}
|
|
|
|
setSprings(ctrl, springs);
|
|
return springs;
|
|
}
|
|
function setSprings(ctrl, springs) {
|
|
shared.eachProp(springs, (spring, key) => {
|
|
if (!ctrl.springs[key]) {
|
|
ctrl.springs[key] = spring;
|
|
shared.addFluidObserver(spring, ctrl);
|
|
}
|
|
});
|
|
}
|
|
|
|
function createSpring(key, observer) {
|
|
const spring = new SpringValue();
|
|
spring.key = key;
|
|
|
|
if (observer) {
|
|
shared.addFluidObserver(spring, observer);
|
|
}
|
|
|
|
return spring;
|
|
}
|
|
|
|
function prepareSprings(springs, props, create) {
|
|
if (props.keys) {
|
|
shared.each(props.keys, key => {
|
|
const spring = springs[key] || (springs[key] = create(key));
|
|
spring['_prepareNode'](props);
|
|
});
|
|
}
|
|
}
|
|
|
|
function prepareKeys(ctrl, queue) {
|
|
shared.each(queue, props => {
|
|
prepareSprings(ctrl.springs, props, key => {
|
|
return createSpring(key, ctrl);
|
|
});
|
|
});
|
|
}
|
|
|
|
function _objectWithoutPropertiesLoose(source, excluded) {
|
|
if (source == null) return {};
|
|
var target = {};
|
|
var sourceKeys = Object.keys(source);
|
|
var key, i;
|
|
|
|
for (i = 0; i < sourceKeys.length; i++) {
|
|
key = sourceKeys[i];
|
|
if (excluded.indexOf(key) >= 0) continue;
|
|
target[key] = source[key];
|
|
}
|
|
|
|
return target;
|
|
}
|
|
|
|
const _excluded$3 = ["children"];
|
|
const SpringContext = _ref => {
|
|
let {
|
|
children
|
|
} = _ref,
|
|
props = _objectWithoutPropertiesLoose(_ref, _excluded$3);
|
|
|
|
const inherited = React.useContext(ctx);
|
|
const pause = props.pause || !!inherited.pause,
|
|
immediate = props.immediate || !!inherited.immediate;
|
|
props = shared.useMemoOne(() => ({
|
|
pause,
|
|
immediate
|
|
}), [pause, immediate]);
|
|
const {
|
|
Provider
|
|
} = ctx;
|
|
return React__namespace.createElement(Provider, {
|
|
value: props
|
|
}, children);
|
|
};
|
|
const ctx = makeContext(SpringContext, {});
|
|
SpringContext.Provider = ctx.Provider;
|
|
SpringContext.Consumer = ctx.Consumer;
|
|
|
|
function makeContext(target, init) {
|
|
Object.assign(target, React__namespace.createContext(init));
|
|
target.Provider._context = target;
|
|
target.Consumer._context = target;
|
|
return target;
|
|
}
|
|
|
|
const SpringRef = () => {
|
|
const current = [];
|
|
|
|
const SpringRef = function SpringRef(props) {
|
|
shared.deprecateDirectCall();
|
|
const results = [];
|
|
shared.each(current, (ctrl, i) => {
|
|
if (shared.is.und(props)) {
|
|
results.push(ctrl.start());
|
|
} else {
|
|
const update = _getProps(props, ctrl, i);
|
|
|
|
if (update) {
|
|
results.push(ctrl.start(update));
|
|
}
|
|
}
|
|
});
|
|
return results;
|
|
};
|
|
|
|
SpringRef.current = current;
|
|
|
|
SpringRef.add = function (ctrl) {
|
|
if (!current.includes(ctrl)) {
|
|
current.push(ctrl);
|
|
}
|
|
};
|
|
|
|
SpringRef.delete = function (ctrl) {
|
|
const i = current.indexOf(ctrl);
|
|
if (~i) current.splice(i, 1);
|
|
};
|
|
|
|
SpringRef.pause = function () {
|
|
shared.each(current, ctrl => ctrl.pause(...arguments));
|
|
return this;
|
|
};
|
|
|
|
SpringRef.resume = function () {
|
|
shared.each(current, ctrl => ctrl.resume(...arguments));
|
|
return this;
|
|
};
|
|
|
|
SpringRef.set = function (values) {
|
|
shared.each(current, ctrl => ctrl.set(values));
|
|
};
|
|
|
|
SpringRef.start = function (props) {
|
|
const results = [];
|
|
shared.each(current, (ctrl, i) => {
|
|
if (shared.is.und(props)) {
|
|
results.push(ctrl.start());
|
|
} else {
|
|
const update = this._getProps(props, ctrl, i);
|
|
|
|
if (update) {
|
|
results.push(ctrl.start(update));
|
|
}
|
|
}
|
|
});
|
|
return results;
|
|
};
|
|
|
|
SpringRef.stop = function () {
|
|
shared.each(current, ctrl => ctrl.stop(...arguments));
|
|
return this;
|
|
};
|
|
|
|
SpringRef.update = function (props) {
|
|
shared.each(current, (ctrl, i) => ctrl.update(this._getProps(props, ctrl, i)));
|
|
return this;
|
|
};
|
|
|
|
const _getProps = function _getProps(arg, ctrl, index) {
|
|
return shared.is.fun(arg) ? arg(index, ctrl) : arg;
|
|
};
|
|
|
|
SpringRef._getProps = _getProps;
|
|
return SpringRef;
|
|
};
|
|
|
|
function useSprings(length, props, deps) {
|
|
const propsFn = shared.is.fun(props) && props;
|
|
if (propsFn && !deps) deps = [];
|
|
const ref = React.useMemo(() => propsFn || arguments.length == 3 ? SpringRef() : void 0, []);
|
|
const layoutId = React.useRef(0);
|
|
const forceUpdate = shared.useForceUpdate();
|
|
const state = React.useMemo(() => ({
|
|
ctrls: [],
|
|
queue: [],
|
|
|
|
flush(ctrl, updates) {
|
|
const springs = getSprings(ctrl, updates);
|
|
const canFlushSync = layoutId.current > 0 && !state.queue.length && !Object.keys(springs).some(key => !ctrl.springs[key]);
|
|
return canFlushSync ? flushUpdateQueue(ctrl, updates) : new Promise(resolve => {
|
|
setSprings(ctrl, springs);
|
|
state.queue.push(() => {
|
|
resolve(flushUpdateQueue(ctrl, updates));
|
|
});
|
|
forceUpdate();
|
|
});
|
|
}
|
|
|
|
}), []);
|
|
const ctrls = React.useRef([...state.ctrls]);
|
|
const updates = [];
|
|
const prevLength = shared.usePrev(length) || 0;
|
|
React.useMemo(() => {
|
|
shared.each(ctrls.current.slice(length, prevLength), ctrl => {
|
|
detachRefs(ctrl, ref);
|
|
ctrl.stop(true);
|
|
});
|
|
ctrls.current.length = length;
|
|
declareUpdates(prevLength, length);
|
|
}, [length]);
|
|
React.useMemo(() => {
|
|
declareUpdates(0, Math.min(prevLength, length));
|
|
}, deps);
|
|
|
|
function declareUpdates(startIndex, endIndex) {
|
|
for (let i = startIndex; i < endIndex; i++) {
|
|
const ctrl = ctrls.current[i] || (ctrls.current[i] = new Controller(null, state.flush));
|
|
const update = propsFn ? propsFn(i, ctrl) : props[i];
|
|
|
|
if (update) {
|
|
updates[i] = declareUpdate(update);
|
|
}
|
|
}
|
|
}
|
|
|
|
const springs = ctrls.current.map((ctrl, i) => getSprings(ctrl, updates[i]));
|
|
const context = React.useContext(SpringContext);
|
|
const prevContext = shared.usePrev(context);
|
|
const hasContext = context !== prevContext && hasProps(context);
|
|
shared.useLayoutEffect(() => {
|
|
layoutId.current++;
|
|
state.ctrls = ctrls.current;
|
|
const {
|
|
queue
|
|
} = state;
|
|
|
|
if (queue.length) {
|
|
state.queue = [];
|
|
shared.each(queue, cb => cb());
|
|
}
|
|
|
|
shared.each(ctrls.current, (ctrl, i) => {
|
|
ref == null ? void 0 : ref.add(ctrl);
|
|
|
|
if (hasContext) {
|
|
ctrl.start({
|
|
default: context
|
|
});
|
|
}
|
|
|
|
const update = updates[i];
|
|
|
|
if (update) {
|
|
replaceRef(ctrl, update.ref);
|
|
|
|
if (ctrl.ref) {
|
|
ctrl.queue.push(update);
|
|
} else {
|
|
ctrl.start(update);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
shared.useOnce(() => () => {
|
|
shared.each(state.ctrls, ctrl => ctrl.stop(true));
|
|
});
|
|
const values = springs.map(x => _extends({}, x));
|
|
return ref ? [values, ref] : values;
|
|
}
|
|
|
|
function useSpring(props, deps) {
|
|
const isFn = shared.is.fun(props);
|
|
const [[values], ref] = useSprings(1, isFn ? props : [props], isFn ? deps || [] : deps);
|
|
return isFn || arguments.length == 2 ? [values, ref] : values;
|
|
}
|
|
|
|
const initSpringRef = () => SpringRef();
|
|
|
|
const useSpringRef = () => React.useState(initSpringRef)[0];
|
|
|
|
function useTrail(length, propsArg, deps) {
|
|
var _passedRef;
|
|
|
|
const propsFn = shared.is.fun(propsArg) && propsArg;
|
|
if (propsFn && !deps) deps = [];
|
|
let reverse = true;
|
|
let passedRef = undefined;
|
|
const result = useSprings(length, (i, ctrl) => {
|
|
const props = propsFn ? propsFn(i, ctrl) : propsArg;
|
|
passedRef = props.ref;
|
|
reverse = reverse && props.reverse;
|
|
return props;
|
|
}, deps || [{}]);
|
|
const ref = (_passedRef = passedRef) != null ? _passedRef : result[1];
|
|
shared.useLayoutEffect(() => {
|
|
shared.each(ref.current, (ctrl, i) => {
|
|
const parent = ref.current[i + (reverse ? 1 : -1)];
|
|
|
|
if (parent) {
|
|
ctrl.start({
|
|
to: parent.springs
|
|
});
|
|
} else {
|
|
ctrl.start();
|
|
}
|
|
});
|
|
}, deps);
|
|
|
|
if (propsFn || arguments.length == 3) {
|
|
ref['_getProps'] = (propsArg, ctrl, i) => {
|
|
const props = shared.is.fun(propsArg) ? propsArg(i, ctrl) : propsArg;
|
|
|
|
if (props) {
|
|
const parent = ref.current[i + (props.reverse ? 1 : -1)];
|
|
if (parent) props.to = parent.springs;
|
|
return props;
|
|
}
|
|
};
|
|
|
|
return result;
|
|
}
|
|
|
|
ref['start'] = propsArg => {
|
|
const results = [];
|
|
shared.each(ref.current, (ctrl, i) => {
|
|
const props = shared.is.fun(propsArg) ? propsArg(i, ctrl) : propsArg;
|
|
const parent = ref.current[i + (reverse ? 1 : -1)];
|
|
|
|
if (parent) {
|
|
results.push(ctrl.start(_extends({}, props, {
|
|
to: parent.springs
|
|
})));
|
|
} else {
|
|
results.push(ctrl.start(_extends({}, props)));
|
|
}
|
|
});
|
|
return results;
|
|
};
|
|
|
|
return result[0];
|
|
}
|
|
|
|
let TransitionPhase;
|
|
|
|
(function (TransitionPhase) {
|
|
TransitionPhase["MOUNT"] = "mount";
|
|
TransitionPhase["ENTER"] = "enter";
|
|
TransitionPhase["UPDATE"] = "update";
|
|
TransitionPhase["LEAVE"] = "leave";
|
|
})(TransitionPhase || (TransitionPhase = {}));
|
|
|
|
function useTransition(data, props, deps) {
|
|
const propsFn = shared.is.fun(props) && props;
|
|
const {
|
|
reset,
|
|
sort,
|
|
trail = 0,
|
|
expires = true,
|
|
exitBeforeEnter = false,
|
|
onDestroyed,
|
|
ref: propsRef,
|
|
config: propsConfig
|
|
} = propsFn ? propsFn() : props;
|
|
const ref = React.useMemo(() => propsFn || arguments.length == 3 ? SpringRef() : void 0, []);
|
|
const items = shared.toArray(data);
|
|
const transitions = [];
|
|
const usedTransitions = React.useRef(null);
|
|
const prevTransitions = reset ? null : usedTransitions.current;
|
|
shared.useLayoutEffect(() => {
|
|
usedTransitions.current = transitions;
|
|
});
|
|
shared.useOnce(() => {
|
|
shared.each(usedTransitions.current, t => {
|
|
var _t$ctrl$ref;
|
|
|
|
(_t$ctrl$ref = t.ctrl.ref) == null ? void 0 : _t$ctrl$ref.add(t.ctrl);
|
|
const change = changes.get(t);
|
|
|
|
if (change) {
|
|
t.ctrl.start(change.payload);
|
|
}
|
|
});
|
|
return () => {
|
|
shared.each(usedTransitions.current, t => {
|
|
if (t.expired) {
|
|
clearTimeout(t.expirationId);
|
|
}
|
|
|
|
detachRefs(t.ctrl, ref);
|
|
t.ctrl.stop(true);
|
|
});
|
|
};
|
|
});
|
|
const keys = getKeys(items, propsFn ? propsFn() : props, prevTransitions);
|
|
const expired = reset && usedTransitions.current || [];
|
|
shared.useLayoutEffect(() => shared.each(expired, ({
|
|
ctrl,
|
|
item,
|
|
key
|
|
}) => {
|
|
detachRefs(ctrl, ref);
|
|
callProp(onDestroyed, item, key);
|
|
}));
|
|
const reused = [];
|
|
if (prevTransitions) shared.each(prevTransitions, (t, i) => {
|
|
if (t.expired) {
|
|
clearTimeout(t.expirationId);
|
|
expired.push(t);
|
|
} else {
|
|
i = reused[i] = keys.indexOf(t.key);
|
|
if (~i) transitions[i] = t;
|
|
}
|
|
});
|
|
shared.each(items, (item, i) => {
|
|
if (!transitions[i]) {
|
|
transitions[i] = {
|
|
key: keys[i],
|
|
item,
|
|
phase: TransitionPhase.MOUNT,
|
|
ctrl: new Controller()
|
|
};
|
|
transitions[i].ctrl.item = item;
|
|
}
|
|
});
|
|
|
|
if (reused.length) {
|
|
let i = -1;
|
|
const {
|
|
leave
|
|
} = propsFn ? propsFn() : props;
|
|
shared.each(reused, (keyIndex, prevIndex) => {
|
|
const t = prevTransitions[prevIndex];
|
|
|
|
if (~keyIndex) {
|
|
i = transitions.indexOf(t);
|
|
transitions[i] = _extends({}, t, {
|
|
item: items[keyIndex]
|
|
});
|
|
} else if (leave) {
|
|
transitions.splice(++i, 0, t);
|
|
}
|
|
});
|
|
}
|
|
|
|
if (shared.is.fun(sort)) {
|
|
transitions.sort((a, b) => sort(a.item, b.item));
|
|
}
|
|
|
|
let delay = -trail;
|
|
const forceUpdate = shared.useForceUpdate();
|
|
const defaultProps = getDefaultProps(props);
|
|
const changes = new Map();
|
|
const exitingTransitions = React.useRef(new Map());
|
|
const forceChange = React.useRef(false);
|
|
shared.each(transitions, (t, i) => {
|
|
const key = t.key;
|
|
const prevPhase = t.phase;
|
|
const p = propsFn ? propsFn() : props;
|
|
let to;
|
|
let phase;
|
|
let propsDelay = callProp(p.delay || 0, key);
|
|
|
|
if (prevPhase == TransitionPhase.MOUNT) {
|
|
to = p.enter;
|
|
phase = TransitionPhase.ENTER;
|
|
} else {
|
|
const isLeave = keys.indexOf(key) < 0;
|
|
|
|
if (prevPhase != TransitionPhase.LEAVE) {
|
|
if (isLeave) {
|
|
to = p.leave;
|
|
phase = TransitionPhase.LEAVE;
|
|
} else if (to = p.update) {
|
|
phase = TransitionPhase.UPDATE;
|
|
} else return;
|
|
} else if (!isLeave) {
|
|
to = p.enter;
|
|
phase = TransitionPhase.ENTER;
|
|
} else return;
|
|
}
|
|
|
|
to = callProp(to, t.item, i);
|
|
to = shared.is.obj(to) ? inferTo(to) : {
|
|
to
|
|
};
|
|
|
|
if (!to.config) {
|
|
const config = propsConfig || defaultProps.config;
|
|
to.config = callProp(config, t.item, i, phase);
|
|
}
|
|
|
|
delay += trail;
|
|
|
|
const payload = _extends({}, defaultProps, {
|
|
delay: propsDelay + delay,
|
|
ref: propsRef,
|
|
immediate: p.immediate,
|
|
reset: false
|
|
}, to);
|
|
|
|
if (phase == TransitionPhase.ENTER && shared.is.und(payload.from)) {
|
|
const _p = propsFn ? propsFn() : props;
|
|
|
|
const from = shared.is.und(_p.initial) || prevTransitions ? _p.from : _p.initial;
|
|
payload.from = callProp(from, t.item, i);
|
|
}
|
|
|
|
const {
|
|
onResolve
|
|
} = payload;
|
|
|
|
payload.onResolve = result => {
|
|
callProp(onResolve, result);
|
|
const transitions = usedTransitions.current;
|
|
const t = transitions.find(t => t.key === key);
|
|
if (!t) return;
|
|
|
|
if (result.cancelled && t.phase != TransitionPhase.UPDATE) {
|
|
return;
|
|
}
|
|
|
|
if (t.ctrl.idle) {
|
|
const idle = transitions.every(t => t.ctrl.idle);
|
|
|
|
if (t.phase == TransitionPhase.LEAVE) {
|
|
const expiry = callProp(expires, t.item);
|
|
|
|
if (expiry !== false) {
|
|
const expiryMs = expiry === true ? 0 : expiry;
|
|
t.expired = true;
|
|
|
|
if (!idle && expiryMs > 0) {
|
|
if (expiryMs <= 0x7fffffff) t.expirationId = setTimeout(forceUpdate, expiryMs);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (idle && transitions.some(t => t.expired)) {
|
|
exitingTransitions.current.delete(t);
|
|
|
|
if (exitBeforeEnter) {
|
|
forceChange.current = true;
|
|
}
|
|
|
|
forceUpdate();
|
|
}
|
|
}
|
|
};
|
|
|
|
const springs = getSprings(t.ctrl, payload);
|
|
|
|
if (phase === TransitionPhase.LEAVE && exitBeforeEnter) {
|
|
exitingTransitions.current.set(t, {
|
|
phase,
|
|
springs,
|
|
payload
|
|
});
|
|
} else {
|
|
changes.set(t, {
|
|
phase,
|
|
springs,
|
|
payload
|
|
});
|
|
}
|
|
});
|
|
const context = React.useContext(SpringContext);
|
|
const prevContext = shared.usePrev(context);
|
|
const hasContext = context !== prevContext && hasProps(context);
|
|
shared.useLayoutEffect(() => {
|
|
if (hasContext) {
|
|
shared.each(transitions, t => {
|
|
t.ctrl.start({
|
|
default: context
|
|
});
|
|
});
|
|
}
|
|
}, [context]);
|
|
shared.each(changes, (_, t) => {
|
|
if (exitingTransitions.current.size) {
|
|
const ind = transitions.findIndex(state => state.key === t.key);
|
|
transitions.splice(ind, 1);
|
|
}
|
|
});
|
|
shared.useLayoutEffect(() => {
|
|
shared.each(exitingTransitions.current.size ? exitingTransitions.current : changes, ({
|
|
phase,
|
|
payload
|
|
}, t) => {
|
|
const {
|
|
ctrl
|
|
} = t;
|
|
t.phase = phase;
|
|
ref == null ? void 0 : ref.add(ctrl);
|
|
|
|
if (hasContext && phase == TransitionPhase.ENTER) {
|
|
ctrl.start({
|
|
default: context
|
|
});
|
|
}
|
|
|
|
if (payload) {
|
|
replaceRef(ctrl, payload.ref);
|
|
|
|
if (ctrl.ref && !forceChange.current) {
|
|
ctrl.update(payload);
|
|
} else {
|
|
ctrl.start(payload);
|
|
|
|
if (forceChange.current) {
|
|
forceChange.current = false;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}, reset ? void 0 : deps);
|
|
|
|
const renderTransitions = render => React__namespace.createElement(React__namespace.Fragment, null, transitions.map((t, i) => {
|
|
const {
|
|
springs
|
|
} = changes.get(t) || t.ctrl;
|
|
const elem = render(_extends({}, springs), t.item, t, i);
|
|
return elem && elem.type ? React__namespace.createElement(elem.type, _extends({}, elem.props, {
|
|
key: shared.is.str(t.key) || shared.is.num(t.key) ? t.key : t.ctrl.id,
|
|
ref: elem.ref
|
|
})) : elem;
|
|
}));
|
|
|
|
return ref ? [renderTransitions, ref] : renderTransitions;
|
|
}
|
|
let nextKey = 1;
|
|
|
|
function getKeys(items, {
|
|
key,
|
|
keys = key
|
|
}, prevTransitions) {
|
|
if (keys === null) {
|
|
const reused = new Set();
|
|
return items.map(item => {
|
|
const t = prevTransitions && prevTransitions.find(t => t.item === item && t.phase !== TransitionPhase.LEAVE && !reused.has(t));
|
|
|
|
if (t) {
|
|
reused.add(t);
|
|
return t.key;
|
|
}
|
|
|
|
return nextKey++;
|
|
});
|
|
}
|
|
|
|
return shared.is.und(keys) ? items : shared.is.fun(keys) ? items.map(keys) : shared.toArray(keys);
|
|
}
|
|
|
|
const _excluded$2 = ["children"];
|
|
function Spring(_ref) {
|
|
let {
|
|
children
|
|
} = _ref,
|
|
props = _objectWithoutPropertiesLoose(_ref, _excluded$2);
|
|
|
|
return children(useSpring(props));
|
|
}
|
|
|
|
const _excluded$1 = ["items", "children"];
|
|
function Trail(_ref) {
|
|
let {
|
|
items,
|
|
children
|
|
} = _ref,
|
|
props = _objectWithoutPropertiesLoose(_ref, _excluded$1);
|
|
|
|
const trails = useTrail(items.length, props);
|
|
return items.map((item, index) => {
|
|
const result = children(item, index);
|
|
return shared.is.fun(result) ? result(trails[index]) : result;
|
|
});
|
|
}
|
|
|
|
const _excluded = ["items", "children"];
|
|
function Transition(_ref) {
|
|
let {
|
|
items,
|
|
children
|
|
} = _ref,
|
|
props = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
|
|
return useTransition(items, props)(children);
|
|
}
|
|
|
|
class Interpolation extends FrameValue {
|
|
constructor(source, args) {
|
|
super();
|
|
this.key = void 0;
|
|
this.idle = true;
|
|
this.calc = void 0;
|
|
this._active = new Set();
|
|
this.source = source;
|
|
this.calc = shared.createInterpolator(...args);
|
|
|
|
const value = this._get();
|
|
|
|
const nodeType = animated$1.getAnimatedType(value);
|
|
animated$1.setAnimated(this, nodeType.create(value));
|
|
}
|
|
|
|
advance(_dt) {
|
|
const value = this._get();
|
|
|
|
const oldValue = this.get();
|
|
|
|
if (!shared.isEqual(value, oldValue)) {
|
|
animated$1.getAnimated(this).setValue(value);
|
|
|
|
this._onChange(value, this.idle);
|
|
}
|
|
|
|
if (!this.idle && checkIdle(this._active)) {
|
|
becomeIdle(this);
|
|
}
|
|
}
|
|
|
|
_get() {
|
|
const inputs = shared.is.arr(this.source) ? this.source.map(shared.getFluidValue) : shared.toArray(shared.getFluidValue(this.source));
|
|
return this.calc(...inputs);
|
|
}
|
|
|
|
_start() {
|
|
if (this.idle && !checkIdle(this._active)) {
|
|
this.idle = false;
|
|
shared.each(animated$1.getPayload(this), node => {
|
|
node.done = false;
|
|
});
|
|
|
|
if (shared.Globals.skipAnimation) {
|
|
shared.raf.batchedUpdates(() => this.advance());
|
|
becomeIdle(this);
|
|
} else {
|
|
shared.frameLoop.start(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
_attach() {
|
|
let priority = 1;
|
|
shared.each(shared.toArray(this.source), source => {
|
|
if (shared.hasFluidValue(source)) {
|
|
shared.addFluidObserver(source, this);
|
|
}
|
|
|
|
if (isFrameValue(source)) {
|
|
if (!source.idle) {
|
|
this._active.add(source);
|
|
}
|
|
|
|
priority = Math.max(priority, source.priority + 1);
|
|
}
|
|
});
|
|
this.priority = priority;
|
|
|
|
this._start();
|
|
}
|
|
|
|
_detach() {
|
|
shared.each(shared.toArray(this.source), source => {
|
|
if (shared.hasFluidValue(source)) {
|
|
shared.removeFluidObserver(source, this);
|
|
}
|
|
});
|
|
|
|
this._active.clear();
|
|
|
|
becomeIdle(this);
|
|
}
|
|
|
|
eventObserved(event) {
|
|
if (event.type == 'change') {
|
|
if (event.idle) {
|
|
this.advance();
|
|
} else {
|
|
this._active.add(event.parent);
|
|
|
|
this._start();
|
|
}
|
|
} else if (event.type == 'idle') {
|
|
this._active.delete(event.parent);
|
|
} else if (event.type == 'priority') {
|
|
this.priority = shared.toArray(this.source).reduce((highest, parent) => Math.max(highest, (isFrameValue(parent) ? parent.priority : 0) + 1), 0);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
function isIdle(source) {
|
|
return source.idle !== false;
|
|
}
|
|
|
|
function checkIdle(active) {
|
|
return !active.size || Array.from(active).every(isIdle);
|
|
}
|
|
|
|
function becomeIdle(self) {
|
|
if (!self.idle) {
|
|
self.idle = true;
|
|
shared.each(animated$1.getPayload(self), node => {
|
|
node.done = true;
|
|
});
|
|
shared.callFluidObservers(self, {
|
|
type: 'idle',
|
|
parent: self
|
|
});
|
|
}
|
|
}
|
|
|
|
const to = (source, ...args) => new Interpolation(source, args);
|
|
const interpolate = (source, ...args) => (shared.deprecateInterpolate(), new Interpolation(source, args));
|
|
|
|
shared.Globals.assign({
|
|
createStringInterpolator: shared.createStringInterpolator,
|
|
to: (source, args) => new Interpolation(source, args)
|
|
});
|
|
const update = shared.frameLoop.advance;
|
|
|
|
Object.defineProperty(exports, 'Globals', {
|
|
enumerable: true,
|
|
get: function () {
|
|
return shared.Globals;
|
|
}
|
|
});
|
|
Object.defineProperty(exports, 'createInterpolator', {
|
|
enumerable: true,
|
|
get: function () {
|
|
return shared.createInterpolator;
|
|
}
|
|
});
|
|
exports.BailSignal = BailSignal;
|
|
exports.Controller = Controller;
|
|
exports.FrameValue = FrameValue;
|
|
exports.Interpolation = Interpolation;
|
|
exports.Spring = Spring;
|
|
exports.SpringContext = SpringContext;
|
|
exports.SpringRef = SpringRef;
|
|
exports.SpringValue = SpringValue;
|
|
exports.Trail = Trail;
|
|
exports.Transition = Transition;
|
|
exports.config = config;
|
|
exports.easings = easings;
|
|
exports.inferTo = inferTo;
|
|
exports.interpolate = interpolate;
|
|
exports.to = to;
|
|
exports.update = update;
|
|
exports.useChain = useChain;
|
|
exports.useSpring = useSpring;
|
|
exports.useSpringRef = useSpringRef;
|
|
exports.useSprings = useSprings;
|
|
exports.useTrail = useTrail;
|
|
exports.useTransition = useTransition;
|
|
Object.keys(animated).forEach(function (k) {
|
|
if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, {
|
|
enumerable: true,
|
|
get: function () {
|
|
return animated[k];
|
|
}
|
|
});
|
|
});
|
|
Object.keys(interpolation).forEach(function (k) {
|
|
if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, {
|
|
enumerable: true,
|
|
get: function () {
|
|
return interpolation[k];
|
|
}
|
|
});
|
|
});
|
|
|
|
}, function(modId) { var map = {}; return __REQUIRE__(map[modId], modId); })
|
|
return __REQUIRE__(1656641689787);
|
|
})()
|
|
//miniprogram-npm-outsideDeps=["@react-spring/shared","react","@react-spring/animated","@react-spring/types/animated","@react-spring/types/interpolation"]
|
|
//# sourceMappingURL=index.js.map
|