undefined / index.html
ladalegends's picture
Manual changes saved
bc65b21 verified
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Minecraft Live Бинго 2025</title>
<link href="https://fonts.googleapis.com/css2?family=Golos+Text:wght@400;600&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Unbounded:wght@600&display=swap" rel="stylesheet">
<style>
* {
margin:0;
padding:0;
box-sizing:border-box;
-webkit-tap-highlight-color: transparent;
}
body {
overflow-x: hidden;
width: 100%;
font-family:'Golos Text', sans-serif;
background:#fff;
color:#222;
padding:10px;
text-align:center;
min-height:100vh;
display: flex;
flex-direction: column;
align-items: center;
}
.container {
width: 100%;
max-width: 800px;
display: flex;
flex-direction: column;
align-items: center;
padding: 0 5px;
flex: 1;
}
.header {
margin-bottom:20px;
position: relative;
display: inline-block;
}
.header img {
max-width:320px;
width:80vw;
height:auto;
position: relative;
z-index:1;
display:block;
transition: all 0.3s ease;
}
.header::before {
content:"";
position:absolute;
top:50%; left:50%;
width:200%; height:200%;
left: 50%;
background:radial-gradient(circle, rgba(74,222,128,0.4), transparent 70%);
transform:translate(-50%,-50%);
filter: blur(40px);
opacity:0;
transition:opacity 0.8s ease;
pointer-events:none;
border-radius:50%;
z-index:0;
}
.header.glow::before {opacity:1;}
.header img {
max-width: min(320px, 90vw);
width: auto;
height: auto;
position: relative;
z-index:1;
display: block;
margin: 0 auto;
transition: all 0.3s ease;
}
#logoBingo {position:absolute; top:0; left:0; opacity:0; width:100%; height:auto;}
.bingo-status {
font-size: clamp(18px, 6vw, 25px);
font-weight:bold;
font-family: Golos Text;
color:#28663e;
margin-top:0px;
margin-bottom: 15px;
opacity:0;
transform:translateY(40px);
transition:all .3s ease;
position: relative;
z-index:1;
text-align: center;
width: 100%;
}
.bingo-status.show {opacity:1; transform:translateY(0);}
.bingo-grid {
display:grid;
grid-template-columns:repeat(5, minmax(0, 1fr));
gap:8px;
width: 100%;
max-width: 800px;
margin:-10px auto;
justify-items: center;
padding: 0 5px;
box-sizing: border-box;
justify-content: center;
}
.bingo-card {
background:#ffffff;
border:1px solid #f0f0f0;
border-radius:15px;
text-align:center;
cursor:pointer;
display:flex;
align-items:center;
justify-content:center;
padding:2px;
font-size: clamp(10px, 3vw, 17px);
font-weight: 560;
line-height:1.2;
transition: all 0.3s ease;
opacity:0;
transform:translateY(20px);
color: #2e2e2e;
overflow: hidden;
overflow-wrap: break-word;
word-break: break-word;
hyphens: auto;
text-wrap: pretty;
width: 100%;
aspect-ratio: 1/1;
max-height: 13vh;
min-height: 60px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-touch-callout: none;
}
.bingo-card > div {
white-space: normal;
overflow-wrap: break-word;
word-break: normal;
hyphens: auto;
text-wrap: pretty;
width: 100%;
padding: 2px;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
line-height: 1.3;
word-spacing: normal;
}
.bingo-card.show {opacity:1; transform:translateY(0);}
.bingo-card:hover {background:#f6f6f6; scale: 1.03; border-color: #dedede;}
.bingo-card.completed {background:#dcfce7; border-color:#4ade8083; transition: all 0.4s ease;}
.tooltip {
position: fixed;
background: rgb(255, 255, 255);
backdrop-filter: blur(8px);
color:#222;
padding:20px;
border-radius:12px;
font-size:16px;
line-height:1.5;
box-shadow:0 8px 24px rgba(0, 0, 0, 0.118);
pointer-events:none;
opacity:0;
transform:translateY(10px);
transition: all 0.3s ease;
z-index:1000;
max-width:300px;
text-align:left;
}
.tooltip.show {opacity:1; transform:translateY(0);}
.tooltip .title {font-weight:600; margin-bottom:8px; font-family:'Unbounded', sans-serif;}
.tooltip .desc {font-weight:400; font-size:14px; color:#555;}
.modal {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background: rgba(255, 255, 255, 0.98);
backdrop-filter: blur(10px);
padding: 20px;
box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.15);
transform: translateY(100%);
transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275), opacity 0.3s ease;
z-index: 1000;
height: auto;
max-height: 70vh;
overflow-y: auto;
display: none;
border-top-left-radius: 15px;
border-top-right-radius: 15px;
will-change: transform;
opacity: 0;
}
.modal.show {
opacity: 1;
transform: translateY(0);
transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275), opacity 0.3s ease;
}
.modal.show {
display: block;
transform: translateY(0);
transition-timing-function: cubic-bezier(0.17, 0.67, 0.24, 0.99);
}
.modal.closing {
transform: translateY(100%);
transition-timing-function: cubic-bezier(0.5, 0, 0.75, 0);
}
.modal .title {
font-weight:600;
margin-bottom:8px;
font-family:'Unbounded', sans-serif;
font-size: clamp(16px, 5vw, 20px);
}
.modal .desc {
font-weight:400;
font-size: clamp(14px, 4vw, 16px);
color:#555;
margin-bottom:20px;
line-height: 1.4;
}
.modal button {
display: block;
width: 100%;
margin-top: 10px;
padding: 12px;
border: none;
border-radius: 8px;
font-size: 16px;
cursor: pointer;
font-family: 'Golos Text', sans-serif;
font-weight: 600;
-webkit-tap-highlight-color: transparent;
}
.modal #toggleBtn {background: #4ade80; color: white;}
.modal #closeModal {background: #eee; color: #222;}
.footer {
margin-top: 0px;
margin-bottom: -10px;
padding: 20px 0;
color: #8888888a;
font-size: 14px;
text-align: center;
width: 100%;
}
@media (max-width: 380px) {
.bingo-grid {
gap: 5px;
grid-template-columns: repeat(5, minmax(60px, 1fr));
width: 100%;
margin-top: 35%;
padding: 0 8px;
box-sizing: border-box;
justify-content: center;
}
.bingo-card {
padding: 5px 3px;
border-radius: 8px;
font-size: clamp(9px, 2.8vw, 15px);
min-height: 50px;
width: 100%;
max-width: 72px;
}
.modal {
padding: 15px;
max-height: 70vh;
}
body {
overflow-x: hidden;
width: 100%;
}
}
/* Адаптация для горизонтальной ориентации */
@media (max-height: 500px) and (orientation: landscape) {
.container {
max-width: 95vw;
}
.bingo-card {
max-height: 25vh;
min-height: 50px;
font-size: clamp(8px, 2.5vw, 14px);
}
.header img {
max-width: 200px;
}
.bingo-status {
margin-bottom: 10px;
}
.footer {
padding: 10px 0;
font-size: 12px;
}
}
@media (max-width: 768px) {
input, select, textarea {
font-size: 16px;
}
.bingo-grid {
justify-content: center;
padding: 0 5px;
margin-top: 10%;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header" id="headerBox">
<img id="logoDefault" src="images/bingo.png" alt="Minecraft Bingo">
<img id="logoBingo" src="images/bingo_green.png" alt="Minecraft Bingo">
<div class="bingo-status" id="bingoStatus">Бинго!</div>
</div>
<div class="bingo-grid" id="bingoGrid"></div>
</div>
<div class="footer">Скрафтил: @LadaLegends<br>Таблицу сделал: @dronyara01</div>
<div class="tooltip" id="tooltip"></div>
<div class="modal" id="modal">
<div class="title"></div>
<div class="desc"></div>
<button id="toggleBtn">Отметить как выполненное</button>
<button id="closeModal">Закрыть</button>
</div>
<script>
const bingoItems = [
{text:"Анонс нового дропа", tooltip:{title:"Анонс нового дропа", desc:"Объявление о новом дропе."}},
{text:"Анонс 1.22", tooltip:{title:"Анонс 1.22", desc:"Официальное объявление следующего крупного обновления."}},
{text:"Анонс Dungeons 2", tooltip:{title:"Анонс Minecraft Dungeons 2", desc:"Продолжение Minecraft Dungeons."}},
{text:"Анонс второго фильма", tooltip:{title:"Анонс второго фильма", desc:"Анонс второй части Minecraft Movie."}},
{text:"Комьюнити шоу и прешоу", tooltip:{title:"Комьюнити шоу и прешоу", desc:"Мероприятие, которое проходит перед основной частью трансляции для разогрева."}},
{text:"Водное обновление 2", tooltip:{title:"Водное обновление 2", desc:"Еще одно обновление водной фауны."}},
{text:"Кринж на Minecraft Live", tooltip:{title:"Кринж на Minecraft Live", desc:"Смешные моменты во время трансляции."}},
{text:"Контент с прошлых голосований", tooltip:{title:"Контент с прошлых голосований", desc:"Возвращение контента из голосований"}},
{text:"Копье", tooltip:{title:"Копье", desc:"Новое оружие из сливов."}},
{text:"Живая раковина наутилуса", tooltip:{title:"Живая раковина наутилуса", desc:"Новый моб в виде раковины наутилуса."}},
{text:"Обновление энда", tooltip:{title:"Обновление энда", desc:"Долгожданное обновление измерения Край."}},
{text:"Мульт-сериал на Netflix", tooltip:{title:"Мульт-сериал на Netflix", desc:"Анимационный сериал по Minecraft."}},
{text:"Смешной джеб", tooltip:{title:"Смешное появление Джеба", desc:"Джеб смешно появляется в кадре."}},
{text:"Коллаборация", tooltip:{title:"Коллаборация с брендом", desc:"Очередная коллаборация с известным (или не очень) брендом."}},
{text:"Много воды", tooltip:{title:"Много воды", desc:"Настолько много ненужной информации, что хватило бы на целое водное обновление."}},
{text:"Vibrant Visuals на джаве", tooltip:{title:"Vibrant Visuals на джаве", desc:"Поддержка встроенных официальных для Java издания"}},
{text:"Функционал стола лучника", tooltip:{title:"Функционал для стола лучника", desc:"На данный момент стол лучника не имеет функционала, и нужен только для профессии жителей."}},
{text:"Новая книга", tooltip:{title:"Новая книга по Minecraft", desc:"Mojang показывает новую книгу по своей игре."}},
{text:"Функционал старого предмета", tooltip:{title:"Функционал для старого предмета", desc:"В игру добавляют новый функционал для старого предмета или блока, которого давно не обновляли."}},
{text:"Новые вариации мобов", tooltip:{title:"Новые вариации для мобов", desc:"Недавно были добавлены новые вариации для свиней, куриц и коров. Почему-бы не добавить для остальных?"}},
{text:"Новый плащ", tooltip:{title:"Новый плащ", desc:"Новый косметический предмет в виде плаща в честь чего-либо, который нам покажут на трансляции."}},
{text:"Животное из реального мира", tooltip:{title:"Животное из реального мира", desc:"Новый моб, который имеет аналог в реальном мире."}},
{text:"Обновление старого биома", tooltip:{title:"Обновление старого биома", desc:"Добавление новых структур или механик в уже существующие биомы."}},
{text:"Новый тип деревни", tooltip:{title:"Новый тип деревни", desc:"Добавление нового типа деревни с уникальной архитектурой."}},
{text:"Новый мерч", tooltip:{title:"Новый мерч", desc:"Добавление нового мерча под брендом Mojang."}},
];
let completedCards = new Set();
let tooltip = document.getElementById('tooltip');
let tooltipTimer;
const isMobile = 'ontouchstart' in document.documentElement;
let currentIndex;
let scrollY = 0;
function adjustFontSize(element) {
const card = element.parentElement;
const text = element.textContent;
const length = text.length;
const words = text.split(' ');
const longestWord = words.reduce((a, b) => a.length > b.length ? a : b, '');
// Устанавливаем базовый размер шрифта
let fontSize = 'clamp(11px, 3vw, 16px)';
// Динамическое изменение размера шрифта
if (length > 50) {
fontSize = 'clamp(8px, 2.2vw, 12px)';
} else if (length > 30) {
fontSize = 'clamp(9px, 2.5vw, 14px)';
} else if (length > 20) {
fontSize = 'clamp(10px, 2.8vw, 15px)';
}
element.style.fontSize = fontSize;
// Проверяем, помещается ли текст
if (element.scrollHeight > card.clientHeight || element.scrollWidth > card.clientWidth) {
let currentSize = parseFloat(fontSize);
while ((element.scrollHeight > card.clientHeight || element.scrollWidth > card.clientWidth) && currentSize > 8) {
currentSize -= 0.5;
element.style.fontSize = `${currentSize}px`;
}
}
// Улучшаем перенос длинных слов
if (longestWord.length > 10) {
element.style.wordBreak = 'break-word';
element.style.hyphens = 'auto';
} else {
element.style.wordBreak = 'normal';
element.style.hyphens = 'none';
}
// Улучшаем перенос для коротких слов
element.style.overflowWrap = 'break-word';
}
function initializeBingo(){
const grid=document.getElementById('bingoGrid'); grid.innerHTML='';
bingoItems.forEach((item,i)=>{
const card=document.createElement('div'); card.className='bingo-card'; card.dataset.index=i;
const textDiv = document.createElement('div');
textDiv.textContent = item.text;
card.appendChild(textDiv);
if (!isMobile) {
card.addEventListener('mouseenter',(e)=>{tooltipTimer=setTimeout(()=>showTooltip(e,item.tooltip),300);});
card.addEventListener('mouseleave',()=>{clearTimeout(tooltipTimer); hideTooltip();});
}
card.addEventListener('click',() => {
if (isMobile) {
showModal(item.tooltip, i);
} else {
toggleCard(i);
}
});
grid.appendChild(card);
setTimeout(() => {
card.classList.add('show');
adjustFontSize(textDiv);
}, i*50); // Уменьшили задержку для более быстрой загрузки
});
document.getElementById('toggleBtn').addEventListener('click', () => {
toggleCard(currentIndex);
updateToggleBtn();
hideModal();
});
document.getElementById('closeModal').addEventListener('click', () => {
hideModal();
});
// Adjust on resize for responsiveness
window.addEventListener('resize', () => {
document.querySelectorAll('.bingo-card div').forEach(adjustFontSize);
});
// Adjust on orientation change
window.addEventListener('orientationchange', () => {
setTimeout(() => {
document.querySelectorAll('.bingo-card div').forEach(adjustFontSize);
}, 300);
});
}
function toggleCard(i){
const card=document.querySelector(`[data-index="${i}"]`);
if(completedCards.has(i)){
completedCards.delete(i);
card.classList.remove('completed');
// Removed click animation that was causing logo to move
} else {
completedCards.add(i);
card.classList.add('completed');
card.classList.add('click-animate');
setTimeout(() => card.classList.remove('click-animate'), 200);
}
checkBingo();
if (isMobile) updateToggleBtn();
}
function updateToggleBtn(){
const toggleBtn = document.getElementById('toggleBtn');
if(completedCards.has(currentIndex)){
toggleBtn.textContent = 'Отменить отметку';
toggleBtn.style.background = '#f87171';
} else {
toggleBtn.textContent = 'Отметить как выполненное';
toggleBtn.style.background = '#4ade80';
}
}
function getWinningLine(){
const size = 5;
const grid = Array.from({length:size},()=>Array(size).fill(null));
completedCards.forEach(i=>{
const row = Math.floor(i/size);
const col = i % size;
if(row<size && col<size) grid[row][col] = true;
});
// проверка строк
for(let r=0;r<size;r++){
if(grid[r].every(cell => cell === true)) return true;
}
// проверка столбцов
for(let c=0;c<size;c++){
if(grid.every(row => row[c] === true)) return true;
}
// диагонали
if(grid.every((row,i) => row[i] === true)) return true;
if(grid.every((row,i) => row[size-1-i] === true)) return true;
return false;
}
function checkBingo(){
const status=document.getElementById('bingoStatus');
const logoDefault=document.getElementById('logoDefault');
const logoBingo=document.getElementById('logoBingo');
const header=document.getElementById('headerBox');
if(getWinningLine()){
status.classList.add('show'); header.classList.add('glow');
logoDefault.style.transform="scale(0.90) translateY(-20px)";
logoBingo.style.transform="scale(0.90) translateY(-20px)";
logoBingo.style.opacity=1; logoDefault.style.opacity=0;
} else {
status.classList.remove('show'); header.classList.remove('glow');
logoDefault.style.transform="scale(1) translateY(0)";
logoBingo.style.transform="scale(1) translateY(0)";
logoBingo.style.opacity=0; logoDefault.style.opacity=1;
}
}
function showTooltip(e,tooltipData){
tooltip.innerHTML=`<div class="title">${tooltipData.title}</div><div class="desc">${tooltipData.desc}</div>`;
tooltip.classList.add('show'); moveTooltip(e);
}
function hideTooltip(){tooltip.classList.remove('show');}
function moveTooltip(e){tooltip.style.left=e.clientX+12+'px'; tooltip.style.top=e.clientY-40+'px';}
function showModal(tooltipData, index){
document.querySelector('.modal .title').innerHTML = tooltipData.title;
document.querySelector('.modal .desc').innerHTML = tooltipData.desc;
currentIndex = index;
updateToggleBtn();
scrollY = window.scrollY;
document.body.style.position = 'fixed';
document.body.style.top = `-${scrollY}px`;
document.body.style.overflow = 'hidden';
const modal = document.getElementById('modal');
modal.classList.remove('closing');
// Анимация появления
modal.style.transform = 'translateY(100%)';
modal.style.display = 'block';
requestAnimationFrame(() => {
modal.classList.add('show');
modal.style.transform = 'translateY(0)';
});
}
function hideModal(){
const modal = document.getElementById('modal');
modal.classList.remove('show');
modal.classList.add('closing');
modal.style.transform = 'translateY(100%)';
setTimeout(() => {
modal.classList.remove('closing');
modal.style.display = 'none';
const storedScrollY = document.body.style.top;
document.body.style.position = '';
document.body.style.top = '';
document.body.style.overflow = '';
window.scrollTo(0, parseInt(storedScrollY || '0') * -1);
}, 300);
}
document.addEventListener('DOMContentLoaded',initializeBingo);
</script>
</body>
</html>