Skip to content

Commit bfb4841

Browse files
committed
Fix mobile course slide gestures
1 parent 541e407 commit bfb4841

3 files changed

Lines changed: 86 additions & 5 deletions

File tree

‎assets/course-pages.css‎

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
--rose: #bd4d68;
1414
--dark: #101b18;
1515
}
16-
html, body { margin: 0; min-height: 100%; }
16+
html, body { margin: 0; min-height: 100%; overflow-x: hidden; }
1717
body {
1818
font-family: -apple-system, BlinkMacSystemFont, "Noto Sans TC", "Microsoft JhengHei", "Segoe UI", sans-serif;
1919
background:
@@ -34,13 +34,15 @@ a { color: inherit; }
3434
overflow-y: auto;
3535
overscroll-behavior: contain;
3636
scroll-padding: 72px 0 88px;
37+
-webkit-overflow-scrolling: touch;
38+
touch-action: pan-y;
3739
}
3840
.slide.active { display: flex; animation: enter 0.25s ease; }
3941
@keyframes enter {
4042
from { opacity: 0; transform: translateY(10px); }
4143
to { opacity: 1; transform: translateY(0); }
4244
}
43-
.inner { width: min(1180px, 100%); margin: auto; }
45+
.inner { width: min(1180px, 100%); min-width: 0; margin: auto; }
4446
.kicker {
4547
display: inline-flex;
4648
align-items: center;
@@ -66,13 +68,17 @@ h1 {
6668
line-height: 1.1;
6769
letter-spacing: 0;
6870
font-weight: 850;
71+
overflow-wrap: anywhere;
72+
word-break: break-word;
6973
}
7074
h2 {
7175
font-size: clamp(30px, 4.2vw, 52px);
7276
line-height: 1.18;
7377
letter-spacing: 0;
7478
font-weight: 820;
7579
margin-bottom: 22px;
80+
overflow-wrap: anywhere;
81+
word-break: break-word;
7682
}
7783
h3 { font-size: clamp(18px, 2vw, 24px); line-height: 1.35; margin-bottom: 10px; }
7884
p, li { color: var(--muted); font-size: clamp(15px, 1.35vw, 19px); line-height: 1.75; }
@@ -260,8 +266,17 @@ textarea { min-height: 70px; resize: vertical; }
260266
@media (max-width: 860px) {
261267
body { overflow: auto; }
262268
.deck { height: auto; min-height: 100vh; }
263-
.slide { position: relative; min-height: 100vh; padding: 70px 20px 86px; }
269+
.slide {
270+
position: relative;
271+
min-height: 100vh;
272+
padding: 70px 20px 86px;
273+
overflow: visible;
274+
}
275+
.slide.active { display: block; }
264276
.slide:not(.active) { display: none; }
277+
.inner { width: min(100%, 520px); margin: 0 auto; }
278+
h1 { width: 100%; font-size: 32px; line-height: 1.18; word-break: break-all; }
279+
h2 { width: 100%; font-size: 30px; line-height: 1.22; word-break: break-all; }
265280
.grid, .grid.two, .form-grid { grid-template-columns: 1fr; }
266281
.dots { display: none; }
267282
}

‎assets/course-pages.js‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ function show(index) {
2020
slides[current].scrollTop = 0;
2121
slides[current].scrollLeft = 0;
2222
}
23+
window.scrollTo(0, 0);
2324
if (dots) dots.querySelectorAll(".dot").forEach((dot, i) => dot.classList.toggle("active", i === current));
2425
if (counter) counter.textContent = (current + 1) + " / " + slides.length;
2526
}
@@ -53,4 +54,28 @@ document.addEventListener("keydown", event => {
5354
}
5455
});
5556

57+
let touchStartX = 0;
58+
let touchStartY = 0;
59+
let touchStartedOnControl = false;
60+
61+
document.addEventListener("touchstart", event => {
62+
const touch = event.changedTouches[0];
63+
if (!touch) return;
64+
touchStartedOnControl = Boolean(event.target?.closest?.("a, button, input, textarea, select"));
65+
touchStartX = touch.clientX;
66+
touchStartY = touch.clientY;
67+
}, { passive: true });
68+
69+
document.addEventListener("touchend", event => {
70+
if (touchStartedOnControl) return;
71+
const touch = event.changedTouches[0];
72+
if (!touch) return;
73+
const deltaX = touch.clientX - touchStartX;
74+
const deltaY = touch.clientY - touchStartY;
75+
const isHorizontalSwipe = Math.abs(deltaX) > 56 && Math.abs(deltaX) > Math.abs(deltaY) * 1.25;
76+
if (!isHorizontalSwipe) return;
77+
if (deltaX < 0) show(current + 1);
78+
if (deltaX > 0) show(current - 1);
79+
}, { passive: true });
80+
5681
show(0);

