Skip to content

Commit 1e87b68

Browse files
authored
Fix countdown smart easing (#288)
* log animation duration * small improvements * fix the bug (#287) * fix issue in determineDirectionAndSmartEasing * clean up * build
1 parent 5ec1dfb commit 1e87b68

File tree

9 files changed

+72
-58
lines changed

9 files changed

+72
-58
lines changed

.eslintrc.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ module.exports = {
99
'plugin:@typescript-eslint/recommended',
1010
],
1111
rules: {
12-
"@typescript-eslint/no-explicit-any": "off",
13-
"@typescript-eslint/explicit-module-boundary-types": "off"
12+
'@typescript-eslint/no-explicit-any': 'off',
13+
'@typescript-eslint/explicit-module-boundary-types': 'off',
14+
'no-prototype-builtins': 'off',
15+
},
16+
env: {
17+
browser: true,
18+
es6: true,
1419
}
1520
};

demo/demo.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ window.onload = function () {
88
var demo = new CountUp('myTargetElement', 100);
99
var codeVisualizer = el('codeVisualizer');
1010
var errorSection = el('errorSection');
11+
var startTime;
1112
el('version').innerHTML = demo.version;
1213

1314
document.querySelectorAll('.updateCodeVis').forEach(elem => elem.onchange = updateCodeVisualizer);
@@ -99,11 +100,12 @@ window.onload = function () {
99100
demo = new CountUp('myTargetElement', endVal, options);
100101
if (!demo.error) {
101102
errorSection.style.display = 'none';
103+
startTime = Date.now();
102104
if (el('useOnComplete').checked) {
103105
demo.start(methodToCallOnComplete);
104106
}
105107
else {
106-
demo.start();
108+
demo.start(() => calculateAnimationTime());
107109
}
108110
updateCodeVisualizer();
109111
}
@@ -113,7 +115,12 @@ window.onload = function () {
113115
console.error(demo.error);
114116
}
115117
}
118+
function calculateAnimationTime() {
119+
const duration = Date.now() - startTime;
120+
console.log('actual animation duration (ms):', duration);
121+
}
116122
function methodToCallOnComplete() {
123+
calculateAnimationTime();
117124
console.log('COMPLETE!');
118125
alert('COMPLETE!');
119126
}

dist/countUp.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ export declare class CountUp {
4040
once: boolean;
4141
constructor(target: string | HTMLElement | HTMLInputElement, endVal: number, options?: CountUpOptions);
4242
handleScroll(self: CountUp): void;
43+
/**
44+
* Smart easing works by breaking the animation into 2 parts, the second part being the
45+
* smartEasingAmount and first part being the total amount minus the smartEasingAmount. It works
46+
* by disabling easing for the first part and enabling it on the second part. It is used if
47+
* usingEasing is true and the total animation amount exceeds the smartEasingThreshold.
48+
*/
4349
private determineDirectionAndSmartEasing;
4450
start(callback?: (args?: any) => any): void;
4551
pauseResume(): void;

dist/countUp.js

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var CountUp = /** @class */ (function () {
1515
var _this = this;
1616
this.endVal = endVal;
1717
this.options = options;
18-
this.version = '2.3.1';
18+
this.version = '2.3.2';
1919
this.defaults = {
2020
startVal: 0,
2121
decimalPlaces: 0,
@@ -55,20 +55,11 @@ var CountUp = /** @class */ (function () {
5555
}
5656
}
5757
else {
58-
if (_this.countDown) {
59-
_this.frameVal = _this.startVal - ((_this.startVal - _this.endVal) * (progress / _this.duration));
60-
}
61-
else {
62-
_this.frameVal = _this.startVal + (_this.endVal - _this.startVal) * (progress / _this.duration);
63-
}
58+
_this.frameVal = _this.startVal + (_this.endVal - _this.startVal) * (progress / _this.duration);
6459
}
6560
// don't go past endVal since progress can exceed duration in the last frame
66-
if (_this.countDown) {
67-
_this.frameVal = (_this.frameVal < _this.endVal) ? _this.endVal : _this.frameVal;
68-
}
69-
else {
70-
_this.frameVal = (_this.frameVal > _this.endVal) ? _this.endVal : _this.frameVal;
71-
}
61+
var wentPast = _this.countDown ? _this.frameVal < _this.endVal : _this.frameVal > _this.endVal;
62+
_this.frameVal = wentPast ? _this.endVal : _this.frameVal;
7263
// decimal
7364
_this.frameVal = Number(_this.frameVal.toFixed(_this.options.decimalPlaces));
7465
// format and print value
@@ -113,6 +104,7 @@ var CountUp = /** @class */ (function () {
113104
}
114105
return neg + _this.options.prefix + x1 + x2 + _this.options.suffix;
115106
};
107+
// t: current time, b: beginning value, c: change in value, d: duration
116108
this.easeOutExpo = function (t, b, c, d) {
117109
return c * (-Math.pow(2, -10 * t / d) + 1) * 1024 / 1023 + b;
118110
};
@@ -141,7 +133,7 @@ var CountUp = /** @class */ (function () {
141133
// scroll spy
142134
if (typeof window !== 'undefined' && this.options.enableScrollSpy) {
143135
if (!this.error) {
144-
// set up global array of onscroll functions
136+
// set up global array of onscroll functions to handle multiple instances
145137
window['onScrollFns'] = window['onScrollFns'] || [];
146138
window['onScrollFns'].push(function () { return _this.handleScroll(_this); });
147139
window.onscroll = function () {
@@ -172,12 +164,17 @@ var CountUp = /** @class */ (function () {
172164
self.reset();
173165
}
174166
};
175-
// determines where easing starts and whether to count down or up
167+
/**
168+
* Smart easing works by breaking the animation into 2 parts, the second part being the
169+
* smartEasingAmount and first part being the total amount minus the smartEasingAmount. It works
170+
* by disabling easing for the first part and enabling it on the second part. It is used if
171+
* usingEasing is true and the total animation amount exceeds the smartEasingThreshold.
172+
*/
176173
CountUp.prototype.determineDirectionAndSmartEasing = function () {
177174
var end = (this.finalEndVal) ? this.finalEndVal : this.endVal;
178175
this.countDown = (this.startVal > end);
179176
var animateAmount = end - this.startVal;
180-
if (Math.abs(animateAmount) > this.options.smartEasingThreshold) {
177+
if (Math.abs(animateAmount) > this.options.smartEasingThreshold && this.options.useEasing) {
181178
this.finalEndVal = end;
182179
var up = (this.countDown) ? 1 : -1;
183180
this.endVal = end + (up * this.options.smartEasingAmount);
@@ -187,7 +184,8 @@ var CountUp = /** @class */ (function () {
187184
this.endVal = end;
188185
this.finalEndVal = null;
189186
}
190-
if (this.finalEndVal) {
187+
if (this.finalEndVal !== null) {
188+
// setting finalEndVal indicates smart easing
191189
this.useEasing = false;
192190
}
193191
else {
@@ -241,7 +239,7 @@ var CountUp = /** @class */ (function () {
241239
return;
242240
}
243241
this.startVal = this.frameVal;
244-
if (!this.finalEndVal) {
242+
if (this.finalEndVal == null) {
245243
this.resetDuration();
246244
}
247245
this.finalEndVal = null;

dist/countUp.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)