-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcarousel.js
More file actions
125 lines (110 loc) · 3.7 KB
/
carousel.js
File metadata and controls
125 lines (110 loc) · 3.7 KB
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
122
123
124
125
(function () {
document.querySelectorAll('section[aria-roledescription="carousel"]').forEach(function (section) {
var track = section.querySelector('ul.framer--carousel');
var controls = section.querySelector('fieldset.framer--carousel-controls');
if (!track || !controls) return;
var slides = Array.prototype.slice.call(track.querySelectorAll(':scope > li'));
if (slides.length === 0) return;
var prevBtn = controls.querySelector('button[aria-label="Previous"]');
var nextBtn = controls.querySelector('button[aria-label="Next"]');
var dotBtns = Array.prototype.slice.call(
controls.querySelectorAll('button[aria-label^="Scroll to page"]')
);
function getCurrentIndex() {
var trackRect = track.getBoundingClientRect();
var center = trackRect.left + trackRect.width / 2;
var closest = 0;
var closestDist = Infinity;
for (var i = 0; i < slides.length; i++) {
var r = slides[i].getBoundingClientRect();
var slideCenter = r.left + r.width / 2;
var dist = Math.abs(slideCenter - center);
if (dist < closestDist) {
closestDist = dist;
closest = i;
}
}
return closest;
}
function scrollToIndex(idx) {
if (idx < 0) idx = 0;
if (idx >= slides.length) idx = slides.length - 1;
slides[idx].scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
}
function updateUI() {
var idx = getCurrentIndex();
if (prevBtn) {
if (idx === 0) {
prevBtn.style.opacity = '0';
prevBtn.style.pointerEvents = 'none';
prevBtn.style.cursor = 'default';
} else {
prevBtn.style.opacity = '1';
prevBtn.style.pointerEvents = 'auto';
prevBtn.style.cursor = 'pointer';
}
}
if (nextBtn) {
if (idx === slides.length - 1) {
nextBtn.style.opacity = '0';
nextBtn.style.pointerEvents = 'none';
nextBtn.style.cursor = 'default';
} else {
nextBtn.style.opacity = '1';
nextBtn.style.pointerEvents = 'auto';
nextBtn.style.cursor = 'pointer';
}
}
for (var i = 0; i < dotBtns.length; i++) {
var dot = dotBtns[i].querySelector('div');
if (dot) {
dot.style.opacity = i === idx ? '1' : '0.5';
}
}
}
function addPressEffect(btn) {
if (!btn) return;
btn.style.transition = 'transform 0.1s ease';
btn.addEventListener('mousedown', function () {
btn.style.transform = 'scale(0.85)';
});
btn.addEventListener('mouseup', function () {
btn.style.transform = 'none';
});
btn.addEventListener('mouseleave', function () {
btn.style.transform = 'none';
});
btn.addEventListener('touchstart', function () {
btn.style.transform = 'scale(0.85)';
});
btn.addEventListener('touchend', function () {
btn.style.transform = 'none';
});
}
addPressEffect(prevBtn);
addPressEffect(nextBtn);
if (prevBtn) {
prevBtn.addEventListener('click', function () {
var idx = getCurrentIndex();
if (idx > 0) scrollToIndex(idx - 1);
});
}
if (nextBtn) {
nextBtn.addEventListener('click', function () {
var idx = getCurrentIndex();
if (idx < slides.length - 1) scrollToIndex(idx + 1);
});
}
dotBtns.forEach(function (btn, i) {
btn.addEventListener('click', function () {
scrollToIndex(i);
});
});
var scrollTimer;
track.addEventListener('scroll', function () {
clearTimeout(scrollTimer);
scrollTimer = setTimeout(updateUI, 100);
});
updateUI();
});
})();