-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtimeline.js
121 lines (107 loc) · 3.72 KB
/
timeline.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
(function() {
// VARIABLES
const timeline = document.querySelector(".timeline ol"),
elH = document.querySelectorAll(".timeline li > div"),
arrows = document.querySelectorAll(".timeline .arrows .arrow"),
arrowPrev = document.querySelector(".timeline .arrows .arrow__prev"),
arrowNext = document.querySelector(".timeline .arrows .arrow__next"),
firstItem = document.querySelector(".timeline li:first-child"),
lastItem = document.querySelector(".timeline li:last-child"),
xScrolling = 280,
disabledClass = "disabled";
// START
window.addEventListener("load", init);
function init() {
setEqualHeights(elH);
animateTl(xScrolling, arrows, timeline);
setSwipeFn(timeline, arrowPrev, arrowNext);
setKeyboardFn(arrowPrev, arrowNext);
}
// SET EQUAL HEIGHTS
function setEqualHeights(el) {
let counter = 0;
for (let i = 0; i < el.length; i++) {
const singleHeight = el[i].offsetHeight;
if (counter < singleHeight) {
counter = singleHeight;
}
}
for (let i = 0; i < el.length; i++) {
el[i].style.height = `${counter}px`;
}
}
// CHECK IF AN ELEMENT IS IN VIEWPORT
// http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
function isElementInViewport(el) {
const rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
// SET STATE OF PREV/NEXT ARROWS
function setBtnState(el, flag = true) {
if (flag) {
el.classList.add(disabledClass);
} else {
if (el.classList.contains(disabledClass)) {
el.classList.remove(disabledClass);
}
el.disabled = false;
}
}
// ANIMATE TIMELINE
function animateTl(scrolling, el, tl) {
let counter = 0;
for (let i = 0; i < el.length; i++) {
el[i].addEventListener("click", function() {
if (!arrowPrev.disabled) {
arrowPrev.disabled = true;
}
if (!arrowNext.disabled) {
arrowNext.disabled = true;
}
const sign = (this.classList.contains("arrow__prev")) ? "" : "-";
if (counter === 0) {
tl.style.transform = `translateX(-${scrolling}px)`;
} else {
const tlStyle = getComputedStyle(tl);
// add more browser prefixes if needed here
const tlTransform = tlStyle.getPropertyValue("-webkit-transform") || tlStyle.getPropertyValue("transform");
const values = parseInt(tlTransform.split(",")[4]) + parseInt(`${sign}${scrolling}`);
tl.style.transform = `translateX(${values}px)`;
}
setTimeout(() => {
isElementInViewport(firstItem) ? setBtnState(arrowPrev) : setBtnState(arrowPrev, false);
isElementInViewport(lastItem) ? setBtnState(arrowNext) : setBtnState(arrowNext, false);
}, 1100);
counter++;
});
}
}
// ADD SWIPE SUPPORT FOR TOUCH DEVICES
function setSwipeFn(tl, prev, next) {
const hammer = new Hammer(tl);
hammer.on("swipeleft", () => next.click());
hammer.on("swiperight", () => prev.click());
}
// ADD BASIC KEYBOARD FUNCTIONALITY
function setKeyboardFn(prev, next) {
document.addEventListener("keydown", (e) => {
if ((e.which === 37) || (e.which === 39)) {
const timelineOfTop = timeline.offsetTop;
const y = window.pageYOffset;
if (timelineOfTop !== y) {
window.scrollTo(0, timelineOfTop);
}
if (e.which === 37) {
prev.click();
} else if (e.which === 39) {
next.click();
}
}
});
}
})();