This commit is contained in:
cay 2026-04-11 12:37:10 +01:00
parent efb8589a61
commit 06eebb345d
2 changed files with 114 additions and 5 deletions

View File

@ -4,7 +4,7 @@ let currentGroupId = null;
let currentPage = 1;
let currentDeckId = null;
let deckCards = []; // [{card_id, amount}]
let userCardsCache = []; // aktuelle Seite: [{card_id, amount, name, image, rarity, attack, defense}]
let userCardsCache = []; // aktuelle Seite: [{card_id, amount, name, image, rarity, attack, defense, range, race}]
let decks = []; // [{id, name}]
/* ── Kristall-Mapping ───────────────────────── */
@ -26,6 +26,28 @@ function rarityImgs(rarity, size = 14) {
return img.repeat(count);
}
/* ── Stat-Icons ─────────────────────────────── */
function rangeIcon() {
return `<svg viewBox="0 0 16 16" width="11" height="11" style="display:inline;vertical-align:middle;flex-shrink:0" fill="none" stroke="#e8b84b" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 2 Q1 8 4 14"/>
<line x1="4" y1="2" x2="4" y2="14" stroke-width="0.7" stroke-dasharray="2,1.5"/>
<line x1="4" y1="8" x2="13" y2="8"/>
<polyline points="11,6 13,8 11,10"/>
<line x1="5" y1="7" x2="4" y2="8"/><line x1="5" y1="9" x2="4" y2="8"/>
</svg>`;
}
function raceIcon() {
return `<svg viewBox="0 0 16 16" width="11" height="11" style="display:inline;vertical-align:middle;flex-shrink:0" fill="none" stroke="#7de87d" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
<circle cx="9" cy="2.5" r="1.4" fill="#7de87d" stroke="none"/>
<line x1="9" y1="4" x2="8" y2="9"/>
<line x1="8" y1="9" x2="10" y2="14"/>
<line x1="8" y1="9" x2="6" y2="13"/>
<line x1="8.5" y1="5.5" x2="11" y2="8"/>
<line x1="8.5" y1="5.5" x2="6" y2="7"/>
</svg>`;
}
/*
INIT
*/
@ -439,6 +461,40 @@ function renderShell() {
}
.kd-deck-count-indeck { font-family: "Cinzel", serif; font-size: 13px; color: #000; font-weight: bold; text-shadow: 0 0 3px rgba(255,255,255,0.6); }
/* ── Reichweite & Laufen Badges ────────── */
.kd-range-race {
position: absolute;
bottom: 20px;
left: 0; right: 0;
display: flex;
justify-content: center;
gap: 4px;
padding: 0 3px;
pointer-events: none;
z-index: 6;
}
.kd-badge-range, .kd-badge-race {
display: flex;
align-items: center;
gap: 2px;
padding: 1px 4px;
border-radius: 20px;
font-family: "Cinzel", serif;
font-size: 9px;
font-weight: bold;
line-height: 1;
}
.kd-badge-range {
background: rgba(30,20,0,0.82);
border: 1px solid #e8b84b;
color: #e8b84b;
}
.kd-badge-race {
background: rgba(0,25,0,0.82);
border: 1px solid #7de87d;
color: #7de87d;
}
/* ── Rarity Kristalle ───────────────────── */
.kd-rarity {
position: absolute;
@ -772,6 +828,11 @@ function renderCollectionGrid(grid, cards) {
<span class="kd-count-owned" title="Besitzt du">× ${c.amount}</span>
</div>
${c.rarity ? `<div class="kd-rarity">${rarityImgs(c.rarity, 13)}</div>` : ""}
${(c.range != null || c.race != null) ? `
<div class="kd-range-race">
${c.range != null ? `<span class="kd-badge-range">${rangeIcon()}&thinsp;${c.range}</span>` : ""}
${c.race != null ? `<span class="kd-badge-race">${raceIcon()}&thinsp;${c.race}</span>` : ""}
</div>` : ""}
</div>`;
})
.join("");
@ -808,6 +869,11 @@ function renderDeckGrid(grid, cards) {
<span class="kd-deck-count-indeck" title="Im Deck">🃏 ${c.amount}</span>
</div>
${c.rarity ? `<div class="kd-rarity" style="top:75%">${rarityImgs(c.rarity, 14)}</div>` : ""}
${(c.range != null || c.race != null) ? `
<div class="kd-range-race">
${c.range != null ? `<span class="kd-badge-range">${rangeIcon()}&thinsp;${c.range}</span>` : ""}
${c.race != null ? `<span class="kd-badge-race">${raceIcon()}&thinsp;${c.race}</span>` : ""}
</div>` : ""}
</div>`;
})
.join("");

View File

@ -165,6 +165,34 @@
transform: translateY(-4px);
transition: transform 0.15s;
}
/* ── Reichweite & Laufen Badges (Hand + Board) ── */
.cs-range, .cs-race {
position: absolute;
display: flex;
align-items: center;
gap: 2px;
padding: 1px 4px;
border-radius: 20px;
font-family: "Cinzel", serif;
font-size: 8px;
font-weight: bold;
line-height: 1;
z-index: 6;
pointer-events: none;
}
.cs-range {
bottom: 22px; left: 3px;
background: rgba(30,20,0,0.85);
border: 1px solid #e8b84b;
color: #e8b84b;
}
.cs-race {
bottom: 6px; left: 3px;
background: rgba(0,25,0,0.85);
border: 1px solid #7de87d;
color: #7de87d;
}
</style>
</head>
@ -383,6 +411,10 @@
handSlotState[id] = null;
});
/* ── Stat-Icon SVGs ─────────────────────────────────── */
const SVG_RANGE = `<svg viewBox="0 0 16 16" width="10" height="10" style="display:inline;vertical-align:middle;flex-shrink:0" fill="none" stroke="#e8b84b" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4 2 Q1 8 4 14"/><line x1="4" y1="2" x2="4" y2="14" stroke-width="0.7" stroke-dasharray="2,1.5"/><line x1="4" y1="8" x2="13" y2="8"/><polyline points="11,6 13,8 11,10"/><line x1="5" y1="7" x2="4" y2="8"/><line x1="5" y1="9" x2="4" y2="8"/></svg>`;
const SVG_RACE = `<svg viewBox="0 0 16 16" width="10" height="10" style="display:inline;vertical-align:middle;flex-shrink:0" fill="none" stroke="#7de87d" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="2.5" r="1.4" fill="#7de87d" stroke="none"/><line x1="9" y1="4" x2="8" y2="9"/><line x1="8" y1="9" x2="10" y2="14"/><line x1="8" y1="9" x2="6" y2="13"/><line x1="8.5" y1="5.5" x2="11" y2="8"/><line x1="8.5" y1="5.5" x2="6" y2="7"/></svg>`;
/* ── Slot rendern ──────────────────────────────────── */
function renderHandSlot(id) {
const slot = document.getElementById(id);
@ -400,6 +432,8 @@
const atkVal = card.attack ?? null;
const defVal = card.defends ?? null;
const rngVal = card.range ?? null;
const rceVal = card.race ?? null;
const statsHtml = `
<div class="card-stat-overlay">
@ -410,6 +444,8 @@
? `<span class="cs-cd ${isReady ? "cs-cd-ready" : ""}">${isReady ? "✓" : currentCd}</span>`
: ""
}
${rngVal != null ? `<span class="cs-range">${SVG_RANGE}&thinsp;${rngVal}</span>` : ""}
${rceVal != null ? `<span class="cs-race">${SVG_RACE}&thinsp;${rceVal}</span>` : ""}
</div>`;
const readyBadge = isReady
@ -641,20 +677,27 @@
if (!slot || !card) return;
const atkVal = card.attack ?? null;
const defVal = card.defends ?? null;
const cdVal = card.cooldown ?? null;
const cdVal = card.cooldown ?? null;
const rngVal = card.range ?? null;
const rceVal = card.race ?? null;
const hasAtk = atkVal != null;
const hasDef = defVal != null;
const hasCd = cdVal != null;
const hasCd = cdVal != null;
const hasRng = rngVal != null;
const hasRce = rceVal != null;
const statsHtml =
hasAtk || hasDef || hasCd
hasAtk || hasDef || hasCd || hasRng || hasRce
? `
<div class="card-stat-overlay">
${hasAtk ? `<span class="cs-atk">${atkVal}</span>` : ""}
${hasDef ? `<span class="cs-def">${defVal}</span>` : ""}
${hasCd ? `<span class="cs-cd">${cdVal}</span>` : ""}
${hasCd ? `<span class="cs-cd">${cdVal}</span>` : ""}
${hasRng ? `<span class="cs-range">${SVG_RANGE}&thinsp;${rngVal}</span>` : ""}
${hasRce ? `<span class="cs-race">${SVG_RACE}&thinsp;${rceVal}</span>` : ""}
</div>`
: "";
// note: SVG_RACE is defined as the walking icon above
slot.classList.add("slot-occupied");
slot.innerHTML = card.image