Skip to content

Commit 35cc72e

Browse files
committed
add embla in herosection draft
1 parent f13d353 commit 35cc72e

File tree

9 files changed

+639
-40
lines changed

9 files changed

+639
-40
lines changed

assets/css/custom.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* custom classes: */
22
.header-bg {
33
background-image: url(/img/home/header-background.avif), linear-gradient(to bottom, rgb(4.31% 5.88% 9.02%) 0%, rgb(7.84% 20.39% 32.94%) 38%, rgb(24.71% 54.51% 85.1%) 72%, rgb(60.39% 78.04% 96.08%) 90%);
4-
background-size: auto 100%;
4+
background-size: auto 100%, 100% 100%;
55
}
66

77
.container-prose {

assets/js/home-embla.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
(() => {
2+
const root = document.querySelector("[data-embla-swipe-header]");
3+
if (!root || typeof EmblaCarousel === "undefined") {
4+
return;
5+
}
6+
7+
const viewport = root.querySelector(".embla__viewport");
8+
if (!viewport) {
9+
return;
10+
}
11+
12+
const panels = Array.from(root.querySelectorAll("[data-panel]"));
13+
const dots = Array.from(root.querySelectorAll("[data-swipe-dot]"));
14+
const align = (viewSize, snapSize, index) =>
15+
index === 0 ? 0 : Math.max(0, viewSize - snapSize);
16+
17+
const embla = EmblaCarousel(viewport, {
18+
align,
19+
containScroll: false,
20+
loop: false,
21+
});
22+
23+
const selectedIndex = () => embla.selectedScrollSnap();
24+
25+
const updateActive = () => {
26+
const index = selectedIndex();
27+
const activeSide = index === 0 ? "left" : "right";
28+
root.dataset.active = index === 0 ? "left" : "right";
29+
panels.forEach((panel, panelIndex) => {
30+
panel.setAttribute("aria-pressed", panelIndex === index ? "true" : "false");
31+
});
32+
dots.forEach((dot) => {
33+
dot.setAttribute("aria-pressed", dot.dataset.swipeDot === activeSide ? "true" : "false");
34+
});
35+
};
36+
37+
const initialIndex = root.dataset.active === "right" ? 1 : 0;
38+
embla.scrollTo(initialIndex, true);
39+
updateActive();
40+
embla.on("select", updateActive);
41+
embla.on("reInit", () => {
42+
updateActive();
43+
});
44+
45+
const activatePanel = (index) => {
46+
if (index === selectedIndex()) {
47+
return;
48+
}
49+
embla.scrollTo(index);
50+
};
51+
52+
panels.forEach((panel, index) => {
53+
panel.addEventListener("click", (event) => {
54+
if (event.defaultPrevented) {
55+
return;
56+
}
57+
const interactiveTarget = event.target.closest("a, button, input, select, textarea");
58+
if (interactiveTarget && index === selectedIndex()) {
59+
return;
60+
}
61+
activatePanel(index);
62+
});
63+
64+
panel.addEventListener("keydown", (event) => {
65+
if (event.key !== "Enter" && event.key !== " ") {
66+
return;
67+
}
68+
event.preventDefault();
69+
activatePanel(index);
70+
});
71+
});
72+
73+
dots.forEach((dot) => {
74+
dot.addEventListener("click", () => {
75+
activatePanel(dot.dataset.swipeDot === "right" ? 1 : 0);
76+
});
77+
});
78+
79+
})();

assets/js/home-swipe-header.js

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
(() => {
2+
const root = document.querySelector("[data-swipe-header]");
3+
if (!root) {
4+
return;
5+
}
6+
7+
const panels = Array.from(root.querySelectorAll("[data-panel]"));
8+
let resizeTimer = null;
9+
const updateMetrics = () => {
10+
const height = root.getBoundingClientRect().height;
11+
if (height > 0) {
12+
root.style.setProperty("--swipe-max-height", `${height}px`);
13+
}
14+
const header = root.querySelector(".swipe-header");
15+
if (header) {
16+
const width = header.getBoundingClientRect().width;
17+
if (width > 0) {
18+
const isDesktop = window.matchMedia("(min-width: 768px)").matches;
19+
const targetWidth = isDesktop ? width * 0.8 : width;
20+
root.style.setProperty("--swipe-active-width", `${Math.round(targetWidth)}px`);
21+
}
22+
}
23+
};
24+
25+
const queueHeightUpdate = () => {
26+
if (resizeTimer) {
27+
window.clearTimeout(resizeTimer);
28+
}
29+
resizeTimer = window.setTimeout(() => {
30+
updateMetrics();
31+
resizeTimer = null;
32+
}, 150);
33+
};
34+
35+
updateMetrics();
36+
window.addEventListener("load", updateMetrics);
37+
window.addEventListener("resize", queueHeightUpdate);
38+
root.addEventListener("load", updateMetrics, true);
39+
document.addEventListener("lazyloaded", updateMetrics);
40+
41+
let animationTimer = null;
42+
const setActive = (side) => {
43+
if (root.dataset.active === side) {
44+
return;
45+
}
46+
47+
const previous = root.dataset.active;
48+
const previousPanel = panels.find(
49+
(panel) => panel.dataset.panel === previous
50+
);
51+
const previousContent = previousPanel
52+
? previousPanel.querySelector(".swipe-panel__content")
53+
: null;
54+
const previousBody = previousPanel
55+
? previousPanel.querySelector(".swipe-panel__body")
56+
: null;
57+
if (previousPanel && previousContent) {
58+
const panelRect = previousPanel.getBoundingClientRect();
59+
const contentRect = previousContent.getBoundingClientRect();
60+
if (contentRect.width && contentRect.height) {
61+
previousPanel.style.setProperty(
62+
"--swipe-content-width",
63+
`${contentRect.width}px`
64+
);
65+
previousPanel.style.setProperty(
66+
"--swipe-content-height",
67+
`${contentRect.height}px`
68+
);
69+
previousPanel.style.setProperty(
70+
"--swipe-content-top",
71+
`${contentRect.top - panelRect.top}px`
72+
);
73+
previousPanel.style.setProperty(
74+
"--swipe-content-left",
75+
`${contentRect.left - panelRect.left}px`
76+
);
77+
}
78+
}
79+
if (previousPanel && previousBody) {
80+
const bodyRect = previousBody.getBoundingClientRect();
81+
if (bodyRect.height) {
82+
previousPanel.style.setProperty(
83+
"--swipe-body-height",
84+
`${bodyRect.height}px`
85+
);
86+
}
87+
}
88+
root.dataset.animatingOut = previous;
89+
if (animationTimer) {
90+
window.clearTimeout(animationTimer);
91+
}
92+
animationTimer = window.setTimeout(() => {
93+
root.dataset.active = side;
94+
panels.forEach((panel) => {
95+
const isActive = panel.dataset.panel === side;
96+
panel.setAttribute("aria-pressed", isActive ? "true" : "false");
97+
});
98+
root.dataset.animating = side;
99+
window.setTimeout(() => {
100+
if (root.dataset.animating === side) {
101+
root.dataset.animating = "";
102+
}
103+
}, 520);
104+
if (root.dataset.animatingOut === previous) {
105+
root.dataset.animatingOut = "";
106+
}
107+
if (previousPanel) {
108+
previousPanel.style.removeProperty("--swipe-content-width");
109+
previousPanel.style.removeProperty("--swipe-content-height");
110+
previousPanel.style.removeProperty("--swipe-content-top");
111+
previousPanel.style.removeProperty("--swipe-content-left");
112+
previousPanel.style.removeProperty("--swipe-body-height");
113+
}
114+
animationTimer = null;
115+
}, 520);
116+
};
117+
118+
root.addEventListener("click", (event) => {
119+
const panel = event.target.closest("[data-panel]");
120+
if (!panel) {
121+
return;
122+
}
123+
setActive(panel.dataset.panel);
124+
});
125+
126+
root.addEventListener("keydown", (event) => {
127+
if (event.key !== "Enter" && event.key !== " ") {
128+
return;
129+
}
130+
const panel = event.target.closest("[data-panel]");
131+
if (!panel) {
132+
return;
133+
}
134+
event.preventDefault();
135+
setActive(panel.dataset.panel);
136+
});
137+
138+
let startX = null;
139+
root.addEventListener("pointerdown", (event) => {
140+
startX = event.clientX;
141+
});
142+
143+
root.addEventListener("pointerup", (event) => {
144+
if (startX === null) {
145+
return;
146+
}
147+
const dx = event.clientX - startX;
148+
if (Math.abs(dx) > 40) {
149+
setActive(dx < 0 ? "right" : "left");
150+
}
151+
startX = null;
152+
});
153+
154+
root.addEventListener("pointercancel", () => {
155+
startX = null;
156+
});
157+
})();

config/_default/hugo.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ module:
4646
target: assets/js/alpinejs
4747
- source: node_modules/lazysizes
4848
target: assets/js/lazysizes
49+
- source: node_modules/embla-carousel
50+
target: assets/js/embla
4951
- source: node_modules/js-yaml/dist
5052
target: assets/js/js-yaml
5153
- source: node_modules/altcha/dist_external

0 commit comments

Comments
 (0)