From a8bb5f90e5a60f53f555584507c24e9c5e90bee1 Mon Sep 17 00:00:00 2001 From: Cay Date: Sun, 15 Mar 2026 11:23:30 +0000 Subject: [PATCH] AI 6 --- public/css/building.css | 117 ++++++++++++++++++++-- public/images/avatar_silhouette.svg | 24 +++++ public/js/buildings/wohnhaus.js | 145 +++++++++++++--------------- 3 files changed, 200 insertions(+), 86 deletions(-) create mode 100644 public/images/avatar_silhouette.svg diff --git a/public/css/building.css b/public/css/building.css index 0ad1ba3..30725db 100644 --- a/public/css/building.css +++ b/public/css/building.css @@ -238,17 +238,122 @@ body { position: relative; } -.character-center img { +/* ======================== + Avatar Wrapper +======================== */ + +.avatar-wrapper { + position: relative; width: 180px; height: 320px; - object-fit: cover; - object-position: top; border-radius: 8px; border: 2px solid #8b6a3c; + background: radial-gradient(ellipse at center, #2a1f14 0%, #0d0a07 100%); box-shadow: - 0 0 20px rgba(0, 0, 0, 0.7), - inset 0 0 10px rgba(0, 0, 0, 0.3); - filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.8)); + 0 0 20px rgba(0, 0, 0, 0.8), + inset 0 0 30px rgba(0, 0, 0, 0.5); + overflow: hidden; +} + +.avatar-base { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + object-fit: contain; + display: block; + opacity: 0.9; +} + +/* Item Overlays */ + +.avatar-overlay { + position: absolute; + pointer-events: none; + display: none; + z-index: 2; +} + +.avatar-overlay.visible { + display: block; + animation: overlayFadeIn 0.25s ease; +} + +.avatar-overlay img { + width: 100%; + height: 100%; + object-fit: contain; + filter: drop-shadow(0 0 4px rgba(255, 200, 80, 0.5)) + drop-shadow(0 2px 6px rgba(0, 0, 0, 0.9)); +} + +@keyframes overlayFadeIn { + from { + opacity: 0; + transform: scale(1.15); + } + to { + opacity: 1; + transform: scale(1); + } +} + +/* Positionen der Item-Overlays (180x320px) */ + +.avatar-overlay[data-slot="helmet"] { + top: 1%; + left: 22%; + width: 56%; + height: 20%; +} +.avatar-overlay[data-slot="amulet"] { + top: 21%; + left: 58%; + width: 30%; + height: 11%; +} +.avatar-overlay[data-slot="shoulder"] { + top: 19%; + left: 3%; + width: 30%; + height: 13%; +} +.avatar-overlay[data-slot="weapon"] { + top: 38%; + left: 56%; + width: 40%; + height: 32%; +} +.avatar-overlay[data-slot="gloves"] { + top: 54%; + left: 2%; + width: 30%; + height: 13%; +} +.avatar-overlay[data-slot="shield"] { + top: 36%; + left: 4%; + width: 36%; + height: 30%; +} +.avatar-overlay[data-slot="belt"] { + top: 51%; + left: 18%; + width: 64%; + height: 11%; +} +.avatar-overlay[data-slot="ring"] { + top: 67%; + left: 3%; + width: 24%; + height: 9%; +} +.avatar-overlay[data-slot="boots"] { + top: 80%; + left: 12%; + width: 76%; + height: 18%; } /* Top-Slots (Helm + Amulett) über dem Avatar */ diff --git a/public/images/avatar_silhouette.svg b/public/images/avatar_silhouette.svg new file mode 100644 index 0000000..156ebf0 --- /dev/null +++ b/public/images/avatar_silhouette.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/js/buildings/wohnhaus.js b/public/js/buildings/wohnhaus.js index e38c61d..37a5af1 100644 --- a/public/js/buildings/wohnhaus.js +++ b/public/js/buildings/wohnhaus.js @@ -6,7 +6,6 @@ export async function loadWohnhaus() { const ui = document.querySelector(".building-ui"); ui.innerHTML = ` -
@@ -22,7 +21,20 @@ export async function loadWohnhaus() {
Helm
Amulett
- Avatar + +
+ Avatar +
+
+
+
+
+
+
+
+
+
+
Guertel
Stiefel
@@ -38,7 +50,6 @@ export async function loadWohnhaus() {
-
Inventar
@@ -46,22 +57,39 @@ export async function loadWohnhaus() {
- +
- +
`; await loadInventory(); await loadEquipment(); - initInventoryButtons(); - initDrag(); initSlotDrag(); initDrop(); initInventoryDrop(); } +/* ================================ + AVATAR OVERLAY AKTUALISIEREN +================================ */ + +function updateAvatarOverlay(slotName, iconSrc) { + const overlay = document.querySelector(`.avatar-overlay[data-slot="${slotName}"]`); + if (!overlay) return; + + const img = overlay.querySelector("img"); + + if (iconSrc) { + img.src = iconSrc; + overlay.classList.add("visible"); + } else { + overlay.classList.remove("visible"); + setTimeout(() => { img.src = ""; }, 250); + } +} + /* ================================ INVENTAR LADEN ================================ */ @@ -69,7 +97,6 @@ export async function loadWohnhaus() { async function loadInventory() { const res = await fetch("/api/inventory"); inventoryItems = await res.json(); - renderInventory(); } @@ -79,7 +106,6 @@ async function loadInventory() { function renderInventory() { const grid = document.getElementById("inventory-grid"); - let html = ""; const start = inventoryPage * slotsPerPage; @@ -90,32 +116,22 @@ function renderInventory() { if (item) { const icon = item.icon || "/images/items/default.png"; - html += `
- - - -
-`; + data-slot="${item.equip_slot || ""}" + data-id="${item.id}" + data-level="${item.level}" + draggable="true"> + +`; } else { - html += ` -
-`; + html += `
`; } } grid.innerHTML = html; - const totalPages = Math.max( - 1, - Math.ceil(inventoryItems.length / slotsPerPage), - ); - + const totalPages = Math.max(1, Math.ceil(inventoryItems.length / slotsPerPage)); document.getElementById("inventory-page").innerText = "Seite " + (inventoryPage + 1) + " / " + totalPages; @@ -135,11 +151,7 @@ function initInventoryButtons() { }; document.getElementById("inv-right").onclick = () => { - const totalPages = Math.max( - 1, - Math.ceil(inventoryItems.length / slotsPerPage), - ); - + const totalPages = Math.max(1, Math.ceil(inventoryItems.length / slotsPerPage)); if (inventoryPage < totalPages - 1) { inventoryPage++; renderInventory(); @@ -163,16 +175,12 @@ async function loadEquipment() { const label = slot.querySelector(".slot-label"); - slot.innerHTML = ` - -`; - + slot.innerHTML = ``; if (label) slot.appendChild(label); - slot.classList.add("has-item"); + + // Avatar Overlay aktualisieren + updateAvatarOverlay(item.slot, item.icon); }); } @@ -201,7 +209,6 @@ function initSlotDrag() { img.addEventListener("dragstart", (e) => { const slot = img.closest(".slot"); - e.dataTransfer.setData("itemId", img.dataset.id); e.dataTransfer.setData("itemLevel", img.dataset.level); e.dataTransfer.setData("slot", slot.dataset.slot); @@ -221,11 +228,10 @@ function initDrop() { slot.addEventListener("drop", (e) => { e.preventDefault(); - const itemId = e.dataTransfer.getData("itemId"); + const itemId = e.dataTransfer.getData("itemId"); const itemLevel = e.dataTransfer.getData("itemLevel"); - const itemSlot = e.dataTransfer.getData("slot"); - const source = e.dataTransfer.getData("source"); - + const itemSlot = e.dataTransfer.getData("slot"); + const source = e.dataTransfer.getData("source"); const targetSlot = slot.dataset.slot; if (!itemSlot || itemSlot !== targetSlot) return; @@ -233,41 +239,27 @@ function initDrop() { let icon; if (source === "inventory") { - const inventoryItem = document.querySelector( - '.inventory-slot[data-id="' + itemId + '"]', - ); - + const inventoryItem = document.querySelector('.inventory-slot[data-id="' + itemId + '"]'); if (!inventoryItem) return; - icon = inventoryItem.querySelector("img").src; - inventoryItem.classList.add("empty"); inventoryItem.innerHTML = ""; } else { - const slotItem = document.querySelector( - '.slot[data-slot="' + itemSlot + '"] img', - ); + const slotItem = document.querySelector('.slot[data-slot="' + itemSlot + '"] img'); if (!slotItem) return; - icon = slotItem.src; } const label = slot.querySelector(".slot-label"); - - slot.innerHTML = ` - -`; - + slot.innerHTML = ``; if (label) slot.appendChild(label); - slot.classList.add("has-item"); + // Avatar Overlay anzeigen + updateAvatarOverlay(targetSlot, icon); + initDrag(); initSlotDrag(); - saveEquipment(targetSlot, itemId, itemLevel); }); }); @@ -285,20 +277,17 @@ function initInventoryDrop() { grid.addEventListener("drop", (e) => { e.preventDefault(); - const source = e.dataTransfer.getData("source"); - + const source = e.dataTransfer.getData("source"); if (source !== "slot") return; - const itemId = e.dataTransfer.getData("itemId"); + const itemId = e.dataTransfer.getData("itemId"); const itemLevel = e.dataTransfer.getData("itemLevel"); - const slotName = e.dataTransfer.getData("slot"); + const slotName = e.dataTransfer.getData("slot"); const slot = document.querySelector('.slot[data-slot="' + slotName + '"]'); - if (!slot) return; const img = slot.querySelector("img"); - if (!img) return; inventoryItems.push({ @@ -311,14 +300,14 @@ function initInventoryDrop() { renderInventory(); const label = slot.querySelector(".slot-label"); - slot.innerHTML = ""; if (label) slot.appendChild(label); - slot.classList.remove("has-item"); - saveEquipment(slotName, null, null); + // Avatar Overlay entfernen + updateAvatarOverlay(slotName, null); + saveEquipment(slotName, null, null); initDrag(); initSlotDrag(); }); @@ -332,10 +321,6 @@ async function saveEquipment(slot, itemId, itemLevelId) { await fetch("/api/equip", { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - slot: slot, - itemId: itemId, - itemLevelId: itemLevelId, - }), + body: JSON.stringify({ slot, itemId, itemLevelId }), }); -} +} \ No newline at end of file