use-animate-number
Version:
React hook for changin a number value smoothly
104 lines (103 loc) • 4.05 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
var react_1 = require("react");
var easings = __importStar(require("./easingFunctions"));
var initTimer = setTimeout(function () { return null; }, Math.max());
var defaultOptions = {
duration: 1000,
enterance: true,
direct: false,
disabled: false,
easing: 'easeInOutQuad',
decimals: 2,
};
var useAnimateNumber = function (initial, options) {
if (initial === void 0) { initial = 0; }
var conf = __assign(__assign({}, defaultOptions), options);
var increment = 20;
var _a = react_1.useState({
value: initial,
skip: conf.disabled || !conf.enterance,
}), animationInfo = _a[0], setAnimationInfo = _a[1];
var _b = react_1.useState(conf.duration + 100), currentTime = _b[0], setCurrentTime = _b[1];
var _c = react_1.useState(0), currentValue = _c[0], setCurrentValue = _c[1];
var timer = react_1.useRef(initTimer);
var clearTm = function () { return timer && clearTimeout(timer.current); };
// Clear timer at load and unload
react_1.useEffect(function () {
clearTm();
return function () { return clearTm(); };
}, []);
react_1.useEffect(function () {
if (conf.direct) {
clearTm();
setAnimationInfo({ value: initial, skip: conf.disabled });
}
}, [initial]);
// Start animation: clear previous timer, setTime to zero
react_1.useEffect(function () {
if (animationInfo.skip) {
setCurrentValue(animationInfo.value || 0);
}
else {
setCurrentTime(0);
}
}, [animationInfo]);
var easingFn = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return easings['easeInOutQuad'].apply(easings, args);
};
var handleValueSet = function (value, skip) {
if (skip === void 0) { skip = conf.disabled; }
clearTm();
// wrapped by timeout to get all of the function calls simultaneously
setTimeout(function () {
setAnimationInfo({ value: value, skip: skip });
}, 1);
};
// Animation frame for each currentTime change.
react_1.useEffect(function () {
if (currentTime < conf.duration) {
setCurrentValue(easingFn(currentTime, currentValue, (animationInfo.value - currentValue), conf.duration));
timer.current = setTimeout(function () {
// trigger animation frame effect by increasing currentTime
setCurrentTime(currentTime + increment);
}, increment);
}
}, [currentTime]);
return [parseFloat((currentValue).toFixed(conf.decimals)), handleValueSet];
};
exports.default = useAnimateNumber;