Rebuild the UI in an Apple style with spring-driven motion
Replace the look of every page (key, lobby, create, table, range, review) with light/dark semantic colors, translucent materials, iOS-style grouped lists and system typography. Add fluid.js, a small spring engine with interruptible, velocity-aware animations, and use it for draggable bottom sheets, sliding segmented controls, a custom bet slider with rubber-banding, swipe-to-delete in the lobby, and dealt/flipped cards. Seats and cards are now reused between renders so animations are not cut off. Honors reduced motion, reduced transparency and increased contrast. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d5ef2d310f
commit
c3fbfdd12e
18 files changed
+4877
-1278
No files matched your search
+10
-2
@@ -5,6 +5,10 @@
|
||||
const $ = (id) => document.getElementById(id);
|
||||
const { RANKS, CATEGORIES, FACING_ACTIONS, handAt, categoryOf, labelOf, facingOf, facingAction } = window.HandRange;
|
||||
|
||||
Fluid.navBar($('nav'), $('large-title'));
|
||||
const tabsSeg = Fluid.Segmented($('tabs'));
|
||||
Fluid.Segmented($('count'));
|
||||
|
||||
function swatch(id) {
|
||||
const s = document.createElement('span');
|
||||
s.className = `swatch-dot cat-${id}`;
|
||||
@@ -22,7 +26,8 @@
|
||||
function showView(name) {
|
||||
$('view-range').hidden = name !== 'range';
|
||||
$('view-quiz').hidden = name !== 'quiz';
|
||||
for (const b of $('tabs').children) b.classList.toggle('active', b.dataset.view === name);
|
||||
for (const b of $('tabs').querySelectorAll('[data-view]')) b.classList.toggle('active', b.dataset.view === name);
|
||||
tabsSeg.update();
|
||||
}
|
||||
$('tabs').addEventListener('click', (e) => {
|
||||
const b = e.target.closest('[data-view]');
|
||||
@@ -99,7 +104,7 @@
|
||||
const b = e.target.closest('[data-count]');
|
||||
if (!b) return;
|
||||
quizCount = Number(b.dataset.count);
|
||||
for (const x of $('count').children) x.classList.toggle('active', x === b);
|
||||
for (const x of $('count').querySelectorAll('[data-count]')) x.classList.toggle('active', x === b);
|
||||
});
|
||||
|
||||
function shuffle(a) {
|
||||
@@ -186,6 +191,9 @@
|
||||
fb.className = `quiz-feedback ${ok ? 'good' : 'bad'}`;
|
||||
fb.textContent = `${ok ? '正解!' : '不正解'} ${hand} は「${labelOf(right)}」です。`;
|
||||
fb.hidden = false;
|
||||
// 間違えたら選んだボタンが揺れる(振動と同じ瞬間に)
|
||||
if (!ok) Fluid.shake(button);
|
||||
Fluid.haptic(ok ? 10 : [18, 50, 18]);
|
||||
updateStats();
|
||||
$('next-question').disabled = false;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user