/
dashirak
/
QuestionSorter
Обзор
Документация
Войти
/
dashirak
/
QuestionSorter
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
index.html
670 строк
19 KB
dashirak
Create: index.html
04 авг 2026, 11:29
Верифицирован
04 авг 2026, 11:29
e6336ed
Код
Авторство
О чём код?
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>🐱 Кото-сортировка: 5 уровней!</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Segoe UI', 'Comic Sans MS', 'Chalkboard SE', cursive, sans-serif; background: linear-gradient(145deg, #f9e7b3 0%, #f5d78e 100%); min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; } .game-box { max-width: 1100px; width: 100%; background: #fffaec; border-radius: 80px 80px 40px 40px; box-shadow: 0 20px 30px rgba(0, 0, 0, 0.2), inset 0 0 0 4px #fce2b1; padding: 25px 20px 35px; border: 6px solid #d9b382; position: relative; } h1 { font-size: 2.6rem; text-align: center; color: #4b2e1b; text-shadow: 4px 4px 0 #f7d48a; display: flex; align-items: center; justify-content: center; gap: 14px; flex-wrap: wrap; margin-bottom: 8px; } h1 span { background: #fce3b1; padding: 0 20px; border-radius: 60px; border: 3px dashed #b47d4e; font-size: 1.8rem; line-height: 1.4; } .level-bar { display: flex; justify-content: center; gap: 12px; flex-wrap: wrap; margin: 12px 0 18px; } .level-btn { background: #eed5b0; border: 4px solid #b98244; border-radius: 50px; padding: 10px 22px; font-size: 1.2rem; font-weight: bold; color: #2d1b0c; box-shadow: 0 5px 0 #7e5f38; cursor: pointer; transition: 0.07s linear; display: inline-flex; align-items: center; gap: 8px; } .level-btn.active { background: #ffd966; transform: translateY(3px); box-shadow: 0 2px 0 #7e5f38; border-color: #d48d2b; } .level-btn:active { transform: translateY(5px); box-shadow: 0 1px 0 #7e5f38; } .cat-row { display: flex; justify-content: space-around; align-items: center; margin: 6px 0 20px; flex-wrap: wrap; gap: 8px; } .cat-badge { background: #fedb9f; border-radius: 100px; padding: 6px 20px 6px 12px; display: inline-flex; align-items: center; gap: 10px; font-size: 1.3rem; font-weight: bold; color: #2d1b0c; border: 3px solid #b47d4e; box-shadow: 0 4px 0 #8b6239; } .cat-badge img { width: 40px; height: 40px; object-fit: contain; filter: drop-shadow(2px 4px 4px rgba(0,0,0,0.2)); } .question-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin: 20px 0 16px; padding: 0 6px; } .question-card { background: #fcefd8; border-radius: 40px 40px 20px 20px; border: 4px solid #c9a16e; padding: 14px 4px 12px; text-align: center; box-shadow: 0 8px 0 #9f7b52; transition: 0.05s ease; } .question-card.active-drop { background: #fff2d0; border-color: #e09d4a; box-shadow: 0 0 0 4px #ffc107, 0 8px 0 #9f7b52; } .question-word { font-size: 2.2rem; font-weight: 800; color: #3d2817; background: #ffdd9e; display: inline-block; padding: 0 16px; border-radius: 60px; letter-spacing: 2px; border: 3px solid #b98244; line-height: 1.6; margin-bottom: 8px; } .drop-zone { min-height: 80px; background: #f5e7cf; border-radius: 30px; border: 4px dashed #ac8a5d; margin: 10px 4px 4px; padding: 10px 6px; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 8px; transition: background 0.2s; } .drop-zone.dragover { background: #ffe9b6; border-color: #e6942b; border-style: solid; } .answer-chip { background: #f5f0e0; border-radius: 60px; padding: 5px 16px; font-size: 1.1rem; font-weight: 600; color: #2f1d0e; border: 3px solid #b68f60; box-shadow: 0 4px 0 #7e623f; display: inline-flex; align-items: center; gap: 6px; background: #ffefd2; pointer-events: none; } .answer-chip.cat-icon::before { content: "🐱"; font-size: 1.2rem; margin-right: 4px; } .apple-basket { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 12px; background: #e3caa3; padding: 18px 22px; border-radius: 100px 100px 40px 40px; margin: 16px 0 14px; border: 6px solid #c29d6b; background: #ecd5b0; min-height: 85px; } .apple-item { background: #ec1f1f; background: radial-gradient(circle at 30% 30%, #ff6b4a, #c42d1c); color: #f9f1d2; padding: 10px 20px; border-radius: 50px; font-size: 1.2rem; font-weight: bold; border: 4px solid #af4d2a; box-shadow: 0 6px 0 #6e2d17, inset 0 -2px 0 #ffb38b; display: inline-flex; align-items: center; gap: 8px; cursor: grab; transition: 0.08s linear; user-select: none; text-shadow: 2px 2px 0 #421f0e; letter-spacing: 1px; } .apple-item:active { cursor: grabbing; opacity: 0.7; } .apple-item.dragging { opacity: 0.3; transform: scale(0.95); } .apple-item:before { content: "🍎"; font-size: 1.6rem; filter: drop-shadow(2px 4px 2px #2f1a0b); } .check-area { display: flex; justify-content: center; gap: 20px; flex-wrap: wrap; margin: 18px 0 12px; } .btn { background: #fed275; border: none; border-radius: 60px; padding: 14px 28px; font-size: 1.6rem; font-weight: bold; color: #2b1d0d; border: 5px solid #b47d4e; box-shadow: 0 9px 0 #7b5b35; cursor: pointer; transition: 0.07s linear; display: inline-flex; align-items: center; gap: 10px; } .btn:active { transform: translateY(6px); box-shadow: 0 3px 0 #7b5b35; } .btn.reset-btn { background: #f5baba; border-color: #b16f6f; box-shadow: 0 9px 0 #7a4848; } .message { font-size: 1.6rem; text-align: center; padding: 12px 16px; background: #f9e6c2; border-radius: 60px; border: 4px solid #b48b52; margin: 16px 0 0; min-height: 4rem; font-weight: 600; color: #342012; display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap; } .message span { font-size: 2.2rem; } .footer-cat { font-size: 1.1rem; text-align: center; margin-top: 14px; color: #5b3b20; } .progress-text { font-size: 1.2rem; background: #dbbd92; padding: 4px 18px; border-radius: 40px; color: #2d1b0c; border: 3px solid #a77b4b; } @media (max-width: 700px) { .question-grid { grid-template-columns: repeat(2, 1fr); gap: 10px; } h1 { font-size: 1.8rem; } .apple-item { font-size: 1rem; padding: 6px 14px; } .level-btn { font-size: 1rem; padding: 6px 14px; } } </style> </head> <body> <div class="game-box" id="gameApp"> <h1> <span>🐈⬛ Кото-сортировка</span> <span style="font-size: 1.6rem;">🌟 5 уровней</span> </h1> <div class="level-bar" id="levelBar"> <button class="level-btn active" data-level="0">🐾 Уровень 1</button> <button class="level-btn" data-level="1">🐾 Уровень 2</button> <button class="level-btn" data-level="2">🐾 Уровень 3</button> <button class="level-btn" data-level="3">🐾 Уровень 4</button> <button class="level-btn" data-level="4">🐾 Уровень 5</button> </div> <div class="cat-row"> <div class="cat-badge"><img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='50' r='45' fill='%23f7d48a'/%3E%3Ccircle cx='35' cy='40' r='8' fill='%23332'/%3E%3Ccircle cx='65' cy='40' r='8' fill='%23332'/%3E%3Ccircle cx='38' cy='38' r='3' fill='white'/%3E%3Ccircle cx='68' cy='38' r='3' fill='white'/%3E%3Cpath d='M40 60 Q50 70,60 60' stroke='%23332' stroke-width='5' fill='none'/%3E%3C/svg%3E" alt="cat"> Тащи яблоки</div> <div class="cat-badge"><span class="progress-text" id="progressDisplay">⭐ 0/5</span></div> </div> <!-- Вопросы и зоны --> <div class="question-grid" id="questionGrid"> <div class="question-card" data-question="what"> <div class="question-word">What</div> <div class="drop-zone" id="dropWhat"></div> </div> <div class="question-card" data-question="who"> <div class="question-word">Who</div> <div class="drop-zone" id="dropWho"></div> </div> <div class="question-card" data-question="where"> <div class="question-word">Where</div> <div class="drop-zone" id="dropWhere"></div> </div> <div class="question-card" data-question="how"> <div class="question-word">How</div> <div class="drop-zone" id="dropHow"></div> </div> </div> <!-- Яблоки-ответы --> <div class="apple-basket" id="appleBasket"></div> <div class="check-area"> <button class="btn" id="checkBtn">🐾 Проверить</button> <button class="btn reset-btn" id="resetBtn">🔄 Сброс</button> </div> <div class="message" id="messageBox"> <span>🐱</span> Перетащи яблоки к вопросам! </div> <div class="footer-cat">🍎 5 уровней — 5 разных наборов ответов</div> </div> <script> (function() { // ---------- ДАННЫЕ УРОВНЕЙ ---------- const levelData = [ { // Уровень 1 what: 'pen', who: 'mum', where: 'in my bag', how: 'happy', answers: ['pen', 'mum', 'in my bag', 'happy'] }, { // Уровень 2 what: 'cake', who: 'boy', where: 'on the table', how: 'tired', answers: ['cake', 'boy', 'on the table', 'tired'] }, { // Уровень 3 what: 'hat', who: 'Shrek', where: 'in my room', how: 'sad', answers: ['hat', 'Shrek', 'in my room', 'sad'] }, { // Уровень 4 what: 'book', who: 'teacher', where: 'at school', how: 'angry', answers: ['book', 'teacher', 'at school', 'angry'] }, { // Уровень 5 what: 'cat', who: 'dad', where: 'in the garden', how: 'hungry', answers: ['cat', 'dad', 'in the garden', 'hungry'] } ]; // ---------- DOM ---------- const dropZones = { what: document.getElementById('dropWhat'), who: document.getElementById('dropWho'), where: document.getElementById('dropWhere'), how: document.getElementById('dropHow') }; const basket = document.getElementById('appleBasket'); const messageBox = document.getElementById('messageBox'); const progressDisplay = document.getElementById('progressDisplay'); const levelBtns = document.querySelectorAll('.level-btn'); let currentLevel = 0; let assigned = { what: null, who: null, where: null, how: null }; let levelCompleted = [false, false, false, false, false]; // ---------- ВСПОМОГАТЕЛЬНЫЕ ---------- function getCorrectMap(level) { const data = levelData[level]; return { what: data.what, who: data.who, where: data.where, how: data.how }; } function getAnswers(level) { return levelData[level].answers.slice(); } // обновить прогресс function updateProgress() { const done = levelCompleted.filter(v => v === true).length; progressDisplay.textContent = `⭐ ${done}/${levelCompleted.length}`; } // ---------- ОТРИСОВКА УРОВНЯ ---------- function renderLevel(level) { // Очищаем зоны for (let key in dropZones) { dropZones[key].innerHTML = ''; assigned[key] = null; } // Очищаем корзину basket.innerHTML = ''; // Заполняем корзину ответами const answers = getAnswers(level); answers.forEach(ans => { const apple = createAppleElement(ans); basket.appendChild(apple); }); // Обновляем сообщение messageBox.innerHTML = `<span>🐱</span> Уровень ${level+1} — сортируй яблоки!`; // Активная кнопка levelBtns.forEach((btn, idx) => { btn.classList.toggle('active', idx === level); }); // Если уровень уже пройден, показываем подсказку if (levelCompleted[level]) { messageBox.innerHTML = `<span>🎉</span> Уровень ${level+1} уже пройден! Можешь повторить.`; } updateProgress(); } // Создать яблоко function createAppleElement(answer) { const div = document.createElement('div'); div.className = 'apple-item'; div.draggable = true; div.dataset.answer = answer; div.textContent = answer; div.addEventListener('dragstart', dragStartHandler); div.addEventListener('dragend', dragEndHandler); return div; } // Найти яблоко в корзине по ответу function findAppleInBasket(answer) { const items = basket.querySelectorAll('.apple-item'); for (let item of items) { if (item.dataset.answer === answer) return item; } return null; } // ---------- DRAG & DROP ---------- function dragStartHandler(e) { const target = e.target.closest('.apple-item'); if (!target) return; if (target.closest('.drop-zone')) { e.preventDefault(); return false; } e.dataTransfer.setData('text/plain', target.dataset.answer); e.dataTransfer.effectAllowed = 'move'; target.classList.add('dragging'); } function dragEndHandler(e) { const target = e.target.closest('.apple-item'); if (target) target.classList.remove('dragging'); } function setupDropZones() { for (let key in dropZones) { const zone = dropZones[key]; zone.addEventListener('dragover', (e) => { e.preventDefault(); e.dataTransfer.dropEffect = 'move'; zone.classList.add('dragover'); }); zone.addEventListener('dragleave', () => { zone.classList.remove('dragover'); }); zone.addEventListener('drop', (e) => { e.preventDefault(); zone.classList.remove('dragover'); const answer = e.dataTransfer.getData('text/plain'); if (!answer) return; // Ищем яблоко в корзине const sourceApple = findAppleInBasket(answer); if (!sourceApple) return; // Если в зоне уже есть ответ - возвращаем его в корзину const existingChip = zone.querySelector('.answer-chip'); if (existingChip) { const oldAnswer = existingChip.dataset.answer; existingChip.remove(); // убираем из assigned for (let q in assigned) { if (assigned[q] === oldAnswer) { assigned[q] = null; break; } } // возвращаем яблоко в корзину const oldApple = createAppleElement(oldAnswer); basket.appendChild(oldApple); } // Удаляем яблоко из корзины sourceApple.remove(); // Создаём чип в зоне const chip = document.createElement('div'); chip.className = 'answer-chip cat-icon'; chip.dataset.answer = answer; chip.textContent = answer; zone.appendChild(chip); assigned[key] = answer; messageBox.innerHTML = `<span>🐈</span> "${answer}" → ${key.toUpperCase()}!`; }); } } // ---------- ПРОВЕРКА ---------- function checkAnswers() { const correct = getCorrectMap(currentLevel); let allCorrect = true; let details = []; for (let key in correct) { const userAns = assigned[key]; const correctAns = correct[key]; if (userAns === correctAns) { details.push(`✅ ${key.toUpperCase()} → "${userAns}"`); } else { allCorrect = false; details.push(`❌ ${key.toUpperCase()} → "${userAns || 'пусто'}" (должно: "${correctAns}")`); } } if (allCorrect) { levelCompleted[currentLevel] = true; updateProgress(); messageBox.innerHTML = `<span>🎉🐱✨</span> Уровень ${currentLevel+1} пройден! Отлично!<br><span style="font-size:1rem;">${details.join(' | ')}</span>`; } else { messageBox.innerHTML = `<span>😿❌</span> Не всё верно. Попробуй ещё!<br><span style="font-size:1rem;">${details.join(' | ')}</span>`; } } // ---------- СБРОС УРОВНЯ ---------- function resetLevel() { // просто перерисовать уровень renderLevel(currentLevel); messageBox.innerHTML = `<span>🔄</span> Уровень ${currentLevel+1} сброшен.`; } // ---------- ПЕРЕКЛЮЧЕНИЕ УРОВНЯ ---------- function switchLevel(level) { if (level < 0 || level >= levelData.length) return; currentLevel = level; renderLevel(level); } // ---------- ИНИЦИАЛИЗАЦИЯ ---------- function init() { // Кнопки уровней levelBtns.forEach((btn, idx) => { btn.addEventListener('click', () => { switchLevel(idx); }); }); // Кнопки проверки и сброса document.getElementById('checkBtn').addEventListener('click', checkAnswers); document.getElementById('resetBtn').addEventListener('click', resetLevel); setupDropZones(); renderLevel(0); updateProgress(); // дополнительно обновляем при изменениях в корзине const observer = new MutationObserver(() => { // ничего не делаем, но можно обновить }); observer.observe(basket, { childList: true, subtree: false }); } init(); })(); </script> </body> </html>