-
Notifications
You must be signed in to change notification settings - Fork 0
/
ScrollAnimation.js
64 lines (60 loc) · 1.67 KB
/
ScrollAnimation.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
* スクロールアニメーションするクラスです。
*/
export class ScrollAnimation {
startPositionX = 0;
startPositionY = 0;
endPositionX = 0;
endPositionY = 0;
startTime = 0;
duration = 1000;
animationId;
constructor({ duration }) {
this.duration = duration;
}
/**
* アニメーションのイージング関数です
* @param x
* @returns {number}
*/
easeOutQuart(x) {
return 1 - Math.pow(1 - x, 4);
}
/**
* フレームごとにスクロールを実行する関数です。
* これを連続的に繰り返すことでアニメーションさせています。
*/
animation() {
const progress = Math.min(1, (Date.now() - this.startTime) / this.duration);
const scrollValX =
this.startPositionX +
(this.endPositionX - this.startPositionX) * this.easeOutQuart(progress);
const scrollValY =
this.startPositionY +
(this.endPositionY - this.startPositionY) * this.easeOutQuart(progress);
window.scrollTo(scrollValX, scrollValY);
if (progress < 1) {
this.animationId = requestAnimationFrame(() => {
this.animation();
});
}
}
/**
* アニメーションをキャンセルします
*/
cancelScroll() {
window.cancelAnimationFrame(this.animationId);
}
/**
* スクロールアニメーションを実行します
* @param target
*/
exeScroll({ target }) {
this.startPositionX = window.scrollX;
this.startPositionY = window.scrollY;
this.endPositionX = target.x != null ? target.x : window.scrollX;
this.endPositionY = target.y != null ? target.y : window.scrollY;
this.startTime = Date.now();
this.animation();
}
}