updated frame for mobile
This commit is contained in:
@@ -1135,6 +1135,7 @@
|
|||||||
--frame-base-gap: clamp(2px, 0.3vw, 6px);
|
--frame-base-gap: clamp(2px, 0.3vw, 6px);
|
||||||
--frame-gap: calc(var(--frame-base-gap) * var(--frame-grid-zoom-scale));
|
--frame-gap: calc(var(--frame-base-gap) * var(--frame-grid-zoom-scale));
|
||||||
display: grid;
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr);
|
||||||
gap: 14px;
|
gap: 14px;
|
||||||
padding: 18px;
|
padding: 18px;
|
||||||
border: 1px solid #27272a;
|
border: 1px solid #27272a;
|
||||||
@@ -1152,7 +1153,8 @@
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
min-width: max-content;
|
min-width: 0;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tarot-frame-panel-title {
|
.tarot-frame-panel-title {
|
||||||
@@ -1183,8 +1185,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tarot-frame-grid-viewport {
|
.tarot-frame-grid-viewport {
|
||||||
width: 100%;
|
width: min(100%, calc(100vw - 52px));
|
||||||
max-width: 100%;
|
max-width: calc(100vw - 52px);
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
overscroll-behavior: contain;
|
overscroll-behavior: contain;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
@@ -1481,7 +1485,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.tarot-frame-panel {
|
.tarot-frame-panel {
|
||||||
--frame-base-cell-width: 26px;
|
--frame-base-gap: 2px;
|
||||||
|
--frame-base-cell-width: min(26px, calc((100vw - 78px) / 14));
|
||||||
}
|
}
|
||||||
|
|
||||||
.tarot-frame-card-badge {
|
.tarot-frame-card-badge {
|
||||||
|
|||||||
@@ -991,7 +991,46 @@
|
|||||||
return getCardOverlayDate(card) || formatMonthDay(getRelation(card, "decan")?.data?.dateStart) || getDisplayCardName(card);
|
return getCardOverlayDate(card) || formatMonthDay(getRelation(card, "decan")?.data?.dateStart) || getDisplayCardName(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
function centerGridViewport() {
|
function getOccupiedGridBounds(gridTrackEl) {
|
||||||
|
if (!(gridTrackEl instanceof HTMLElement)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filledSlots = Array.from(gridTrackEl.querySelectorAll(".tarot-frame-slot:not(.is-empty-slot)"));
|
||||||
|
if (!filledSlots.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const trackRect = gridTrackEl.getBoundingClientRect();
|
||||||
|
return filledSlots.reduce((bounds, slotEl) => {
|
||||||
|
if (!(slotEl instanceof HTMLElement)) {
|
||||||
|
return bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
const slotRect = slotEl.getBoundingClientRect();
|
||||||
|
const left = slotRect.left - trackRect.left;
|
||||||
|
const right = slotRect.right - trackRect.left;
|
||||||
|
if (!bounds) {
|
||||||
|
return { left, right };
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
left: Math.min(bounds.left, left),
|
||||||
|
right: Math.max(bounds.right, right)
|
||||||
|
};
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetFrameSectionScroll() {
|
||||||
|
const sectionEl = document.getElementById("tarot-frame-section");
|
||||||
|
if (!(sectionEl instanceof HTMLElement)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sectionEl.scrollTop = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function centerGridViewport(attempt = 0) {
|
||||||
const { tarotFrameBoardEl } = getElements();
|
const { tarotFrameBoardEl } = getElements();
|
||||||
const gridViewportEl = tarotFrameBoardEl?.querySelector(".tarot-frame-grid-viewport");
|
const gridViewportEl = tarotFrameBoardEl?.querySelector(".tarot-frame-grid-viewport");
|
||||||
const gridTrackEl = tarotFrameBoardEl?.querySelector(".tarot-frame-grid-track");
|
const gridTrackEl = tarotFrameBoardEl?.querySelector(".tarot-frame-grid-track");
|
||||||
@@ -1004,16 +1043,44 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const overflowX = Math.max(0, gridTrackEl.offsetWidth - gridViewportEl.clientWidth);
|
const contentWidth = gridTrackEl.scrollWidth || gridTrackEl.offsetWidth;
|
||||||
gridViewportEl.scrollLeft = overflowX > 0 ? overflowX / 2 : 0;
|
const viewportWidth = gridViewportEl.clientWidth;
|
||||||
|
if (!contentWidth || !viewportWidth) {
|
||||||
|
if (attempt < 6) {
|
||||||
|
centerGridViewport(attempt + 1);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const occupiedBounds = getOccupiedGridBounds(gridTrackEl);
|
||||||
|
const targetCenter = occupiedBounds
|
||||||
|
? (occupiedBounds.left + occupiedBounds.right) / 2
|
||||||
|
: contentWidth / 2;
|
||||||
|
const maxScrollLeft = Math.max(0, contentWidth - viewportWidth);
|
||||||
|
const targetScrollLeft = Math.min(Math.max(targetCenter - (viewportWidth / 2), 0), maxScrollLeft);
|
||||||
|
gridViewportEl.scrollLeft = targetScrollLeft;
|
||||||
|
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
if (!(gridViewportEl instanceof HTMLElement) || !(gridTrackEl instanceof HTMLElement)) {
|
if (!(gridViewportEl instanceof HTMLElement) || !(gridTrackEl instanceof HTMLElement)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const nextOverflowX = Math.max(0, gridTrackEl.offsetWidth - gridViewportEl.clientWidth);
|
const nextContentWidth = gridTrackEl.scrollWidth || gridTrackEl.offsetWidth;
|
||||||
gridViewportEl.scrollLeft = nextOverflowX > 0 ? nextOverflowX / 2 : 0;
|
const nextViewportWidth = gridViewportEl.clientWidth;
|
||||||
|
if (!nextContentWidth || !nextViewportWidth) {
|
||||||
|
if (attempt < 6) {
|
||||||
|
centerGridViewport(attempt + 1);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextOccupiedBounds = getOccupiedGridBounds(gridTrackEl);
|
||||||
|
const nextTargetCenter = nextOccupiedBounds
|
||||||
|
? (nextOccupiedBounds.left + nextOccupiedBounds.right) / 2
|
||||||
|
: nextContentWidth / 2;
|
||||||
|
const nextMaxScrollLeft = Math.max(0, nextContentWidth - nextViewportWidth);
|
||||||
|
const nextTargetScrollLeft = Math.min(Math.max(nextTargetCenter - (nextViewportWidth / 2), 0), nextMaxScrollLeft);
|
||||||
|
gridViewportEl.scrollLeft = nextTargetScrollLeft;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2061,6 +2128,8 @@
|
|||||||
await config.ensureTarotSection(referenceData, magickDataset);
|
await config.ensureTarotSection(referenceData, magickDataset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetFrameSectionScroll();
|
||||||
|
|
||||||
const cards = getCards();
|
const cards = getCards();
|
||||||
if (!cards.length) {
|
if (!cards.length) {
|
||||||
setStatus("Tarot cards are still loading...");
|
setStatus("Tarot cards are still loading...");
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<link rel="stylesheet" href="node_modules/@fontsource/amiri/arabic-400.css">
|
<link rel="stylesheet" href="node_modules/@fontsource/amiri/arabic-400.css">
|
||||||
<link rel="stylesheet" href="node_modules/@fontsource/amiri/arabic-700.css">
|
<link rel="stylesheet" href="node_modules/@fontsource/amiri/arabic-700.css">
|
||||||
<link rel="stylesheet" href="node_modules/@fontsource/noto-naskh-arabic/arabic-400.css">
|
<link rel="stylesheet" href="node_modules/@fontsource/noto-naskh-arabic/arabic-400.css">
|
||||||
<link rel="stylesheet" href="app/styles.css?v=20260402-frame-center-05">
|
<link rel="stylesheet" href="app/styles.css?v=20260402-frame-center-07">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="topbar">
|
<div class="topbar">
|
||||||
@@ -1178,7 +1178,7 @@
|
|||||||
<script src="app/ui-numbers-detail.js"></script>
|
<script src="app/ui-numbers-detail.js"></script>
|
||||||
<script src="app/ui-numbers.js"></script>
|
<script src="app/ui-numbers.js"></script>
|
||||||
<script src="app/ui-tarot-spread.js"></script>
|
<script src="app/ui-tarot-spread.js"></script>
|
||||||
<script src="app/ui-tarot-frame.js?v=20260402-frame-center-05"></script>
|
<script src="app/ui-tarot-frame.js?v=20260402-frame-mobile-center-06"></script>
|
||||||
<script src="app/ui-settings.js?v=20260309-gate"></script>
|
<script src="app/ui-settings.js?v=20260309-gate"></script>
|
||||||
<script src="app/ui-chrome.js?v=20260328-topbar-settings-01"></script>
|
<script src="app/ui-chrome.js?v=20260328-topbar-settings-01"></script>
|
||||||
<script src="app/ui-navigation.js?v=20260401-tarot-frame-01"></script>
|
<script src="app/ui-navigation.js?v=20260401-tarot-frame-01"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user