updated card images

This commit is contained in:
2026-04-24 00:38:44 -07:00
parent a129f0db6a
commit 5744edadb9
6 changed files with 225 additions and 18 deletions
+22 -9
View File
@@ -22,6 +22,7 @@
getWallFaceLetter,
getWallTarotCard,
resolveCardImageUrl,
openTarotCardInfo,
openTarotCardLightbox,
MOTHER_CONNECTORS,
formatDirectionName,
@@ -48,6 +49,18 @@
svg.setAttribute("role", "img");
svg.setAttribute("aria-label", "Cube of Space interactive chassis");
function openTarotTarget(cardName, fallbackSrc, fallbackLabel) {
if (typeof openTarotCardInfo === "function" && openTarotCardInfo(cardName) === true) {
return true;
}
if (typeof openTarotCardLightbox === "function") {
return openTarotCardLightbox(cardName, fallbackSrc, fallbackLabel);
}
return false;
}
const wallById = new Map(walls.map((wall) => [normalizeId(wall?.id), wall]));
const projectedVertices = projectVertices();
const faces = Object.entries(FACE_GEOMETRY)
@@ -144,14 +157,14 @@
cardImg.addEventListener("click", (event) => {
event.stopPropagation();
selectWall();
openTarotCardLightbox(wallTarotCard, cardUrl, `${wall?.name || wallId} wall tarot card`);
openTarotTarget(wallTarotCard, cardUrl, `${wall?.name || wallId} wall tarot card`);
});
cardImg.addEventListener("keydown", (event) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
event.stopPropagation();
selectWall();
openTarotCardLightbox(wallTarotCard, cardUrl, `${wall?.name || wallId} wall tarot card`);
openTarotTarget(wallTarotCard, cardUrl, `${wall?.name || wallId} wall tarot card`);
}
});
svg.appendChild(cardImg);
@@ -263,14 +276,14 @@
connectorImg.addEventListener("click", (event) => {
event.stopPropagation();
selectConnector();
openTarotCardLightbox(connectorTarotCard, connectorCardUrl, connector?.name || "Mother connector");
openTarotTarget(connectorTarotCard, connectorCardUrl, connector?.name || "Mother connector");
});
connectorImg.addEventListener("keydown", (event) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
event.stopPropagation();
selectConnector();
openTarotCardLightbox(connectorTarotCard, connectorCardUrl, connector?.name || "Mother connector");
openTarotTarget(connectorTarotCard, connectorCardUrl, connector?.name || "Mother connector");
}
});
group.appendChild(connectorImg);
@@ -336,7 +349,7 @@
const selectEdge = () => {
state.selectedEdgeId = edgeId;
state.selectedNodeType = "wall";
state.selectedNodeType = "edge";
state.selectedConnectorId = null;
if (!edgeWalls.includes(normalizeId(state.selectedWallId)) && edgeWalls[0]) {
state.selectedWallId = edgeWalls[0];
@@ -399,14 +412,14 @@
cardImg.addEventListener("click", (event) => {
event.stopPropagation();
selectEdge();
openTarotCardLightbox(edgeTarotCard, edgeCardUrl, edge?.name || "Cube edge");
openTarotTarget(edgeTarotCard, edgeCardUrl, edge?.name || "Cube edge");
});
cardImg.addEventListener("keydown", (event) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
event.stopPropagation();
selectEdge();
openTarotCardLightbox(edgeTarotCard, edgeCardUrl, edge?.name || "Cube edge");
openTarotTarget(edgeTarotCard, edgeCardUrl, edge?.name || "Cube edge");
}
});
marker.appendChild(cardImg);
@@ -486,7 +499,7 @@
state.selectedNodeType = "center";
state.selectedConnectorId = null;
render(getElements());
openTarotCardLightbox(centerTarotCard, centerCardUrl, "Primal Point");
openTarotTarget(centerTarotCard, centerCardUrl, "Primal Point");
});
centerImg.addEventListener("keydown", (event) => {
if (event.key === "Enter" || event.key === " ") {
@@ -495,7 +508,7 @@
state.selectedNodeType = "center";
state.selectedConnectorId = null;
render(getElements());
openTarotCardLightbox(centerTarotCard, centerCardUrl, "Primal Point");
openTarotTarget(centerTarotCard, centerCardUrl, "Primal Point");
}
});
centerMarker.appendChild(centerImg);
+141
View File
@@ -520,6 +520,143 @@
renderEdgeCard(context, wall, bodyEl, wallEdgeDirections);
}
function renderEdgeDetail(context) {
const {
state,
elements,
normalizeId,
normalizeEdgeId,
formatEdgeName,
getWallById,
getEdgeById,
getEdges,
getEdgeWalls,
getEdgeLetterId,
getEdgeLetter,
getEdgePathEntry,
getEdgeAstrologySymbol,
getHebrewLetterName,
toFiniteNumber,
onSelectWall
} = context;
const edge = getEdgeById(state.selectedEdgeId) || getEdges()[0] || null;
if (!edge || !elements?.detailNameEl || !elements?.detailSubEl || !elements?.detailBodyEl) {
return false;
}
const edgeId = normalizeEdgeId(edge.id);
const edgeWalls = getEdgeWalls(edge);
const currentWallId = normalizeId(state.selectedWallId);
const preferredWallId = edgeWalls.includes(currentWallId)
? currentWallId
: normalizeId(edgeWalls[0]);
if (preferredWallId) {
state.selectedWallId = preferredWallId;
}
state.selectedEdgeId = edgeId;
const wallNames = edgeWalls
.map((wallId) => getWallById(wallId)?.name || wallId)
.filter(Boolean)
.join(" ↔ ");
const edgeName = toDisplayText(edge?.name) || formatEdgeName(edgeId);
const edgeLetterId = getEdgeLetterId(edge);
const edgeLetter = getEdgeLetter(edge);
const edgeLetterName = edgeLetterId ? (getHebrewLetterName(edgeLetterId) || edgeLetterId) : "";
const edgeLetterText = edgeLetterId
? [edgeLetter, edgeLetterName].filter(Boolean).join(" ")
: "";
const edgePath = getEdgePathEntry(edge);
const astrologyType = toDisplayText(edgePath?.astrology?.type);
const astrologyName = toDisplayText(edgePath?.astrology?.name);
const astrologySymbol = getEdgeAstrologySymbol(edge);
const astrologyText = astrologySymbol && astrologyName
? `${astrologySymbol} ${astrologyName}`
: astrologySymbol || astrologyName;
const tarotCard = toDisplayText(edgePath?.tarot?.card);
const tarotTrumpNumber = toFiniteNumber(edgePath?.tarot?.trumpNumber);
const pathNo = toFiniteNumber(edgePath?.pathNumber);
elements.detailNameEl.textContent = `${edgeName} Edge`;
elements.detailSubEl.textContent = [edgeLetterText, astrologyText].filter(Boolean).join(" · ") || "Cube Edge";
const bodyEl = elements.detailBodyEl;
bodyEl.innerHTML = "";
const summary = document.createElement("div");
summary.className = "planet-text";
summary.innerHTML = `
<dl class="alpha-dl">
<dt>Name</dt><dd>${toDetailValueMarkup(edgeName)}</dd>
<dt>Between</dt><dd>${toDetailValueMarkup(wallNames)}</dd>
<dt>Letter</dt><dd>${toDetailValueMarkup(edgeLetterText)}</dd>
<dt>Astrology</dt><dd>${toDetailValueMarkup(astrologyText)}</dd>
<dt>Tarot</dt><dd>${toDetailValueMarkup(tarotCard || (tarotTrumpNumber != null ? `Trump ${tarotTrumpNumber}` : ""))}</dd>
<dt>Path</dt><dd>${toDetailValueMarkup(pathNo != null ? `Path ${pathNo}` : "")}</dd>
</dl>
`;
bodyEl.appendChild(createMetaCard("Edge Details", summary));
if (Array.isArray(edge?.keywords) && edge.keywords.length) {
bodyEl.appendChild(createMetaCard("Keywords", edge.keywords.join(", ")));
}
if (edge?.description) {
bodyEl.appendChild(createMetaCard("Description", edge.description));
}
const linksCard = document.createElement("div");
linksCard.className = "planet-meta-card";
linksCard.innerHTML = "<strong>Correspondence Links</strong>";
const links = document.createElement("div");
links.className = "kab-god-links";
edgeWalls.forEach((wallId) => {
const wall = getWallById(wallId);
const button = document.createElement("button");
button.type = "button";
button.className = "kab-god-link";
button.textContent = `${wall?.name || wallId} Wall`;
button.addEventListener("click", () => {
onSelectWall(wallId);
});
links.appendChild(button);
});
if (edgeLetterId) {
links.appendChild(createNavButton(edgeLetter || "!", "nav:alphabet", {
alphabet: "hebrew",
hebrewLetterId: edgeLetterId
}));
}
if (astrologyType === "zodiac" && astrologyName) {
links.appendChild(createNavButton(astrologyName, "nav:zodiac", {
signId: normalizeId(astrologyName)
}));
}
if (tarotCard || tarotTrumpNumber != null) {
links.appendChild(createNavButton(tarotCard || `Trump ${tarotTrumpNumber}`, "nav:tarot-trump", {
cardName: tarotCard,
trumpNumber: tarotTrumpNumber
}));
}
if (pathNo != null) {
links.appendChild(createNavButton(`Path ${pathNo}`, "nav:kabbalah-path", { pathNo }));
}
if (links.childElementCount) {
linksCard.appendChild(links);
bodyEl.appendChild(linksCard);
}
return true;
}
function renderDetail(context) {
if (context.state.selectedNodeType === "connector" && renderConnectorDetail(context)) {
return;
@@ -529,6 +666,10 @@
return;
}
if (context.state.selectedNodeType === "edge" && renderEdgeDetail(context)) {
return;
}
renderWallDetail(context);
}
+3 -2
View File
@@ -38,9 +38,10 @@
const resolvedEdgeId = candidateEdgeId && getEdgeById(candidateEdgeId)
? candidateEdgeId
: normalizeEdgeId(wallEdges[0]?.id || getEdges()[0]?.id);
const wantsEdgeDetail = Boolean(candidateEdgeId) || normalizeId(placement?.nodeType) === "edge";
state.selectedEdgeId = resolvedEdgeId;
state.selectedNodeType = "wall";
state.selectedNodeType = wantsEdgeDetail ? "edge" : "wall";
state.selectedConnectorId = null;
render(getElements());
return true;
@@ -60,7 +61,7 @@
: (edgeWalls.includes(currentWallId) ? currentWallId : (edgeWalls[0] || currentWallId));
state.selectedEdgeId = normalizeEdgeId(edge.id);
state.selectedNodeType = "wall";
state.selectedNodeType = "edge";
state.selectedConnectorId = null;
if (nextWallId) {
+22
View File
@@ -814,6 +814,27 @@
return window.TarotCardImages.resolveTarotCardImage(name) || null;
}
function openTarotCardInfo(cardName, trumpNumber = null) {
const detail = {};
const normalizedCardName = toDisplayText(cardName);
const normalizedTrumpNumber = toFiniteNumber(trumpNumber);
if (normalizedCardName) {
detail.cardName = normalizedCardName;
}
if (normalizedTrumpNumber != null) {
detail.trumpNumber = normalizedTrumpNumber;
}
if (!detail.cardName && detail.trumpNumber == null) {
return false;
}
document.dispatchEvent(new CustomEvent("nav:tarot-trump", { detail }));
return true;
}
function openTarotCardLightbox(cardName, fallbackSrc = "", fallbackLabel = "") {
const openLightbox = window.TarotUiLightbox?.open;
if (typeof openLightbox !== "function") {
@@ -867,6 +888,7 @@
getWallFaceLetter,
getWallTarotCard,
resolveCardImageUrl,
openTarotCardInfo,
openTarotCardLightbox,
MOTHER_CONNECTORS,
formatDirectionName,
+32 -2
View File
@@ -5607,12 +5607,42 @@
function loadCardImage(src) {
return new Promise((resolve) => {
const normalizedSrc = String(src || "").trim();
if (!normalizedSrc) {
resolve(null);
return;
}
const ensureLoaded = window.TarotCardImages?.ensureImageLoaded;
const attachImageFallback = () => {
const image = new Image();
image.decoding = "async";
image.onload = () => resolve(image);
image.onerror = () => resolve(null);
image.src = normalizedSrc;
};
if (typeof ensureLoaded === "function") {
Promise.resolve(ensureLoaded(normalizedSrc))
.then((cachedImage) => {
if (cachedImage?.naturalWidth) {
resolve(cachedImage);
return;
}
attachImageFallback();
})
.catch(() => {
attachImageFallback();
});
return;
}
const image = new Image();
image.crossOrigin = "anonymous";
image.decoding = "async";
image.onload = () => resolve(image);
image.onerror = () => resolve(null);
image.src = src;
image.src = normalizedSrc;
});
}
+5 -5
View File
@@ -1218,11 +1218,11 @@
<script src="app/ui-kabbalah-detail.js"></script>
<script src="app/ui-kabbalah-views.js"></script>
<script src="app/ui-kabbalah.js?v=20260312-tree-export-01"></script>
<script src="app/ui-cube-detail.js"></script>
<script src="app/ui-cube-chassis.js"></script>
<script src="app/ui-cube-detail.js?v=20260424-cube-fixes-01"></script>
<script src="app/ui-cube-chassis.js?v=20260424-cube-fixes-01"></script>
<script src="app/ui-cube-math.js"></script>
<script src="app/ui-cube-selection.js"></script>
<script src="app/ui-cube.js?v=20260312-house-cube-01"></script>
<script src="app/ui-cube-selection.js?v=20260424-cube-fixes-01"></script>
<script src="app/ui-cube.js?v=20260424-cube-fixes-01"></script>
<script src="app/ui-alphabet-gematria.js?v=20260323-word-meta-01"></script>
<script src="app/ui-alphabet-browser.js?v=20260309-enochian-api"></script>
<script src="app/ui-alphabet-references.js"></script>
@@ -1245,7 +1245,7 @@
<script src="app/ui-numbers-detail.js"></script>
<script src="app/ui-numbers.js"></script>
<script src="app/ui-tarot-spread.js"></script>
<script src="app/ui-tarot-frame.js?v=20260408-frame-flip-04"></script>
<script src="app/ui-tarot-frame.js?v=20260424-frame-export-01"></script>
<script src="app/ui-settings.js?v=20260415-stellarium-toggle-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>