diff --git a/www/html/Game/public/css/leaderboard-popup.css b/www/html/Game/public/css/leaderboard-popup.css new file mode 100644 index 0000000..199e2d9 --- /dev/null +++ b/www/html/Game/public/css/leaderboard-popup.css @@ -0,0 +1,444 @@ + +#lobby-rank-overlay, +#lobby-rank-overlay * { + font-family: 'Kanit', 'Noto Sans Thai', system-ui, sans-serif !important; +} + +#lobby-rank-overlay { + position: fixed; + inset: 0; + z-index: 10048; + display: flex; + align-items: center; + justify-content: center; + padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left)); + box-sizing: border-box; +} + +#lobby-rank-overlay.is-hidden { + display: none !important; +} + +#lobby-rank-overlay .lobby-rank-dialog { + position: relative; + z-index: 1; + width: min(1107px, calc(100vw - 24px), calc((100dvh - 24px) * (1107 / 952))); + aspect-ratio: 1107 / 952; + max-height: calc(100dvh - 24px); + --lrb-scale: 1; + --lrb-avatar-focus-y: -14%; + --lrb-avatar-zoom-ped: 1.03; + --lrb-avatar-zoom-row: 1.1; + --lrb-avatar-zoom-self: 1.25; + pointer-events: none; +} + +#lobby-rank-overlay .lobby-rank-dialog * { + pointer-events: auto; +} + +#lobby-rank-overlay .lobby-rank-panel { + position: relative; + width: 100%; + height: 100%; + background: transparent; + border: 0; + border-radius: 0; + box-shadow: none; + padding: 0; + overflow: hidden; +} + +#lobby-rank-overlay .lobby-rank-bg { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + display: block; + object-fit: contain; + object-position: center; + user-select: none; + -webkit-user-drag: none; +} + +#lobby-rank-overlay .lobby-rank-head { + position: absolute; + left: 50%; + top: calc(43px * var(--lrb-scale)); + transform: translateX(-50%); + width: calc(770px * var(--lrb-scale)); + height: calc(67px * var(--lrb-scale)); + border-bottom: none; +} + +#lobby-rank-overlay .lobby-rank-head-box { + display: none; +} + +#lobby-rank-overlay .lobby-rank-case-title { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + margin-top: calc(54px * var(--lrb-scale)); + color: #dffbff; + font-size: calc(42px * var(--lrb-scale)); + font-weight: 700; + line-height: 1; + text-shadow: 0 0 calc(12px * var(--lrb-scale)) rgba(0, 255, 255, 0.5); +} + +#lobby-rank-overlay .lobby-rank-close { + position: absolute; + top: calc(50px * var(--lrb-scale)); + right: calc(-83px * var(--lrb-scale)); + width: calc(65px * var(--lrb-scale)); + height: calc(65px * var(--lrb-scale)); + min-width: calc(65px * var(--lrb-scale)); + min-height: calc(65px * var(--lrb-scale)); + max-width: calc(65px * var(--lrb-scale)); + max-height: calc(65px * var(--lrb-scale)); + border: none; + border-radius: 0; + background: #ffffff; + color: transparent; + font-size: 0; + line-height: 1; + text-shadow: none; + cursor: pointer; + padding: 0; + margin: 0; + z-index: 2; + -webkit-tap-highlight-color: transparent; + opacity: 0; +} + +#lobby-rank-overlay .lobby-rank-backdrop { + position: absolute; + inset: 0; + background: rgba(0, 0, 0, 0.85); + cursor: pointer; +} + +#lobby-rank-overlay .lobby-rank-podium { + position: absolute; + top: 19.33%; + left: 12.47%; + right: 12.47%; + height: 17.65%; + --lrb-ped-width: calc(180px * var(--lrb-scale)); + --lrb-podium-gap: calc(55px * var(--lrb-scale)); + display: grid; + grid-template-columns: repeat(3, var(--lrb-ped-width)); + align-items: end; + justify-content: center; + column-gap: var(--lrb-podium-gap); +} + +#lobby-rank-overlay .lobby-rank-ped { + position: relative; + width: var(--lrb-ped-width); + min-width: var(--lrb-ped-width); + max-width: var(--lrb-ped-width); + height: auto; + background: transparent; + border: none; + box-shadow: none; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-start; + gap: calc(3px * var(--lrb-scale)); + transform-origin: bottom center; + align-self: end; +} + +#lobby-rank-overlay .lobby-rank-ped-badge { + position: absolute; + top: calc(-14px * var(--lrb-scale)); + left: calc(-14px * var(--lrb-scale)); + width: calc(51px * var(--lrb-scale)); + height: calc(51px * var(--lrb-scale)); + z-index: 3; + object-fit: contain; + pointer-events: none; + display: block; +} + +#lobby-rank-overlay .lobby-rank-ped-pic { + width: 100%; + height: 100%; + display: block; + object-fit: contain; + opacity: 1; + filter: none; +} + +#lobby-rank-overlay .lobby-rank-ped-pic-wrap { + position: relative; + overflow: visible; + border-radius: 0; +} + +#lobby-rank-overlay .lobby-rank-ped-avatar { + position: absolute; + left: 50%; + top: 43%; + width: 100%; + height: 85%; + z-index: 1; + display: block; + background: transparent !important; + border: none; + box-shadow: none; + border-radius: 0; + object-fit: cover; + object-position: center var(--lrb-avatar-focus-y); + transform: translate(-50%, -50%) scale(var(--lrb-avatar-zoom-ped)); + transform-origin: center center; +} + +#lobby-rank-overlay .lobby-rank-ped--1 .lobby-rank-ped-pic-wrap { + width: calc(111px * var(--lrb-scale)); + height: calc(111px * var(--lrb-scale)); +} + +#lobby-rank-overlay .lobby-rank-ped--2 .lobby-rank-ped-pic, +#lobby-rank-overlay .lobby-rank-ped--3 .lobby-rank-ped-pic { + width: 100%; + height: 100%; +} + +#lobby-rank-overlay .lobby-rank-ped--2 .lobby-rank-ped-pic-wrap, +#lobby-rank-overlay .lobby-rank-ped--3 .lobby-rank-ped-pic-wrap { + width: calc(91px * var(--lrb-scale)); + height: calc(92px * var(--lrb-scale)); +} + +#lobby-rank-overlay .lobby-rank-ped-name { + color: #ffffff; + font-size: calc(20px * var(--lrb-scale)); + font-weight: 500; + line-height: 1; + text-align: center; + width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin-top: calc(-3px * var(--lrb-scale)); +} + +#lobby-rank-overlay .lobby-rank-ped-score { + color: #72d9ff; + font-size: calc(28px * var(--lrb-scale)); + font-weight: 700; + line-height: 1; +} + +#lobby-rank-overlay .lobby-rank-ped--1 .lobby-rank-ped-score { + color: #DCAB37; +} + +.lobby-rank-ped--1 .lobby-rank-ped-avatar { + transform: translate(-50%, -53%) scale(2.2); +} + +#lobby-rank-overlay .lobby-rank-table-wrap { + position: absolute; + left: 50%; + transform: translateX(-50%); + width: calc(770px * var(--lrb-scale)); + top: calc(384px * var(--lrb-scale)); + bottom: calc(126px * var(--lrb-scale)); + display: flex; + flex-direction: column; +} + +#lobby-rank-overlay .lobby-rank-table-head { + height: calc(67px * var(--lrb-scale)); + width: calc(770px * var(--lrb-scale)); + display: grid; + grid-template-columns: calc(169px * var(--lrb-scale)) 1fr calc(220px * var(--lrb-scale)); + align-items: center; + background: url("../img/Leaderboard/header-box.png") center / 100% 100% no-repeat; + border: none; +} + +#lobby-rank-overlay .lobby-rank-table-head > img:nth-child(2) { + transform: translateX(calc(24px * var(--lrb-scale))); +} + +#lobby-rank-overlay .lobby-rank-table-head > img { + height: calc(46px * var(--lrb-scale)); + width: auto; + justify-self: center; + object-fit: contain; +} + +#lobby-rank-overlay .lobby-rank-list { + flex: 1; + overflow-y: auto; + overflow-x: hidden; + scrollbar-width: thin; +} + +#lobby-rank-overlay .lobby-rank-row { + position: relative; + min-height: calc(46px * var(--lrb-scale)); + display: grid; + grid-template-columns: calc(168px * var(--lrb-scale)) 1fr calc(218px * var(--lrb-scale)); + align-items: center; + color: #e9f8ff; + font-size: calc(15px * var(--lrb-scale)); + padding: 0 calc(0px * var(--lrb-scale)); +} + +#lobby-rank-overlay .lobby-rank-row-line { + position: absolute; + left: 0; + right: 0; + bottom: 0; + height: calc(3px * var(--lrb-scale)); + width: 100%; + object-fit: fill; + opacity: 0.95; +} + +#lobby-rank-overlay .lobby-rank-row-rank { + justify-self: center; +} + +#lobby-rank-overlay .lobby-rank-row-player { + display: flex; + align-items: center; + gap: calc(10px * var(--lrb-scale)); + min-width: 0; +} + +#lobby-rank-overlay .lobby-rank-row-pic-bg { + width: calc(41px * var(--lrb-scale)); + height: calc(41px * var(--lrb-scale)); + position: relative; + flex-shrink: 0; + overflow: hidden; + border-radius: 0; +} + +#lobby-rank-overlay .lobby-rank-row-pic-bg > img:first-child { + width: 100%; + height: 100%; +} + +#lobby-rank-overlay .lobby-rank-row-avatar { + position: absolute; + left: 50%; + top: 50%; + width: calc(31px * var(--lrb-scale)); + height: calc(28px * var(--lrb-scale)); + transform: translate(-50%, -64%) scale(var(--lrb-avatar-zoom-row)); + transform-origin: center top; + object-fit: cover; + object-position: center var(--lrb-avatar-focus-y); + border-radius: 50%; +} + +#lobby-rank-overlay .lobby-rank-row-name { + text-align: center; + width: 100%; + min-width: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + transform: translateX(calc(2px * var(--lrb-scale))); +} + +#lobby-rank-overlay .lobby-rank-row-score { + justify-self: center; +} + +#lobby-rank-overlay .lobby-rank-self { + position: absolute; + left: 50%; + bottom: calc(94px * var(--lrb-scale)); + transform: translateX(-50%); + width: calc(761px * var(--lrb-scale)); + height: calc(95px * var(--lrb-scale)); + display: grid; + grid-template-columns: calc(115px * var(--lrb-scale)) calc(90px * var(--lrb-scale)) 1fr calc(164px * var(--lrb-scale)); + align-items: center; +} + +#lobby-rank-overlay .lobby-rank-self-bg { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + object-fit: contain; +} + +#lobby-rank-overlay .lobby-rank-self-rank, +#lobby-rank-overlay .lobby-rank-self-name, +#lobby-rank-overlay .lobby-rank-self-score { + position: relative; + z-index: 1; + line-height: 1; +} + +#lobby-rank-overlay .lobby-rank-self-rank { + justify-self: center; + color: #ff58d7; + font-size: calc(34px * var(--lrb-scale)); + font-weight: 700; + transform: translateX(calc(20px * var(--lrb-scale))); + +} + +#lobby-rank-overlay .lobby-rank-self-av-wrap { + position: relative; + z-index: 1; + width: calc(61px * var(--lrb-scale)); + height: calc(61px * var(--lrb-scale)); + justify-self: center; + transform: translateX(calc(23px * var(--lrb-scale))); +} + +#lobby-rank-overlay .lobby-rank-self-pic-bg { + width: 100%; + height: 100%; + object-fit: contain; +} + +#lobby-rank-overlay .lobby-rank-self-avatar { + position: absolute; + left: 50%; + top: 46%; + width: calc(47px * var(--lrb-scale)); + height: calc(42px * var(--lrb-scale)); + transform: translate(-50%, -67%) scale(var(--lrb-avatar-zoom-self)); + transform-origin: center top; + border-radius: 50%; + object-fit: cover; + object-position: center var(--lrb-avatar-focus-y); +} + +#lobby-rank-overlay .lobby-rank-self-name { + color: #ffffff; + font-size: calc(34px * var(--lrb-scale)); + font-weight: 700; + text-align: center; + width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + padding-right: calc(16px * var(--lrb-scale)); + transform: translateX(calc(17px * var(--lrb-scale))); +} + +#lobby-rank-overlay .lobby-rank-self-score { + justify-self: center; + color: #ff58d7; + font-size: calc(34px * var(--lrb-scale)); + font-weight: 700; + transform: translateX(calc(-23px * var(--lrb-scale))); +} diff --git a/www/html/Game/public/css/room-lobby.css b/www/html/Game/public/css/room-lobby.css index 446f653..758ff59 100644 --- a/www/html/Game/public/css/room-lobby.css +++ b/www/html/Game/public/css/room-lobby.css @@ -1711,7 +1711,7 @@ body.room-lobby--quiz-active .lobby-b-extra-row { justify-content: flex-end; gap: 0.75rem; } - /* แถวเดียว: อันดับ | ไมค์ | หลักฐาน (ตรง production) */ + /* แถวเดียว: หลักฐาน | อันดับ | ไมค์ (ตรง production) */ .room-lobby-br-fixed .lobby-b-extra-row:not(.is-hidden) { display: contents; } @@ -1721,17 +1721,7 @@ body.room-lobby--quiz-active .lobby-b-extra-row { transform: none !important; z-index: auto; } - .room-lobby-br-fixed #lobby-b-btn-rank { - order: 1; - } - .room-lobby-br-fixed #btn-voice { - order: 2; - } - .room-lobby-br-fixed #lobby-b-btn-evidence { - order: 3; - } .room-lobby-br-fixed .btn-voice-icon { - order: 2; position: static !important; margin: 0 !important; transform: none !important; @@ -2063,311 +2053,7 @@ body.room-lobby--quiz-active .lobby-b-extra-row { } } -/* —— กระดานอันดับ LobbyB (เหรียญ leaderboard-1/2/3 จาก Main-Lobby) —— */ -.lobby-rank-overlay { - position: fixed; - inset: 0; - z-index: 10048; - display: flex; - align-items: center; - justify-content: center; - padding: max(12px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) max(12px, env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left)); - box-sizing: border-box; -} -.lobby-rank-overlay.is-hidden { - display: none !important; -} -.lobby-rank-backdrop { - position: absolute; - inset: 0; - background: rgba(2, 4, 14, 0.82); - backdrop-filter: blur(8px); - -webkit-backdrop-filter: blur(8px); - cursor: pointer; -} -.lobby-rank-dialog { - position: relative; - z-index: 1; - width: min(96vw, 520px); - max-height: min(90vh, 720px); - pointer-events: none; -} -.lobby-rank-dialog * { - pointer-events: auto; -} -.lobby-rank-panel { - background: linear-gradient(165deg, rgba(28, 36, 58, 0.96), rgba(12, 16, 32, 0.98)); - border-radius: 16px; - border: 2px solid rgba(0, 255, 255, 0.45); - box-shadow: - 0 0 0 1px rgba(255, 0, 200, 0.25), - 0 0 32px rgba(0, 255, 255, 0.12), - 0 0 48px rgba(255, 0, 180, 0.08), - inset 0 1px 0 rgba(255, 255, 255, 0.06); - padding: clamp(10px, 2.5vw, 16px); - display: flex; - flex-direction: column; - min-height: 0; - font-family: 'Kanit', 'Sarabun', system-ui, sans-serif; -} -.lobby-rank-head { - display: flex; - flex-direction: row; - align-items: center; - justify-content: center; - position: relative; - padding: 6px 44px 12px 12px; - border-bottom: 1px solid rgba(0, 255, 255, 0.28); - margin-bottom: 8px; -} -.lobby-rank-case-title { - margin: 0; - font-size: clamp(0.95rem, 2.8vw, 1.15rem); - font-weight: 700; - color: #e8f4ff; - text-align: center; - text-shadow: 0 0 12px rgba(0, 255, 255, 0.35); - line-height: 1.25; -} -.lobby-rank-close { - position: absolute; - top: 2px; - right: 4px; - width: 44px; - height: 44px; - padding: 0; - border: none; - border-radius: 10px; - background: transparent; - color: rgba(0, 255, 255, 0.95); - font-size: 1.75rem; - line-height: 1; - cursor: pointer; - text-shadow: 0 0 14px rgba(0, 255, 255, 0.85); - display: flex; - align-items: center; - justify-content: center; - transition: transform 0.15s ease, filter 0.15s ease; -} -.lobby-rank-close:hover { - transform: scale(1.06); - filter: brightness(1.12); -} -.lobby-rank-podium { - display: flex; - flex-direction: row; - align-items: flex-end; - justify-content: center; - gap: clamp(6px, 2vw, 14px); - padding: 8px 4px 14px; - flex-shrink: 0; -} -.lobby-rank-ped { - flex: 1 1 0; - min-width: 0; - max-width: 150px; - display: flex; - flex-direction: column; - align-items: center; - text-align: center; - padding: 10px 6px 12px; - border-radius: 14px; - background: rgba(0, 0, 0, 0.28); - border: 1px solid rgba(0, 255, 255, 0.22); - box-sizing: border-box; -} -.lobby-rank-ped--2 { - order: 1; - min-height: 148px; -} -.lobby-rank-ped--1 { - order: 2; - min-height: 188px; - border-color: rgba(255, 215, 0, 0.45); - box-shadow: 0 0 22px rgba(255, 200, 0, 0.12); -} -.lobby-rank-ped--3 { - order: 3; - min-height: 132px; -} -.lobby-rank-crown { - display: flex; - flex-direction: row; - align-items: center; - justify-content: center; - gap: 4px; - margin-bottom: 4px; - font-size: 1.1rem; - line-height: 1; - filter: drop-shadow(0 0 6px rgba(255, 215, 0, 0.6)); -} -.lobby-rank-crown-n { - font-size: 0.85rem; - font-weight: 800; - color: #ffe066; -} -.lobby-rank-medal-wrap { - height: 36px; - display: flex; - align-items: center; - justify-content: center; - margin-bottom: 6px; -} -.lobby-rank-medal-img { - width: auto; - height: 34px; - object-fit: contain; - display: block; -} -.lobby-rank-ped-avatar { - width: 48px; - height: 48px; - border-radius: 50%; - background: linear-gradient(145deg, #7aa2f7, #565f89); - color: #1a1b26; - font-size: 1.1rem; - font-weight: 800; - display: flex; - align-items: center; - justify-content: center; - margin-bottom: 6px; - box-shadow: 0 0 0 2px rgba(0, 255, 255, 0.3); - flex-shrink: 0; -} -.lobby-rank-ped--1 .lobby-rank-ped-avatar { - width: 56px; - height: 56px; - font-size: 1.25rem; -} -.lobby-rank-ped-name { - font-size: clamp(0.68rem, 2vw, 0.8rem); - font-weight: 600; - color: #e8ecff; - line-height: 1.2; - word-break: break-word; - max-width: 100%; -} -.lobby-rank-ped-score { - margin-top: 4px; - font-size: clamp(0.75rem, 2.2vw, 0.9rem); - font-weight: 700; - color: #fff; - text-shadow: 0 0 8px rgba(255, 255, 255, 0.2); -} -.lobby-rank-table-wrap { - flex: 1 1 auto; - min-height: 0; - overflow-y: auto; - overflow-x: hidden; - margin: 0 -4px; - padding: 0 4px; - scrollbar-width: thin; -} -.lobby-rank-table { - width: 100%; - border-collapse: collapse; - font-size: clamp(0.65rem, 1.9vw, 0.78rem); -} -.lobby-rank-table thead th { - text-align: left; - text-transform: uppercase; - letter-spacing: 0.06em; - color: rgba(0, 255, 255, 0.85); - font-weight: 700; - padding: 8px 6px; - border-bottom: 1px solid rgba(0, 255, 255, 0.25); - position: sticky; - top: 0; - background: linear-gradient(180deg, rgba(20, 26, 44, 0.98), rgba(20, 26, 44, 0.92)); - z-index: 1; -} -.lobby-rank-table thead th:nth-child(1) { width: 3.2rem; } -.lobby-rank-table thead th:nth-child(3) { text-align: right; width: 4rem; } -.lobby-rank-table tbody td { - padding: 7px 6px; - border-bottom: 1px solid rgba(255, 255, 255, 0.06); - color: #e2e8f0; - vertical-align: middle; -} -.lobby-rank-table tbody td:nth-child(3) { - text-align: right; - font-weight: 600; - color: #fff; -} -.lobby-rank-table .lobby-rank-row-av { - display: inline-flex; - align-items: center; - gap: 8px; - min-width: 0; -} -.lobby-rank-table .lobby-rank-mini-av { - width: 26px; - height: 26px; - border-radius: 50%; - background: linear-gradient(145deg, #9ece6a, #565f89); - color: #1a1b26; - font-size: 0.65rem; - font-weight: 800; - display: flex; - align-items: center; - justify-content: center; - flex-shrink: 0; - box-shadow: 0 0 0 1px rgba(0, 255, 255, 0.2); -} -.lobby-rank-table .lobby-rank-row-name { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - max-width: 180px; -} -.lobby-rank-self { - flex-shrink: 0; - display: flex; - flex-direction: row; - align-items: center; - gap: 10px; - padding: 12px 10px 6px; - margin-top: 6px; - border-top: 1px solid rgba(255, 0, 180, 0.42); - background: linear-gradient(90deg, rgba(255, 0, 180, 0.07), transparent); -} -.lobby-rank-self-rank { - font-weight: 800; - color: #c0caf5; - min-width: 2.5rem; - font-size: clamp(0.75rem, 2vw, 0.88rem); -} -.lobby-rank-self-av { - width: 40px; - height: 40px; - border-radius: 50%; - background: linear-gradient(145deg, #f472b6, #a855f7); - color: #fff; - font-size: 1rem; - font-weight: 800; - display: flex; - align-items: center; - justify-content: center; - flex-shrink: 0; - box-shadow: 0 0 0 2px rgba(255, 100, 200, 0.45); -} -.lobby-rank-self-meta { - flex: 1; - min-width: 0; -} -.lobby-rank-self-name { - font-size: clamp(0.85rem, 2.4vw, 1rem); - font-weight: 800; - color: #fff; - line-height: 1.2; -} -.lobby-rank-self-score { - font-size: clamp(0.85rem, 2.4vw, 1rem); - font-weight: 800; - color: #ff4ecd; - text-shadow: 0 0 12px rgba(255, 78, 205, 0.45); - flex-shrink: 0; -} +/* กระดานอันดับ LobbyB — ดู css/leaderboard-popup.css */ .version-tag { position: fixed; diff --git a/www/html/Game/public/img/Leaderboard/1st-pic.png b/www/html/Game/public/img/Leaderboard/1st-pic.png new file mode 100644 index 0000000..d57519f Binary files /dev/null and b/www/html/Game/public/img/Leaderboard/1st-pic.png differ diff --git a/www/html/Game/public/img/Leaderboard/1st.png b/www/html/Game/public/img/Leaderboard/1st.png new file mode 100644 index 0000000..0f77c45 Binary files /dev/null and b/www/html/Game/public/img/Leaderboard/1st.png differ diff --git a/www/html/Game/public/img/Leaderboard/2nd-pic.png b/www/html/Game/public/img/Leaderboard/2nd-pic.png new file mode 100644 index 0000000..c6836d8 Binary files /dev/null and b/www/html/Game/public/img/Leaderboard/2nd-pic.png differ diff --git a/www/html/Game/public/img/Leaderboard/2nd.png b/www/html/Game/public/img/Leaderboard/2nd.png new file mode 100644 index 0000000..3750d82 Binary files /dev/null and b/www/html/Game/public/img/Leaderboard/2nd.png differ diff --git a/www/html/Game/public/img/Leaderboard/3rd-pic.png b/www/html/Game/public/img/Leaderboard/3rd-pic.png new file mode 100644 index 0000000..f4fc878 Binary files /dev/null and b/www/html/Game/public/img/Leaderboard/3rd-pic.png differ diff --git a/www/html/Game/public/img/Leaderboard/3rd.png b/www/html/Game/public/img/Leaderboard/3rd.png new file mode 100644 index 0000000..b5dd7b0 Binary files /dev/null and b/www/html/Game/public/img/Leaderboard/3rd.png differ diff --git a/www/html/Game/public/img/Leaderboard/header-box.png b/www/html/Game/public/img/Leaderboard/header-box.png new file mode 100644 index 0000000..afe62a2 Binary files /dev/null and b/www/html/Game/public/img/Leaderboard/header-box.png differ diff --git a/www/html/Game/public/img/Leaderboard/rank-game-bg.png b/www/html/Game/public/img/Leaderboard/rank-game-bg.png new file mode 100644 index 0000000..85b0ac8 Binary files /dev/null and b/www/html/Game/public/img/Leaderboard/rank-game-bg.png differ diff --git a/www/html/Game/public/img/Leaderboard/rank-line.png b/www/html/Game/public/img/Leaderboard/rank-line.png new file mode 100644 index 0000000..9783a2a Binary files /dev/null and b/www/html/Game/public/img/Leaderboard/rank-line.png differ diff --git a/www/html/Game/public/img/Leaderboard/rank-pic.png b/www/html/Game/public/img/Leaderboard/rank-pic.png new file mode 100644 index 0000000..a8752e8 Binary files /dev/null and b/www/html/Game/public/img/Leaderboard/rank-pic.png differ diff --git a/www/html/Game/public/img/Leaderboard/rank-yourpic.png b/www/html/Game/public/img/Leaderboard/rank-yourpic.png new file mode 100644 index 0000000..4af704e Binary files /dev/null and b/www/html/Game/public/img/Leaderboard/rank-yourpic.png differ diff --git a/www/html/Game/public/img/Leaderboard/txt-player.png b/www/html/Game/public/img/Leaderboard/txt-player.png new file mode 100644 index 0000000..a2cc520 Binary files /dev/null and b/www/html/Game/public/img/Leaderboard/txt-player.png differ diff --git a/www/html/Game/public/img/Leaderboard/txt-rank.png b/www/html/Game/public/img/Leaderboard/txt-rank.png new file mode 100644 index 0000000..e032b44 Binary files /dev/null and b/www/html/Game/public/img/Leaderboard/txt-rank.png differ diff --git a/www/html/Game/public/img/Leaderboard/txt-score.png b/www/html/Game/public/img/Leaderboard/txt-score.png new file mode 100644 index 0000000..fa7e072 Binary files /dev/null and b/www/html/Game/public/img/Leaderboard/txt-score.png differ diff --git a/www/html/Game/public/img/Leaderboard/your-score.png b/www/html/Game/public/img/Leaderboard/your-score.png new file mode 100644 index 0000000..78e8380 Binary files /dev/null and b/www/html/Game/public/img/Leaderboard/your-score.png differ diff --git a/www/html/Game/public/js/room-lobby.js b/www/html/Game/public/js/room-lobby.js index b7df0b5..278c29c 100644 --- a/www/html/Game/public/js/room-lobby.js +++ b/www/html/Game/public/js/room-lobby.js @@ -3709,7 +3709,9 @@ const i = parseInt(hit.getAttribute('data-evidence-tab'), 10); if (!Number.isNaN(i)) syncLobbyEvidenceTabUi(i); }); - const LOBBY_RANK_MEDAL_BASE = typeof appPath === 'function' ? appPath('/Main-Lobby/IMAGE') : '/Main-Lobby/IMAGE'; + const LOBBY_RANK_ASSET_BASE = BASE + '/img/Leaderboard'; + const LOBBY_RANK_BASE_WIDTH = 1107; + const LOBBY_RANK_BASE_HEIGHT = 952; const LOBBY_RANK_MOCK_LEADERS = [ { name: 'Golden L.', score: 9951 }, { name: 'Mixie Kim', score: 9878 }, @@ -3735,27 +3737,51 @@ } } - function buildRankPedestal(rank, entry, medalFile, pedClass) { + function getLobbyPlayerAvatarSrc() { + try { + const composed = (localStorage.getItem('jdCharLobbyIdleDown') || '').trim(); + if (composed) return composed; + } catch (e) { /* ignore */ } + const topRight = document.getElementById('room-lobby-profile-avatar'); + if (topRight && topRight.getAttribute('src')) { + return topRight.getAttribute('src'); + } + return (typeof appPath === 'function' ? appPath('/Game/public/img/characters/char_01_idle_down.png') : (BASE + '/img/characters/char_01_idle_down.png')); + } + + function createAvatarWithTone(src, toneIndex, className) { + const img = document.createElement('img'); + img.className = className || 'lobby-rank-row-avatar'; + img.src = src; + img.alt = ''; + img.decoding = 'async'; + if (toneIndex > 0) { + const hue = (toneIndex * 42) % 360; + img.style.filter = `hue-rotate(${hue}deg) saturate(1.08)`; + } + return img; + } + + function buildRankPedestal(rank, entry, pedClass, toneIndex, avatarSrc) { const wrap = document.createElement('div'); wrap.className = `lobby-rank-ped ${pedClass}`; - if (rank === 1) { - const crown = document.createElement('div'); - crown.className = 'lobby-rank-crown'; - crown.innerHTML = '1'; - wrap.appendChild(crown); - } - const medWrap = document.createElement('div'); - medWrap.className = 'lobby-rank-medal-wrap'; - const img = document.createElement('img'); - img.className = 'lobby-rank-medal-img'; - img.src = `${LOBBY_RANK_MEDAL_BASE}/${medalFile}`; - img.alt = `เหรียญอันดับ ${rank}`; - medWrap.appendChild(img); - wrap.appendChild(medWrap); - const av = document.createElement('div'); - av.className = 'lobby-rank-ped-avatar'; - av.textContent = (entry.name || '?').charAt(0); - wrap.appendChild(av); + const pic = document.createElement('img'); + pic.className = 'lobby-rank-ped-pic'; + pic.src = `${LOBBY_RANK_ASSET_BASE}/${rank}st-pic.png`.replace('/2st-pic', '/2nd-pic').replace('/3st-pic', '/3rd-pic'); + pic.alt = ''; + const picWrap = document.createElement('div'); + picWrap.className = 'lobby-rank-ped-pic-wrap'; + const badge = document.createElement('img'); + badge.className = 'lobby-rank-ped-badge'; + badge.src = `${LOBBY_RANK_ASSET_BASE}/${rank}st.png`.replace('/2st', '/2nd').replace('/3st', '/3rd'); + badge.alt = `อันดับ ${rank}`; + badge.decoding = 'async'; + picWrap.appendChild(pic); + picWrap.appendChild(badge); + const pedAvatar = createAvatarWithTone(avatarSrc, toneIndex, 'lobby-rank-ped-avatar'); + pedAvatar.style.zIndex = '1'; + picWrap.appendChild(pedAvatar); + wrap.appendChild(picWrap); const nm = document.createElement('div'); nm.className = 'lobby-rank-ped-name'; nm.textContent = entry.name || ''; @@ -3772,70 +3798,90 @@ if (titleEl) titleEl.textContent = getLobbyRankCaseTitle(); const sorted = [...LOBBY_RANK_MOCK_LEADERS].sort((a, b) => b.score - a.score); const podium = document.getElementById('lobby-rank-podium'); - const tbody = document.getElementById('lobby-rank-tbody'); + const list = document.getElementById('lobby-rank-list'); const selfFoot = document.getElementById('lobby-rank-self'); - if (!podium || !tbody || !selfFoot) return; + if (!podium || !list || !selfFoot) return; + const playerAvatarSrc = getLobbyPlayerAvatarSrc(); podium.textContent = ''; const first = sorted[0]; const second = sorted[1]; const third = sorted[2]; - if (second) podium.appendChild(buildRankPedestal(2, second, 'leaderboard-2.png', 'lobby-rank-ped--2')); - if (first) podium.appendChild(buildRankPedestal(1, first, 'leaderboard-1.png', 'lobby-rank-ped--1')); - if (third) podium.appendChild(buildRankPedestal(3, third, 'leaderboard-3.png', 'lobby-rank-ped--3')); - tbody.textContent = ''; + if (second) podium.appendChild(buildRankPedestal(2, second, 'lobby-rank-ped--2', 1, playerAvatarSrc)); + if (first) podium.appendChild(buildRankPedestal(1, first, 'lobby-rank-ped--1', 0, playerAvatarSrc)); + if (third) podium.appendChild(buildRankPedestal(3, third, 'lobby-rank-ped--3', 2, playerAvatarSrc)); + list.textContent = ''; for (let i = 3; i < sorted.length && i < 10; i++) { const row = sorted[i]; - const tr = document.createElement('tr'); - const tdR = document.createElement('td'); - tdR.textContent = String(i + 1); - const tdN = document.createElement('td'); - const wrap = document.createElement('div'); - wrap.className = 'lobby-rank-row-av'; - const mav = document.createElement('span'); - mav.className = 'lobby-rank-mini-av'; - mav.textContent = (row.name || '?').charAt(0); - const sp = document.createElement('span'); - sp.className = 'lobby-rank-row-name'; - sp.textContent = row.name || ''; - sp.title = row.name || ''; - wrap.appendChild(mav); - wrap.appendChild(sp); - tdN.appendChild(wrap); - const tdS = document.createElement('td'); - tdS.textContent = String(row.score); - tr.appendChild(tdR); - tr.appendChild(tdN); - tr.appendChild(tdS); - tbody.appendChild(tr); + const rowEl = document.createElement('div'); + rowEl.className = 'lobby-rank-row'; + const rankEl = document.createElement('div'); + rankEl.className = 'lobby-rank-row-rank'; + rankEl.textContent = String(i + 1); + const playerEl = document.createElement('div'); + playerEl.className = 'lobby-rank-row-player'; + const picBg = document.createElement('div'); + picBg.className = 'lobby-rank-row-pic-bg'; + const picFrame = document.createElement('img'); + picFrame.src = `${LOBBY_RANK_ASSET_BASE}/rank-pic.png`; + picFrame.alt = ''; + picFrame.decoding = 'async'; + picBg.appendChild(picFrame); + picBg.appendChild(createAvatarWithTone(playerAvatarSrc, i, 'lobby-rank-row-avatar')); + const nameEl = document.createElement('div'); + nameEl.className = 'lobby-rank-row-name'; + nameEl.textContent = row.name || ''; + nameEl.title = row.name || ''; + playerEl.appendChild(picBg); + playerEl.appendChild(nameEl); + const scoreEl = document.createElement('div'); + scoreEl.className = 'lobby-rank-row-score'; + scoreEl.textContent = String(row.score); + const line = document.createElement('img'); + line.className = 'lobby-rank-row-line'; + line.src = `${LOBBY_RANK_ASSET_BASE}/rank-line.png`; + line.alt = ''; + line.decoding = 'async'; + rowEl.appendChild(rankEl); + rowEl.appendChild(playerEl); + rowEl.appendChild(scoreEl); + rowEl.appendChild(line); + list.appendChild(rowEl); } - selfFoot.textContent = ''; - const selfRank = document.createElement('span'); - selfRank.className = 'lobby-rank-self-rank'; - selfRank.textContent = '28'; - const selfAv = document.createElement('div'); - selfAv.className = 'lobby-rank-self-av'; - selfAv.textContent = (nick || '?').charAt(0); - const meta = document.createElement('div'); - meta.className = 'lobby-rank-self-meta'; - const selfName = document.createElement('div'); - selfName.className = 'lobby-rank-self-name'; - selfName.textContent = nick || 'ผู้เล่น'; - meta.appendChild(selfName); - const selfScore = document.createElement('div'); - selfScore.className = 'lobby-rank-self-score'; - selfScore.textContent = '7250'; - selfFoot.appendChild(selfRank); - selfFoot.appendChild(selfAv); - selfFoot.appendChild(meta); - selfFoot.appendChild(selfScore); + const selfRank = selfFoot.querySelector('.lobby-rank-self-rank'); + const selfName = selfFoot.querySelector('.lobby-rank-self-name'); + const selfScore = selfFoot.querySelector('.lobby-rank-self-score'); + const selfAvatar = selfFoot.querySelector('.lobby-rank-self-avatar'); + if (selfRank) selfRank.textContent = '28'; + if (selfName) selfName.textContent = nick || 'ผู้เล่น'; + if (selfScore) selfScore.textContent = '7250'; + if (selfAvatar) { + selfAvatar.src = playerAvatarSrc; + selfAvatar.alt = nick || 'ผู้เล่น'; + } + } + + function syncLobbyRankScale() { + const dialog = document.querySelector('#lobby-rank-overlay .lobby-rank-dialog'); + if (!dialog) return; + const rect = dialog.getBoundingClientRect(); + if (!rect.width || !rect.height) return; + const scaleW = rect.width / LOBBY_RANK_BASE_WIDTH; + const scaleH = rect.height / LOBBY_RANK_BASE_HEIGHT; + const scale = Math.max(0.28, Math.min(1, Math.min(scaleW, scaleH))); + dialog.style.setProperty('--lrb-scale', String(scale.toFixed(4))); } function openLobbyRankModal() { const ov = document.getElementById('lobby-rank-overlay'); if (!ov) return; - renderLobbyRankModalContent(); ov.classList.remove('is-hidden'); ov.setAttribute('aria-hidden', 'false'); + syncLobbyRankScale(); + renderLobbyRankModalContent(); + requestAnimationFrame(() => { + syncLobbyRankScale(); + renderLobbyRankModalContent(); + }); document.getElementById('lobby-rank-close')?.focus(); } @@ -3846,6 +3892,9 @@ ov.setAttribute('aria-hidden', 'true'); } + window.addEventListener('resize', syncLobbyRankScale); + window.addEventListener('orientationchange', syncLobbyRankScale); + document.getElementById('lobby-b-btn-rank')?.addEventListener('click', () => { if (!isPostCaseLobbyRoom()) return; openLobbyRankModal(); diff --git a/www/html/Game/public/room-lobby.html b/www/html/Game/public/room-lobby.html index 79faeb1..fe27bef 100644 --- a/www/html/Game/public/room-lobby.html +++ b/www/html/Game/public/room-lobby.html @@ -7,9 +7,10 @@ - + +