From 5884ea55f9d589571cb2b59790fac06e39ae9e8e Mon Sep 17 00:00:00 2001 From: jahlib <60108339+jahlib@users.noreply.github.com> Date: Mon, 10 Nov 2025 15:53:34 +0300 Subject: [PATCH] MORE QUICK REACTIONS --- client/game.js | 63 +++++++++++++++++++++++++++++++++++++++++++++-- client/index.html | 35 +++++++++++++++++++++----- client/style.css | 56 +++++++++++++++++++++++++++++++++++------ 3 files changed, 138 insertions(+), 16 deletions(-) diff --git a/client/game.js b/client/game.js index d1143b5..b90cada 100644 --- a/client/game.js +++ b/client/game.js @@ -1791,12 +1791,71 @@ class CardGame { const rect = playerHand.getBoundingClientRect(); // Позиционируем пикер НАД блоком руки по центру - // Ширина пикера: 6 кнопок * 50px + отступы (8px * 7) = 356px const vh = window.innerHeight / 100; - this.reactionPicker.style.left = `${rect.left + rect.width / 2 - 178}px`; // Центрируем + this.reactionPicker.style.left = `${rect.left + rect.width / 2}px`; + this.reactionPicker.style.transform = 'translateX(-50%)'; this.reactionPicker.style.top = `${rect.top - 70 - vh}px`; // Над рукой + 1vh выше this.reactionPicker.classList.add('active'); + + // Предотвращаем конфликт свайпа с другими элементами + const scrollContainer = this.reactionPicker.querySelector('.reaction-picker-scroll'); + if (scrollContainer) { + scrollContainer.addEventListener('touchstart', (e) => { + e.stopPropagation(); + }, { passive: true, once: false }); + + scrollContainer.addEventListener('touchmove', (e) => { + e.stopPropagation(); + }, { passive: true, once: false }); + + // Drag-скролл мышкой (как на телефоне) + let isDown = false; + let startX; + let scrollLeft; + let hasMoved = false; + + scrollContainer.addEventListener('mousedown', (e) => { + isDown = true; + hasMoved = false; + scrollContainer.style.scrollBehavior = 'auto'; + startX = e.pageX; + scrollLeft = scrollContainer.scrollLeft; + }); + + scrollContainer.addEventListener('mouseleave', () => { + isDown = false; + scrollContainer.style.scrollBehavior = 'smooth'; + }); + + scrollContainer.addEventListener('mouseup', () => { + isDown = false; + scrollContainer.style.scrollBehavior = 'smooth'; + }); + + scrollContainer.addEventListener('mousemove', (e) => { + if (!isDown) return; + e.preventDefault(); + const x = e.pageX; + const walk = x - startX; + + // Если сдвинули больше чем на 5px, считаем это скроллом + if (Math.abs(walk) > 5) { + hasMoved = true; + } + + scrollContainer.scrollLeft = scrollLeft - walk; + }); + + // Предотвращаем клик на кнопках если был скролл + scrollContainer.addEventListener('click', (e) => { + if (hasMoved) { + e.preventDefault(); + e.stopPropagation(); + hasMoved = false; + } + }, true); + } } hideReactionPicker() { diff --git a/client/index.html b/client/index.html index 4cebea5..dedeebb 100644 --- a/client/index.html +++ b/client/index.html @@ -247,12 +247,35 @@
- - - - - - +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/client/style.css b/client/style.css index 2646e9a..df000ca 100644 --- a/client/style.css +++ b/client/style.css @@ -383,7 +383,8 @@ input[type="text"]:focus { .hint { color: #666; font-size: 14px; - margin-top: 10px; + margin-top: -10px; + padding-bottom: 10px; } .hint-small { @@ -483,7 +484,6 @@ input[type="text"]:focus { /* Countdown Timer */ #countdown-display { - margin: 30px 0; text-align: center; } @@ -511,14 +511,14 @@ input[type="text"]:focus { justify-content: center; box-shadow: 0 4px 12px rgba(50, 160, 130, 0.4); animation: pulse 1s ease-in-out infinite; - font-size: 20px; + font-size: 18px; font-weight: bold; color: white; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); } #countdown-number { - font-size: 72px; + font-size: 22px; font-weight: bold; color: white; text-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); @@ -1728,6 +1728,21 @@ border: 2px solid #ffd700; font-size: 2em; } + h2 { + font-size: 1.5em; + } + + .room-header { + gap: 8px; + margin-bottom: 20px; + } + + .countdown-timer-small { + width: 42px; + height: 42px; + font-size: 17px; + } + .game-table { padding: 4px; /* Учитываем safe area на iOS */ @@ -2252,26 +2267,51 @@ border: 2px solid #ffd700; position: fixed; background: rgba(30, 30, 30, 0.95); border-radius: 12px; - padding: 8px; - gap: 8px; + padding: 1px; z-index: 10000; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); animation: popIn 0.2s ease-out; + max-width: min(500px, 90vw); } .reaction-picker.active { + display: block; +} + +.reaction-picker-scroll { display: flex; + gap: 8px; + overflow-x: auto; + overflow-y: hidden; + -webkit-overflow-scrolling: touch; + scroll-behavior: smooth; + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE/Edge */ + padding: 12px; + cursor: grab; + user-select: none; +} + +.reaction-picker-scroll:active { + cursor: grabbing; +} + +.reaction-picker-scroll::-webkit-scrollbar { + display: none; /* Chrome/Safari */ } .reaction-btn { width: 50px; height: 50px; + min-width: 50px; + min-height: 50px; border: none; background: rgba(255, 255, 255, 0.1); border-radius: 8px; font-size: 28px; cursor: pointer; transition: all 0.2s ease; + flex-shrink: 0; } .reaction-btn:hover { @@ -2286,11 +2326,11 @@ border: 2px solid #ffd700; @keyframes popIn { from { opacity: 0; - transform: scale(0.8); + transform: scale(0.8) translateX(-50%); } to { opacity: 1; - transform: scale(1); + transform: scale(1) translateX(-50%); } }