‎course.html‎

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
--shadow: 0 18px 50px rgba(24, 49, 43, 0.14);
2626
}
2727
* { box-sizing: border-box; }
28-
html, body { margin: 0; min-height: 100%; }
28+
html, body { margin: 0; min-height: 100%; overflow-x: hidden; }
2929
body {
3030
font-family: -apple-system, BlinkMacSystemFont, "Noto Sans TC", "Microsoft JhengHei", "Segoe UI", sans-serif;
3131
background: var(--bg);
@@ -51,6 +51,8 @@
5151
overflow-y: auto;
5252
overscroll-behavior: contain;
5353
scroll-padding: 72px 0 88px;
54+
-webkit-overflow-scrolling: touch;
55+
touch-action: pan-y;
5456
}
5557
.slide.active { display: flex; animation: in 0.28s ease; }
5658
@keyframes in {
@@ -59,6 +61,7 @@
5961
}
6062
.slide-inner {
6163
width: min(1180px, 100%);
64+
min-width: 0;
6265
margin: auto;
6366
}
6467
.kicker {
@@ -86,13 +89,17 @@
8689
line-height: 1.08;
8790
letter-spacing: 0;
8891
font-weight: 850;
92+
overflow-wrap: anywhere;
93+
word-break: break-word;
8994
}
9095
h2 {
9196
font-size: clamp(30px, 4.2vw, 54px);
9297
line-height: 1.16;
9398
letter-spacing: 0;
9499
font-weight: 820;
95100
margin-bottom: 22px;
101+
overflow-wrap: anywhere;
102+
word-break: break-word;
96103
}
97104
h3 {
98105
font-size: clamp(18px, 2vw, 24px);
@@ -417,8 +424,17 @@
417424
@media (max-width: 850px) {
418425
body { overflow: auto; }
419426
.deck { height: auto; min-height: 100vh; }
420-
.slide { position: relative; min-height: 100vh; padding: 70px 22px 84px; }
427+
.slide {
428+
position: relative;
429+
min-height: 100vh;
430+
padding: 70px 22px 84px;
431+
overflow: visible;
432+
}
433+
.slide.active { display: block; }
421434
.slide:not(.active) { display: none; }
435+
.slide-inner { width: min(100%, 520px); margin: 0 auto; }
436+
h1 { width: 100%; font-size: 32px; line-height: 1.18; word-break: break-all; }
437+
h2 { width: 100%; font-size: 30px; line-height: 1.22; word-break: break-all; }
422438
.grid, .grid.two, .timeline, .tool-board, .worksheet { grid-template-columns: 1fr; }
423439
.day { border-right: 0; border-bottom: 1px solid var(--line); min-height: auto; }
424440
.day:last-child { border-bottom: 0; }
@@ -732,6 +748,7 @@ <h2>從會使用 AI,到會設計 AI 協作</h2>
732748
slides[current].scrollTop = 0;
733749
slides[current].scrollLeft = 0;
734750
}
751+
window.scrollTo(0, 0);
735752
dots.querySelectorAll(".dot").forEach((dot, i) => dot.classList.toggle("active", i === current));
736753
counter.textContent = (current + 1) + " / " + slides.length;
737754
}
@@ -765,6 +782,30 @@ <h2>從會使用 AI,到會設計 AI 協作</h2>
765782
}
766783
});
767784

785+
let touchStartX = 0;
786+
let touchStartY = 0;
787+
let touchStartedOnControl = false;
788+
789+
document.addEventListener("touchstart", event => {
790+
const touch = event.changedTouches[0];
791+
if (!touch) return;
792+
touchStartedOnControl = Boolean(event.target?.closest?.("a, button, input, textarea, select"));
793+
touchStartX = touch.clientX;
794+
touchStartY = touch.clientY;
795+
}, { passive: true });
796+
797+
document.addEventListener("touchend", event => {
798+
if (touchStartedOnControl) return;
799+
const touch = event.changedTouches[0];
800+
if (!touch) return;
801+
const deltaX = touch.clientX - touchStartX;
802+
const deltaY = touch.clientY - touchStartY;
803+
const isHorizontalSwipe = Math.abs(deltaX) > 56 && Math.abs(deltaX) > Math.abs(deltaY) * 1.25;
804+
if (!isHorizontalSwipe) return;
805+
if (deltaX < 0) show(current + 1);
806+
if (deltaX > 0) show(current - 1);
807+
}, { passive: true });
808+
768809
document.querySelectorAll(".layer").forEach(layer => {
769810
layer.addEventListener("click", () => {
770811
document.querySelectorAll(".layer").forEach(item => item.classList.remove("active"));

0 commit comments

Comments
 (0)