Skip to content

Рефлексия #61

@Sensei9797-hub

Description

@Sensei9797-hub

<!doctype html>

<title>Интерактивная рефлексия — Тригонометрические функции (9 класс)</title> <style> :root{ --bg:#0b1220; --card:#0f1a33; --card2:#0c1730; --text:#eaf0ff; --muted:#a9b4d6; --line:#23335f; --ok:#31d07b; --bad:#ff5b6e; --warn:#ffcc66; --btn:#2b6cff; --btn2:#1d2d5a; --shadow: 0 14px 45px rgba(0,0,0,.35); --radius: 18px; } *{box-sizing:border-box} body{ margin:0; font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, "Noto Sans", sans-serif; background: radial-gradient(1200px 800px at 20% 10%, #1a2c66 0%, transparent 55%), radial-gradient(1000px 700px at 85% 25%, #2a145a 0%, transparent 55%), var(--bg); color:var(--text); min-height:100vh; display:flex; align-items:flex-start; justify-content:center; padding:24px; } .wrap{ width:min(980px, 100%); display:grid; gap:16px; } header{ background: linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.02)); border:1px solid rgba(255,255,255,.10); border-radius: var(--radius); box-shadow: var(--shadow); padding:18px 18px 14px; display:flex; gap:14px; align-items:flex-start; justify-content:space-between; flex-wrap:wrap; } .title h1{ margin:0 0 6px; font-size:20px; letter-spacing:.2px; } .title p{ margin:0; color:var(--muted); font-size:14px; line-height:1.35; } .badgeRow{ display:flex; gap:10px; flex-wrap:wrap; align-items:center; justify-content:flex-end; } .badge{ border:1px solid rgba(255,255,255,.14); background: rgba(255,255,255,.05); padding:8px 10px; border-radius: 999px; color: var(--muted); font-size:13px; display:flex; gap:8px; align-items:center; white-space:nowrap; } .dot{width:10px;height:10px;border-radius:999px;background:var(--warn)} .dot.ok{background:var(--ok)} .dot.bad{background:var(--bad)} .grid{ display:grid; grid-template-columns: 1.15fr .85fr; gap:16px; } @media (max-width: 900px){ .grid{grid-template-columns:1fr} } .card{ background: linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.02)); border:1px solid rgba(255,255,255,.10); border-radius: var(--radius); box-shadow: var(--shadow); overflow:hidden; } .cardHead{ padding:14px 16px; border-bottom:1px solid rgba(255,255,255,.08); display:flex; align-items:center; justify-content:space-between; gap:10px; background: rgba(0,0,0,.10); } .cardHead h2{ margin:0; font-size:16px; letter-spacing:.2px; } .cardHead small{color:var(--muted)} .cardBody{padding:14px 16px} .note{ color:var(--muted); font-size:13px; line-height:1.4; margin:0 0 10px; } .row{display:flex; gap:10px; flex-wrap:wrap} .btn{ appearance:none; border:1px solid rgba(255,255,255,.16); background: linear-gradient(180deg, rgba(43,108,255,.95), rgba(43,108,255,.75)); color:white; padding:10px 12px; border-radius:12px; cursor:pointer; font-weight:600; transition:.15s transform, .15s filter; user-select:none; } .btn:hover{transform: translateY(-1px); filter:brightness(1.03)} .btn:active{transform: translateY(0px); filter:brightness(.98)} .btn.secondary{ background: rgba(255,255,255,.06); color: var(--text); } .btn.ghost{ background: transparent; color: var(--muted); } .pill{ display:inline-flex; gap:8px; align-items:center; border:1px solid rgba(255,255,255,.14); background: rgba(0,0,0,.15); padding:8px 10px; border-radius: 999px; font-size:13px; color: var(--muted); } .q{ border:1px solid rgba(255,255,255,.10); background: rgba(0,0,0,.14); border-radius: 14px; padding:12px; margin:10px 0; } .qTop{ display:flex; gap:10px; align-items:flex-start; justify-content:space-between; } .qTitle{ font-weight:700; font-size:14px; margin:0; } .tag{ font-size:12px; color: var(--muted); border:1px solid rgba(255,255,255,.12); padding:4px 8px; border-radius:999px; white-space:nowrap; background: rgba(255,255,255,.04); } .options{margin-top:10px; display:grid; gap:8px} label.opt{ display:flex; gap:10px; align-items:flex-start; border:1px solid rgba(255,255,255,.10); background: rgba(255,255,255,.03); padding:10px 10px; border-radius: 12px; cursor:pointer; transition:.12s background, .12s border-color; } label.opt:hover{background: rgba(255,255,255,.05)} input[type="radio"]{margin-top:3px} .feedback{ margin-top:10px; font-size:13px; color: var(--muted); display:none; } .feedback.ok{color: var(--ok)} .feedback.bad{color: var(--bad)} .divider{ height:1px; background: rgba(255,255,255,.10); margin:12px 0; } .scale{ display:grid; grid-template-columns: 1fr; gap:10px; } .scaleBox{ border:1px solid rgba(255,255,255,.10); background: rgba(0,0,0,.14); border-radius: 14px; padding:12px; } .scaleBox h3{ margin:0 0 8px; font-size:14px; } .rangeRow{ display:flex; gap:10px; align-items:center; flex-wrap:wrap; } input[type="range"]{ width: 100%; accent-color: var(--btn); } .rangeMeta{ display:flex; justify-content:space-between; color:var(--muted); font-size:12px; margin-top:6px; } textarea{ width:100%; min-height:90px; resize:vertical; border-radius:14px; padding:10px 12px; border:1px solid rgba(255,255,255,.12); background: rgba(255,255,255,.03); color: var(--text); outline:none; } textarea::placeholder{color:rgba(234,240,255,.45)} .mini{ font-size:12px; color: var(--muted); margin-top:8px; line-height:1.35; } .resultBox{ border:1px solid rgba(255,255,255,.10); background: linear-gradient(180deg, rgba(0,0,0,.18), rgba(0,0,0,.10)); border-radius: 14px; padding:12px; } .resultBox h3{margin:0 0 8px; font-size:14px} .big{ font-size:34px; font-weight:900; letter-spacing:.3px; margin:6px 0 2px; } .hint{ color: var(--muted); font-size:13px; line-height:1.4; margin:0; } .list{ margin:10px 0 0; padding-left:18px; color: var(--muted); font-size:13px; line-height:1.5; } .kbd{ font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size:12px; padding:2px 6px; border-radius:8px; border:1px solid rgba(255,255,255,.14); background: rgba(255,255,255,.05); color: var(--text); } </style>

Интерактивная рефлексия: «Определение тригонометрических функций»

Цель обучения: 9.2.4.1 — знать определения тригонометрических функций.
Формат: мини-квиз (самопроверка) + самооценка + «выходной билет».

Ещё не проверено
00:00
💾 автосохранение: выкл.
<div class="grid">
  <!-- LEFT: quiz -->
  <section class="card">
    <div class="cardHead">
      <h2>1) Быстрая самопроверка (5 вопросов)</h2>
      <small>выбирай варианты — затем «Проверить»</small>
    </div>
    <div class="cardBody" id="quiz">
      <p class="note">
        Здесь проверяем именно <b>определения</b>. Без «танцев с бубном» — только база.
      </p>

      <!-- Questions injected by JS -->

      <div class="divider"></div>

      <div class="row">
        <button class="btn" id="checkBtn">Проверить</button>
        <button class="btn secondary" id="resetBtn">Сбросить</button>
        <button class="btn ghost" id="fillDemoBtn" title="Заполнить случайно (для демонстрации)">Демо-заполнение</button>
      </div>

      <p class="mini">
        Подсказка: после проверки откроются краткие комментарии (что исправить).
      </p>
    </div>
  </section>

  <!-- RIGHT: reflection -->
  <aside class="card">
    <div class="cardHead">
      <h2>2) Рефлексия и «выходной билет»</h2>
      <small>ответы сохраняются локально</small>
    </div>
    <div class="cardBody">
      <div class="resultBox">
        <h3>Итог самопроверки</h3>
        <div class="big" id="scoreBig">0/5</div>
        <p class="hint" id="scoreHint">Сначала ответь на вопросы и нажми «Проверить».</p>
      </div>

      <div class="divider"></div>

      <div class="scale">
        <div class="scaleBox">
          <h3>Самооценка понимания (0–10)</h3>
          <input type="range" id="understandRange" min="0" max="10" value="5" />
          <div class="rangeMeta">
            <span>«Пока туман»</span>
            <span><b id="understandVal">5</b>/10</span>
            <span>«Могу объяснить»</span>
          </div>
        </div>

        <div class="scaleBox">
          <h3>Что стало понятнее?</h3>
          <textarea id="clearText" placeholder="Например: что sin, cos, tg, ctg — это отношения сторон в прямоугольном треугольнике и зависят от угла…"></textarea>
          <div class="mini">1–2 предложения достаточно. Главное — по делу.</div>
        </div>

        <div class="scaleBox">
          <h3>Где осталось затруднение?</h3>
          <textarea id="hardText" placeholder="Например: путаю tg и ctg, или забываю, что они — отношения…"></textarea>
          <div class="mini">Если затруднений нет — напиши «затруднений нет». Учителю тоже приятно жить 🙂</div>
        </div>

        <div class="scaleBox">
          <h3>Выходной билет (коротко)</h3>
          <div class="q" style="margin:0">
            <p class="note" style="margin:0 0 8px">
              Заполни пропуски:
            </p>
            <div style="color:var(--text); font-size:14px; line-height:1.5">
              <b>sin&nbsp;α</b> = <span class="kbd">…</span> / <span class="kbd">…</span>,
              <b>cos&nbsp;α</b> = <span class="kbd">…</span> / <span class="kbd">…</span>,
              <b>tg&nbsp;α</b> = <span class="kbd">…</span> / <span class="kbd">…</span>,
              <b>ctg&nbsp;α</b> = <span class="kbd">…</span> / <span class="kbd">…</span>.
            </div>
            <div class="divider"></div>
            <textarea id="ticketText" placeholder="Пример: sinα = противолежащий катет / гипотенуза; cosα = прилежащий катет / гипотенуза; tgα = противолежащий / прилежащий; ctgα = прилежащий / противолежащий."></textarea>
            <div class="row" style="margin-top:10px">
              <button class="btn secondary" id="copyBtn">Скопировать мои ответы</button>
              <button class="btn" id="exportBtn">Экспорт .txt</button>
            </div>
            <p class="mini" id="copyInfo" style="margin-top:8px"></p>
          </div>
        </div>

        <div class="scaleBox">
          <h3>Подсказки «что повторить», если балл низкий</h3>
          <ul class="list" id="tipsList">
            <li>Определения sin, cos через стороны прямоугольного треугольника.</li>
            <li>Определения tg и ctg как отношений катетов.</li>
            <li>Одна фраза: «Значение зависит от угла, а не от размера треугольника».</li>
          </ul>
        </div>
      </div>
    </div>
  </aside>
