number-flip-animation
Version:
Small typescript package for animating the change of a number using a flip/slide animation.
84 lines (83 loc) • 5.33 kB
JavaScript
var NumberFlip = /** @class */ (function () {
function NumberFlip(_a) {
var rootElement = _a.rootElement, _b = _a.durationSlide, durationSlide = _b === void 0 ? 1000 : _b, _c = _a.durationFade, durationFade = _c === void 0 ? 200 : _c, initialNumber = _a.initialNumber, _d = _a.animateInitialNumber, animateInitialNumber = _d === void 0 ? true : _d, _e = _a.numberFormatter, numberFormatter = _e === void 0 ? function (num) { return num.toString(); } : _e, _f = _a.decimalSeparator, decimalSeparator = _f === void 0 ? '.' : _f, _g = _a.wrapperClassname, wrapperClassname = _g === void 0 ? 'numberflip-digit-container' : _g, _h = _a.digitClassname, digitClassname = _h === void 0 ? 'numberflip-digit-container-value' : _h;
this.rootElement = rootElement;
this.durationSlide = durationSlide;
this.durationFade = durationFade;
this.numberFormatter = numberFormatter;
this.decimalSeparator = decimalSeparator;
this.wrapperClassname = wrapperClassname;
this.digitClassname = digitClassname;
this.rootElement.style.display = 'flex';
if (initialNumber !== undefined) {
this.setNumber(initialNumber, animateInitialNumber);
}
}
NumberFlip.prototype.setNumber = function (num, animate) {
if (animate === void 0) { animate = true; }
this.adjustAmountOfDigitContainers(num);
this.setDigitInContainers(num, animate);
};
NumberFlip.prototype.adjustAmountOfDigitContainers = function (num) {
var numberOfDigits = this.getDigitsOfNumber(num).length;
var countOfDigitContainers = this.rootElement.getElementsByClassName(this.wrapperClassname).length;
// Create digit containers
while (countOfDigitContainers < numberOfDigits) {
this.rootElement.insertAdjacentHTML('beforeend', "<div class=\"".concat(this.wrapperClassname, "\">") +
/*
The span with visibility hidden is needed in order to make the parent element occupy enough space to display the digit.
Otherwise the parent would have a width and height of 0 due to the absolute position of the .numberflip-digit-container-value element
*/
"<span style=\"visibility: hidden;\">0</span>\n <div class=\"".concat(this.digitClassname, "\" style=\"transform: translateY(-100%);\">\n <span>9</span>\n <span>8</span>\n <span>7</span>\n <span>6</span>\n <span>5</span>\n <span>4</span>\n <span>3</span>\n <span>2</span>\n <span>1</span>\n <span>0</span>\n <span>").concat(this.decimalSeparator, "</span>\n </div>\n </div>"));
countOfDigitContainers++;
}
// Remove unnecessary digit containers
if (countOfDigitContainers > numberOfDigits) {
var digitContainers = this.rootElement.getElementsByClassName(this.digitClassname);
var _loop_1 = function (i) {
var digitContainer = digitContainers[i].parentElement;
digitContainer.style.animationDuration = this_1.durationFade + 'ms';
digitContainer.style.animationName = 'numberflip-animation-fade-out';
// Wait for fade out animation to finish before removing the element
setTimeout(function () { return digitContainer.remove(); }, this_1.durationFade);
};
var this_1 = this;
for (var i = numberOfDigits; i < digitContainers.length; i++) {
_loop_1(i);
}
}
};
NumberFlip.prototype.setDigitInContainers = function (num, animate) {
var _this = this;
var digits = this.getDigitsOfNumber(num);
var digitContainers = this.rootElement.getElementsByClassName(this.digitClassname);
var _loop_2 = function (i) {
var digitContainer = digitContainers[i];
var digit = typeof digits[i] === 'number' ? digits[i] : -1;
// typeof check needed for typescripts typechecker
if (typeof digit === 'number') {
var translate_1 = this_2.calculateTranslateY(digit);
setTimeout(function () {
var durationSlide = animate ? _this.durationSlide : 0;
digitContainer.style.transitionDuration = durationSlide + 'ms';
digitContainer.style.transform = "translateY(".concat(translate_1, "%)");
}, 0);
}
};
var this_2 = this;
for (var i = 0; i < digitContainers.length; i++) {
_loop_2(i);
}
};
NumberFlip.prototype.getDigitsOfNumber = function (num) {
var digits = this.numberFormatter(num).split('');
return digits.map(function (char) { return (char === '.' ? '.' : parseInt(char, 10)); });
};
NumberFlip.prototype.calculateTranslateY = function (digit) {
// 11 is the number of span elements defined above in the adjustAmountOfDigitContainers method
var heightOfSpan = 100 / 11;
return (-10 * heightOfSpan + (digit + 1) * heightOfSpan).toString();
};
return NumberFlip;
}());
export { NumberFlip };