Skip to content

Commit a1d911d

Browse files
authored
Merge pull request #27 from xehpuk/master
Cancel previous animation if still running
2 parents f03abe1 + dd08eba commit a1d911d

File tree

2 files changed

+45
-32
lines changed

2 files changed

+45
-32
lines changed

src/helpers.js

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,46 @@
1-
import { setTimeout } from 'requestanimationframe-timer';
2-
3-
export function animateScroll (id, animate) {
4-
return new Promise((resolve, reject) => {
5-
const element = id ? document.getElementById(id) : document.body;
6-
7-
if (!element) {
8-
return reject(`Cannot find element: #${id}`);
9-
}
10-
11-
const { offset, duration, easing } = animate;
12-
const start = getScrollTop();
13-
const to = getOffsetTop(element) + offset;
14-
const change = to - start;
15-
16-
function animateFn (elapsedTime = 0) {
17-
const increment = 20;
18-
const elapsed = elapsedTime + increment;
19-
const position = easing(null, elapsed, start, change, duration);
20-
setScrollTop(position);
21-
if (elapsed < duration) {
22-
setTimeout(function () {
23-
animateFn(elapsed);
24-
}, increment);
25-
} else {
26-
return resolve(id);
1+
import { setTimeout, clearTimeout } from 'requestanimationframe-timer';
2+
3+
export const animateScroll = (function () {
4+
let timeoutId;
5+
let resolvePrevious;
6+
7+
return function animateScroll (id, animate) {
8+
return new Promise((resolve, reject) => {
9+
const element = id ? document.getElementById(id) : document.body;
10+
11+
if (!element) {
12+
return reject(`Cannot find element: #${id}`);
2713
}
28-
}
2914

30-
animateFn();
31-
});
32-
}
15+
const { offset, duration, easing } = animate;
16+
const start = getScrollTop();
17+
const to = getOffsetTop(element) + offset;
18+
const change = to - start;
19+
20+
function animateFn (elapsedTime = 0) {
21+
const increment = 20;
22+
const elapsed = elapsedTime + increment;
23+
const position = easing(null, elapsed, start, change, duration);
24+
setScrollTop(position);
25+
if (elapsed < duration) {
26+
timeoutId = setTimeout(function () {
27+
animateFn(elapsed);
28+
}, increment);
29+
} else {
30+
timeoutId = undefined;
31+
return resolve(id);
32+
}
33+
}
34+
35+
if (timeoutId) {
36+
clearTimeout(timeoutId);
37+
resolvePrevious();
38+
}
39+
resolvePrevious = resolve;
40+
animateFn();
41+
});
42+
};
43+
})();
3344

3445
export function updateHistory (id) {
3546
window.location.hash = id;

src/scrollchor.jsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ export default class Scrollchor extends React.Component {
4343
event && event.preventDefault();
4444
animateScroll(this.state.to, this.state.animate)
4545
.then((id) => {
46-
this.state.disableHistory || updateHistory(id);
47-
this.state.afterAnimate(event);
46+
if (id) {
47+
this.state.disableHistory || updateHistory(id);
48+
this.state.afterAnimate(event);
49+
}
4850
});
4951
}
5052

0 commit comments

Comments
 (0)