</div>

<footer class="card">
  <div class="cardBody">
    <p class="note" style="margin:0">
      Совет учителю: включи это в конце урока на 5–7 минут. Ученики заполняют, а потом показывают
      «Выходной билет» (можно просто скопировать текст).
    </p>
  </div>
</footer>
<script> // ---------- Quiz data ---------- // Формулировки под "определения" (прямоугольный треугольник). const QUESTIONS = [ { id: "q1", title: "Что такое sin α в прямоугольном треугольнике?", tag: "определение", options: [ "отношение противолежащего катета к гипотенузе", "отношение прилежащего катета к гипотенузе", "отношение гипотенузы к противолежащему катету", "отношение прилежащего катета к противолежащему" ], correct: 0, explain: "sin α = (противолежащий катет) / (гипотенуза)." }, { id: "q2", title: "Что такое cos α в прямоугольном треугольнике?", tag: "определение", options: [ "отношение противолежащего катета к гипотенузе", "отношение прилежащего катета к гипотенузе", "отношение гипотенузы к прилежащему катету", "отношение противолежащего катета к прилежащему" ], correct: 1, explain: "cos α = (прилежащий катет) / (гипотенуза)." }, { id: "q3", title: "tg α — это…", tag: "определение", options: [ "прилежащий катет / гипотенуза", "противолежащий катет / гипотенуза", "противолежащий катет / прилежащий катет", "гипотенуза / прилежащий катет" ], correct: 2, explain: "tg α = (противолежащий катет) / (прилежащий катет)." }, { id: "q4", title: "ctg α — это…", tag: "определение", options: [ "противолежащий катет / прилежащий катет", "прилежащий катет / противолежащий катет", "гипотенуза / противолежащий катет", "гипотенуза / прилежащий катет" ], correct: 1, explain: "ctg α = (прилежащий катет) / (противолежащий катет)." }, { id: "q5", title: "Верное утверждение про значения функций (по определению):", tag: "смысл", options: [ "sin α зависит от размеров треугольника", "sin α зависит только от угла α (для подобных треугольников одинаков)", "cos α всегда больше 1", "tg α не бывает дробью" ], correct: 1, explain: "Отношения сторон в подобных треугольниках одинаковы — значит зависит от угла." } ]; // ---------- DOM helpers ---------- const $ = (sel) => document.querySelector(sel); const quizEl = $("#quiz"); const statusDot = $("#statusDot"); const statusText = $("#statusText"); const scoreBig = $("#scoreBig"); const scoreHint = $("#scoreHint"); const understandRange = $("#understandRange"); const understandVal = $("#understandVal"); const clearText = $("#clearText"); const hardText = $("#hardText"); const ticketText = $("#ticketText"); const autosaveLabel = $("#autosave"); const timerEl = $("#timer"); const LS_KEY = "trig_reflection_v1"; // ---------- Render quiz ---------- function renderQuiz(){ const frag = document.createDocumentFragment(); QUESTIONS.forEach((q, idx) => { const wrap = document.createElement("div"); wrap.className = "q"; wrap.dataset.qid = q.id; wrap.innerHTML = `

${idx+1}. ${q.title}

${q.tag}
${q.options.map((opt, i) => ` ${opt} `).join("")}
`; frag.appendChild(wrap); }); // вставим перед divider (перед кнопками) const divider = quizEl.querySelector(".divider"); quizEl.insertBefore(frag, divider); } // ---------- Check answers ---------- function check(){ let score = 0; QUESTIONS.forEach((q) => { const chosen = quizEl.querySelector(`input[name="${q.id}"]:checked`); const fb = document.getElementById(`${q.id}-fb`); fb.style.display = "block"; if (!chosen){ fb.className = "feedback bad"; fb.textContent = "Нет ответа. Это тоже ответ, но грустный 🙂 " + q.explain; return; } const val = Number(chosen.value); if (val === q.correct){ score++; fb.className = "feedback ok"; fb.textContent = "Верно ✅ " + q.explain; } else { fb.className = "feedback bad"; fb.textContent = "Мимо ❌ " + q.explain; } }); // Update header status if (score === 5){ statusDot.className = "dot ok"; statusText.textContent = "Отлично: 5/5"; scoreHint.textContent = "Можно объяснять соседу и не краснеть 😄"; } else if (score >= 3){ statusDot.className = "dot"; statusText.textContent = "Нормально: есть пробелы"; scoreHint.textContent = "Хорошо. Подтяни 1–2 определения и будет уверенно."; } else { statusDot.className = "dot bad"; statusText.textContent = "Нужно повторить"; scoreHint.textContent = "Сначала выучи 4 определения (sin, cos, tg, ctg) — это фундамент."; } scoreBig.textContent = `${score}/5`; // tweak tips updateTips(score); saveState(true); } function updateTips(score){ const tips = $("#tipsList"); tips.innerHTML = ""; const common = [ "Проговори вслух: sin — противолежащий/гипотенуза, cos — прилежащий/гипотенуза.", "tg и ctg — это отношения катетов: противолежащий/прилежащий и наоборот.", "Проверь себя на рисунке: где угол α — там и «прилежащий» катет." ]; const extraLow = [ "Сделай мини-таблицу в тетради: функция → отношение сторон.", "Нарисуй один прямоугольный треугольник и подпиши стороны относительно α." ]; const extraMid = [ "Попрактикуйся: выбери угол α на рисунке и назови 2 катета (прилежащий/противолежащий).", "Скажи одной фразой: почему значения зависят от угла (подобие)." ]; const extraHigh = [ "Попробуй объяснить определение так, чтобы понял пятиклассник (без формул).", "Проверь себя: можешь ли быстро отличить tg от ctg по рисунку." ]; const addAll = (arr)=>arr.forEach(t=>{ const li=document.createElement("li"); li.textContent=t; tips.appendChild(li); }); addAll(common); if (score <= 2) addAll(extraLow); else if (score <= 4) addAll(extraMid); else addAll(extraHigh); } // ---------- Reset ---------- function resetAll(){ // radios QUESTIONS.forEach(q=>{ quizEl.querySelectorAll(`input[name="${q.id}"]`).forEach(r=>r.checked=false); const fb = document.getElementById(`${q.id}-fb`); fb.style.display = "none"; fb.textContent = ""; }); // right panel scoreBig.textContent = "0/5"; scoreHint.textContent = "Сначала ответь на вопросы и нажми «Проверить»."; statusDot.className = "dot"; statusText.textContent = "Ещё не проверено"; understandRange.value = 5; understandVal.textContent = "5"; clearText.value = ""; hardText.value = ""; ticketText.value = ""; $("#copyInfo").textContent = ""; updateTips(0); localStorage.removeItem(LS_KEY); autosaveLabel.textContent = "автосохранение: выкл."; } // ---------- Demo fill ---------- function demoFill(){ QUESTIONS.forEach(q=>{ const rnd = Math.floor(Math.random()*q.options.length); const el = quizEl.querySelector(`input[name="${q.id}"][value="${rnd}"]`); if(el) el.checked = true; }); clearText.value = "Стало понятнее, что sin и cos — отношения сторон к гипотенузе."; hardText.value = "Иногда путаю, где прилежащий катет относительно угла."; ticketText.value = "sinα = противолежащий катет / гипотенуза; cosα = прилежащий катет / гипотенуза; tgα = противолежащий / прилежащий; ctgα = прилежащий / противолежащий."; understandRange.value = 6; understandVal.textContent = "6"; saveState(true); } // ---------- Save / load ---------- function getState(){ const answers = {}; QUESTIONS.forEach(q=>{ const chosen = quizEl.querySelector(`input[name="${q.id}"]:checked`); answers[q.id] = chosen ? Number(chosen.value) : null; }); return { answers, understand: Number(understandRange.value), clear: clearText.value, hard: hardText.value, ticket: ticketText.value, ts: Date.now() }; } function applyState(st){ if(!st) return; if(st.answers){ Object.entries(st.answers).forEach(([qid,val])=>{ if(val === null || val === undefined) return; const el = quizEl.querySelector(`input[name="${qid}"][value="${val}"]`); if(el) el.checked = true; }); } if(typeof st.understand === "number"){ understandRange.value = String(st.understand); understandVal.textContent = String(st.understand); } if(typeof st.clear === "string") clearText.value = st.clear; if(typeof st.hard === "string") hardText.value = st.hard; if(typeof st.ticket === "string") ticketText.value = st.ticket; } function saveState(showLabel=false){ const st = getState(); localStorage.setItem(LS_KEY, JSON.stringify(st)); if(showLabel){ autosaveLabel.textContent = "автосохранение: включено"; } } function loadState(){ const raw = localStorage.getItem(LS_KEY); if(!raw) return; try{ const st = JSON.parse(raw); applyState(st); autosaveLabel.textContent = "автосохранение: включено"; }catch(e){ // ignore } } // ---------- Copy / export ---------- function buildExportText(){ const st = getState(); const lines = []; lines.push("Интерактивная рефлексия — Определение тригонометрических функций (9.2.4.1)"); lines.push("Дата: " + new Date().toLocaleString()); lines.push(""); lines.push("Самооценка понимания: " + st.understand + "/10"); lines.push(""); lines.push("Что стало понятнее:"); lines.push(st.clear.trim() ? st.clear.trim() : "(пусто)"); lines.push(""); lines.push("Где осталось затруднение:"); lines.push(st.hard.trim() ? st.hard.trim() : "(пусто)"); lines.push(""); lines.push("Выходной билет:"); lines.push(st.ticket.trim() ? st.ticket.trim() : "(пусто)"); lines.push(""); lines.push("Ответы на мини-квиз:"); QUESTIONS.forEach((q, i)=>{ const v = st.answers[q.id]; const chosen = (v === null) ? "(нет ответа)" : q.options[v]; lines.push(`${i+1}) ${q.title}`); lines.push(" Мой ответ: " + chosen); }); return lines.join("\n"); } async function copyToClipboard(){ const text = buildExportText(); try{ await navigator.clipboard.writeText(text); $("#copyInfo").textContent = "Скопировано ✅ Теперь можно вставить в чат/документ."; }catch(e){ $("#copyInfo").textContent = "Не удалось скопировать (браузер запретил). Используй экспорт .txt."; } } function exportTxt(){ const text = buildExportText(); const blob = new Blob([text], {type:"text/plain;charset=utf-8"}); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "reflexia_trig_9kl.txt"; document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(url); $("#copyInfo").textContent = "Файл .txt скачан ✅"; } // ---------- Timer ---------- let t0 = Date.now(); function tick(){ const s = Math.floor((Date.now()-t0)/1000); const mm = String(Math.floor(s/60)).padStart(2,"0"); const ss = String(s%60).padStart(2,"0"); timerEl.textContent = `${mm}:${ss}`; } // ---------- Bindings ---------- function bindAutosave(){ // autosave on interactions quizEl.addEventListener("change", (e)=>{ if(e.target && e.target.matches('input[type="radio"]')) saveState(true); }); [understandRange, clearText, hardText, ticketText].forEach(el=>{ el.addEventListener("input", ()=>{ if(el === understandRange) understandVal.textContent = understandRange.value; saveState(true); }); }); } // ---------- Init ---------- renderQuiz(); loadState(); updateTips(0); bindAutosave(); $("#checkBtn").addEventListener("click", check); $("#resetBtn").addEventListener("click", resetAll); $("#fillDemoBtn").addEventListener("click", demoFill); $("#copyBtn").addEventListener("click", copyToClipboard); $("#exportBtn").addEventListener("click", exportTxt); setInterval(tick, 250); </script>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions