470 lines
27 KiB
HTML
470 lines
27 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>{{第N周}} · {{班级简称}}课评</title>
|
||
<style>
|
||
@import url('https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;600;700&family=Noto+Sans+SC:wght@300;400;500;600&display=swap');
|
||
|
||
:root {
|
||
--coral: #e85d4c;
|
||
--coral-light: #f5a99e;
|
||
--coral-dark: #c44738;
|
||
--amber: #f0a84a;
|
||
--amber-light: #f5d08a;
|
||
--ink: #2c2420;
|
||
--ink-soft: #5a524e;
|
||
--paper: #faf6f1;
|
||
--paper-warm: #f5efe8;
|
||
--cream: #fffdf9;
|
||
--border: #e8e0d8;
|
||
--shadow-soft: rgba(44, 36, 32, 0.06);
|
||
--shadow-medium: rgba(44, 36, 32, 0.10);
|
||
--shadow-card: rgba(44, 36, 32, 0.08);
|
||
}
|
||
|
||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||
html { scroll-behavior: smooth; }
|
||
|
||
body {
|
||
font-family: 'Noto Sans SC', -apple-system, BlinkMacSystemFont, sans-serif;
|
||
background: var(--paper);
|
||
min-height: 100vh;
|
||
color: var(--ink);
|
||
background-image:
|
||
radial-gradient(circle at 20% 50%, rgba(240, 168, 74, 0.03) 0%, transparent 50%),
|
||
radial-gradient(circle at 80% 20%, rgba(232, 93, 76, 0.02) 0%, transparent 50%),
|
||
radial-gradient(circle at 50% 80%, rgba(240, 168, 74, 0.02) 0%, transparent 40%);
|
||
}
|
||
|
||
.topbar {
|
||
position: sticky; top: 0; z-index: 100;
|
||
background: rgba(250, 246, 241, 0.92); backdrop-filter: blur(16px);
|
||
border-bottom: 1px solid var(--border);
|
||
padding: 14px 28px; display: flex; justify-content: space-between; align-items: center;
|
||
}
|
||
.topbar-title { font-family: 'Noto Serif SC', serif; font-size: 1.05em; font-weight: 600; color: var(--ink); letter-spacing: 0.5px; }
|
||
.topbar-meta { font-size: 0.8em; color: var(--ink-soft); margin-top: 2px; }
|
||
.topbar-actions { display: flex; gap: 10px; }
|
||
.btn { padding: 8px 18px; border-radius: 10px; font-size: 0.85em; font-weight: 500; cursor: pointer; transition: all 0.25s ease; border: none; font-family: inherit; }
|
||
.btn-outline { background: transparent; border: 1.5px solid var(--border); color: var(--ink-soft); }
|
||
.btn-outline:hover { border-color: var(--coral); color: var(--coral); background: rgba(232, 93, 76, 0.05); }
|
||
.btn-success { background: var(--coral); color: white; }
|
||
.btn-success:hover { background: var(--coral-dark); }
|
||
.btn-success:disabled { opacity: 0.5; cursor: not-allowed; }
|
||
|
||
.main { max-width: 680px; margin: 0 auto; padding: 28px 20px 160px; position: relative; }
|
||
|
||
.course-hero {
|
||
background: linear-gradient(135deg, var(--cream) 0%, var(--paper-warm) 100%);
|
||
border-radius: 20px; padding: 36px 32px 32px; margin-bottom: 24px;
|
||
border: 1px solid var(--border); position: relative; overflow: hidden;
|
||
box-shadow: 0 2px 8px var(--shadow-soft), 0 8px 32px var(--shadow-card);
|
||
}
|
||
.course-hero::before { content: ''; position: absolute; top: -60px; right: -40px; width: 180px; height: 180px; border-radius: 50%; background: radial-gradient(circle, rgba(232, 93, 76, 0.08) 0%, transparent 70%); }
|
||
.course-hero::after { content: ''; position: absolute; bottom: -40px; left: -30px; width: 140px; height: 140px; border-radius: 50%; background: radial-gradient(circle, rgba(240, 168, 74, 0.06) 0%, transparent 70%); }
|
||
|
||
.hero-badge { display: inline-flex; align-items: center; gap: 6px; background: linear-gradient(135deg, var(--coral) 0%, var(--amber) 100%); color: white; font-size: 0.75em; font-weight: 600; padding: 6px 16px; border-radius: 20px; margin-bottom: 16px; position: relative; z-index: 1; letter-spacing: 0.5px; }
|
||
.hero-title { font-family: 'Noto Serif SC', serif; font-size: 2.2em; font-weight: 700; color: var(--ink); line-height: 1.3; margin-bottom: 8px; position: relative; z-index: 1; letter-spacing: 2px; }
|
||
.hero-subtitle { font-size: 0.95em; color: var(--ink-soft); margin-bottom: 20px; position: relative; z-index: 1; }
|
||
.hero-divider { width: 60px; height: 3px; background: linear-gradient(90deg, var(--coral), var(--amber)); border-radius: 2px; margin-bottom: 20px; position: relative; z-index: 1; }
|
||
.hero-info { display: flex; flex-wrap: wrap; gap: 16px; position: relative; z-index: 1; }
|
||
.hero-info-item { display: flex; align-items: center; gap: 6px; font-size: 0.85em; color: var(--ink-soft); }
|
||
.hero-info-item .icon { font-size: 1.1em; }
|
||
|
||
.goals-section { background: var(--cream); border-radius: 16px; padding: 24px; margin-bottom: 28px; border: 1px solid var(--border); box-shadow: 0 2px 12px var(--shadow-soft); }
|
||
.goals-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 18px; }
|
||
.goals-title { font-family: 'Noto Serif SC', serif; font-size: 1em; font-weight: 600; color: var(--ink); display: flex; align-items: center; gap: 8px; }
|
||
.goals-title .title-icon { font-size: 1.2em; }
|
||
.goals-toggle { font-size: 0.78em; color: var(--ink-soft); cursor: pointer; background: var(--paper-warm); border: 1px solid var(--border); font-family: inherit; padding: 5px 12px; border-radius: 8px; transition: all 0.2s ease; }
|
||
.goals-toggle:hover { background: var(--coral); color: white; border-color: var(--coral); }
|
||
.goals-list { list-style: none; display: block; }
|
||
.goals-list.collapsed { display: none; }
|
||
.goals-list li { padding: 12px 16px; background: var(--paper); border-radius: 10px; margin-bottom: 10px; font-size: 0.9em; color: var(--ink-soft); display: flex; align-items: flex-start; gap: 12px; border-left: 3px solid transparent; transition: all 0.2s ease; }
|
||
.goals-list li:hover { border-left-color: var(--coral); background: var(--cream); transform: translateX(4px); }
|
||
.goals-list li:last-child { margin-bottom: 0; }
|
||
.goal-num { background: linear-gradient(135deg, var(--coral) 0%, var(--amber) 100%); color: white; width: 26px; height: 26px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 0.78em; font-weight: 600; flex-shrink: 0; margin-top: 1px; }
|
||
.goal-text { flex: 1; line-height: 1.6; }
|
||
|
||
.cards-slider-wrapper { position: relative; border-radius: 16px; margin-bottom: 20px; overflow: hidden; }
|
||
.cards-slider { position: relative; min-height: 300px; }
|
||
|
||
.student-card {
|
||
background: var(--cream); border-radius: 16px; border: 1px solid var(--border);
|
||
transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||
position: absolute; width: 100%; top: 0; left: 0;
|
||
opacity: 0; transform: translateX(60px) scale(0.96); pointer-events: none;
|
||
box-shadow: 0 4px 20px var(--shadow-card);
|
||
}
|
||
.student-card.active { opacity: 1; transform: translateX(0) scale(1); pointer-events: auto; position: relative; }
|
||
.student-card.prev { transform: translateX(-60px) scale(0.96); opacity: 0; }
|
||
.student-card:hover { box-shadow: 0 8px 32px var(--shadow-medium); }
|
||
|
||
.card-header { padding: 18px 24px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--border); background: linear-gradient(135deg, rgba(250, 246, 241, 0.5) 0%, rgba(245, 239, 232, 0.5) 100%); border-radius: 16px 16px 0 0; }
|
||
.student-name { font-family: 'Noto Serif SC', serif; font-size: 1.15em; font-weight: 600; color: var(--ink); letter-spacing: 1px; }
|
||
.card-badge { font-size: 0.75em; padding: 5px 12px; border-radius: 20px; font-weight: 500; }
|
||
.badge-normal { background: #e8f5e9; color: #2e7d32; }
|
||
.badge-makeup { background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%); color: #e65100; }
|
||
.badge-absent { background: #fce4ec; color: #c2185b; }
|
||
|
||
.card-body { padding: 24px; }
|
||
.feedback-content { font-size: 0.92em; line-height: 2; color: var(--ink-soft); margin-bottom: 20px; }
|
||
.metrics { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
|
||
.metric-item { padding: 14px; background: var(--paper); border-radius: 10px; border: 1px solid transparent; transition: all 0.2s ease; }
|
||
.metric-item:hover { border-color: var(--border); background: var(--cream); }
|
||
.metric-label { font-size: 0.72em; color: #999; margin-bottom: 5px; text-transform: uppercase; letter-spacing: 0.5px; }
|
||
.metric-value { font-size: 0.88em; font-weight: 500; color: var(--ink); }
|
||
.metric-stars { color: var(--amber); letter-spacing: 1px; }
|
||
|
||
.star-rating { display: flex; align-items: center; gap: 2px; margin-top: 6px; }
|
||
.star-rating .star { font-size: 1.3em; color: #ddd5cc; cursor: default; transition: all 0.15s ease; user-select: none; line-height: 1; }
|
||
.star-rating .star.filled { color: var(--amber); }
|
||
.star-score { font-size: 0.78em; color: var(--ink-soft); margin-left: 6px; font-weight: 500; min-width: 28px; }
|
||
.metric-comment { margin-top: 8px; padding: 8px 10px; background: var(--paper); border-radius: 8px; font-size: 0.82em; color: var(--ink-soft); line-height: 1.5; border: 1px solid transparent; min-height: 32px; }
|
||
|
||
.side-nav-btn {
|
||
position: fixed; top: 50%; transform: translateY(-50%); z-index: 90;
|
||
width: 52px; height: 80px; border: none;
|
||
background: rgba(250, 246, 241, 0.85); backdrop-filter: blur(12px);
|
||
cursor: pointer; display: flex; align-items: center; justify-content: center;
|
||
font-size: 1.4em; color: var(--ink-soft); transition: all 0.3s ease;
|
||
box-shadow: 0 4px 16px var(--shadow-medium);
|
||
}
|
||
.side-nav-btn:hover:not(:disabled) { background: var(--cream); color: var(--coral); width: 60px; box-shadow: 0 6px 24px rgba(232, 93, 76, 0.15); }
|
||
.side-nav-btn:disabled { opacity: 0.25; cursor: not-allowed; }
|
||
.side-nav-btn.prev-btn { left: 0; border-radius: 0 12px 12px 0; border-right: 1px solid var(--border); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); padding-right: 4px; }
|
||
.side-nav-btn.next-btn { right: 0; border-radius: 12px 0 0 12px; border-left: 1px solid var(--border); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); padding-left: 4px; }
|
||
.side-nav-btn .arrow { transition: transform 0.3s ease; }
|
||
.side-nav-btn:hover .arrow.prev-arrow { transform: translateX(-3px); }
|
||
.side-nav-btn:hover .arrow.next-arrow { transform: translateX(3px); }
|
||
|
||
.nav-controls { display: flex; justify-content: center; align-items: center; gap: 20px; margin-bottom: 16px; }
|
||
.page-indicator { font-family: 'Noto Serif SC', serif; font-size: 0.95em; color: var(--ink-soft); font-weight: 500; min-width: 70px; text-align: center; letter-spacing: 1px; }
|
||
|
||
.progress-dots { display: flex; justify-content: center; gap: 10px; margin-top: 4px; }
|
||
.progress-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--border); cursor: pointer; transition: all 0.3s ease; position: relative; }
|
||
.progress-dot.active { background: var(--coral); width: 28px; border-radius: 4px; }
|
||
.progress-dot:hover:not(.active) { background: var(--coral-light); transform: scale(1.3); }
|
||
|
||
.toast { position: fixed; bottom: 80px; left: 50%; transform: translateX(-50%) translateY(20px); background: var(--ink); color: white; padding: 12px 28px; border-radius: 10px; font-size: 0.85em; opacity: 0; transition: all 0.3s ease; pointer-events: none; z-index: 200; box-shadow: 0 4px 16px rgba(0,0,0,0.15); }
|
||
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
|
||
|
||
.footer { text-align: center; padding: 36px 20px; color: #bbb; font-size: 0.78em; font-family: 'Noto Serif SC', serif; letter-spacing: 1px; }
|
||
|
||
@media (max-width: 768px) {
|
||
.hero-title { font-size: 1.7em; }
|
||
.side-nav-btn { width: 40px; height: 60px; font-size: 1.1em; }
|
||
.main { padding: 20px 16px 160px; }
|
||
.course-hero { padding: 28px 20px 24px; }
|
||
}
|
||
</style>
|
||
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
|
||
</head>
|
||
<body>
|
||
<!-- ========== 顶栏 ========== -->
|
||
<div class="topbar">
|
||
<div>
|
||
<div class="topbar-title">{{第N周}} · {{班级简称}}班课评</div>
|
||
<div class="topbar-meta">{{日期中文}} · 《{{课程名称}}》 · {{老师}}老师</div>
|
||
</div>
|
||
<div class="topbar-actions">
|
||
<button class="btn btn-outline" onclick="exportText()">📋 导出</button>
|
||
<button class="btn btn-success" id="screenshotBtn" onclick="downloadAllScreenshots()">📸 全部下载</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ========== 左右切换按钮 ========== -->
|
||
<button class="side-nav-btn prev-btn" id="sidePrevBtn" onclick="prevCard()" title="上一张"><span class="arrow prev-arrow">‹</span></button>
|
||
<button class="side-nav-btn next-btn" id="sideNextBtn" onclick="nextCard()" title="下一张"><span class="arrow next-arrow">›</span></button>
|
||
|
||
<!-- ========== 主内容区 ========== -->
|
||
<div class="main">
|
||
<!-- 课程头部 -->
|
||
<div class="course-hero">
|
||
<div class="hero-badge">📚 本周课程</div>
|
||
<h1 class="hero-title">《{{课程名称}}》</h1>
|
||
<p class="hero-subtitle">{{课程副标题}} · 第{{课次}}课</p>
|
||
<div class="hero-divider"></div>
|
||
<div class="hero-info">
|
||
<div class="hero-info-item"><span class="icon">📅</span><span>{{日期中文}}</span></div>
|
||
<div class="hero-info-item"><span class="icon">⏰</span><span>{{上课时间}}</span></div>
|
||
<div class="hero-info-item"><span class="icon">👩🏫</span><span>{{老师}}老师</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 知识点 -->
|
||
<div class="goals-section">
|
||
<div class="goals-header">
|
||
<span class="goals-title"><span class="title-icon">🎯</span>本周知识点</span>
|
||
<button class="goals-toggle" onclick="toggleGoals()">收起</button>
|
||
</div>
|
||
<ul class="goals-list" id="goalsList">
|
||
{{知识点列表}}
|
||
<!-- 示例格式:
|
||
<li><span class="goal-num">1</span><span class="goal-text">知识点内容</span></li>
|
||
-->
|
||
</ul>
|
||
</div>
|
||
|
||
<!-- 学生卡片区(由 JS 动态生成) -->
|
||
<div class="cards-slider-wrapper">
|
||
<div class="cards-slider" id="cardsSlider"></div>
|
||
</div>
|
||
|
||
<!-- 页码指示器 -->
|
||
<div class="nav-controls"><span class="page-indicator" id="pageIndicator"></span></div>
|
||
<div class="progress-dots" id="progressDots"></div>
|
||
|
||
<div class="footer">{{底部文案}}</div>
|
||
</div>
|
||
|
||
<div class="toast" id="toast"></div>
|
||
|
||
<script>
|
||
// ============================================================
|
||
// 📝 配置区:填写以下数据即可生成课评网页
|
||
// ============================================================
|
||
|
||
// 页面元信息
|
||
var PAGE = {
|
||
weekLabel: '{{第N周}}', // 如 "第17周"
|
||
classShort: '{{班级简称}}', // 如 "K4"
|
||
courseName: '{{课程名称}}', // 如 "成语接龙"
|
||
courseSubtitle: '{{课程副标题}}', // 如 "列表 · 插入与查找元素"
|
||
lessonNum: '{{课次}}', // 如 "17"
|
||
dateCN: '{{日期中文}}', // 如 "2026年6月26日"
|
||
dateISO: '{{日期ISO}}', // 如 "2026-06-26"
|
||
timeSlot: '{{上课时间}}', // 如 "周五 19:00-20:30"
|
||
teacher: '{{老师}}', // 如 "橙子"
|
||
footerText: '{{底部文案}}' // 如 "穹狼科创 · K4班 · 橙子老师"
|
||
};
|
||
|
||
// 知识点列表(数组,每项一条)
|
||
var GOALS = [
|
||
// 示例:
|
||
// '理解词语接龙的游戏规则:下一个词的首字必须等于上一个词的末字',
|
||
// '学习使用变量"旧词语"和列表"词语表"存储和管理接龙数据',
|
||
];
|
||
|
||
// 学生数据(数组,每项一个学生)
|
||
// badge: 'normal' | 'makeup' | 'absent'
|
||
// metrics: [{ label, score(1-5), comment }, ...]
|
||
var STUDENTS = [
|
||
// 示例:
|
||
// {
|
||
// name: '陈圆振',
|
||
// badge: 'normal',
|
||
// badgeText: '正常上课',
|
||
// feedback: '圆振这节课表现很积极~...',
|
||
// metrics: [
|
||
// { label: '课堂互动', score: 5, comment: '积极回答问题' },
|
||
// { label: '知识理解', score: 5, comment: '理解透彻' },
|
||
// ]
|
||
// },
|
||
];
|
||
|
||
// 截图下载的文件名格式:{姓名}-第{课次}课{课程名称}.png
|
||
function getScreenshotFilename(studentName) {
|
||
return studentName + '-第' + PAGE.lessonNum + '课' + PAGE.courseName + '.png';
|
||
}
|
||
|
||
// ============================================================
|
||
// 🔧 以下为渲染引擎,一般无需修改
|
||
// ============================================================
|
||
|
||
var totalCards = STUDENTS.length;
|
||
var currentCard = 0;
|
||
|
||
// 渲染知识点
|
||
(function renderGoals() {
|
||
var html = '';
|
||
GOALS.forEach(function(g, i) {
|
||
html += '<li><span class="goal-num">' + (i + 1) + '</span><span class="goal-text">' + g + '</span></li>';
|
||
});
|
||
document.getElementById('goalsList').innerHTML = html;
|
||
})();
|
||
|
||
// 渲染学生卡片
|
||
(function renderCards() {
|
||
var badgeClassMap = { normal: 'badge-normal', makeup: 'badge-makeup', absent: 'badge-absent' };
|
||
var scoreLabels = ['未评', '需加强', '合格', '良好', '优秀', '超棒'];
|
||
var cardsHtml = '';
|
||
STUDENTS.forEach(function(s, idx) {
|
||
var isActive = idx === 0 ? ' active' : '';
|
||
cardsHtml += '<div class="student-card' + isActive + '" data-index="' + idx + '">';
|
||
cardsHtml += '<div class="card-header"><span class="student-name">' + s.name + '</span><span class="card-badge ' + (badgeClassMap[s.badge] || 'badge-normal') + '">' + s.badgeText + '</span></div>';
|
||
cardsHtml += '<div class="card-body">';
|
||
cardsHtml += '<div class="feedback-content" data-student="' + s.name + '">' + s.feedback + '</div>';
|
||
cardsHtml += '<div class="metrics">';
|
||
s.metrics.forEach(function(m) {
|
||
var starsHtml = '';
|
||
for (var si = 1; si <= 5; si++) {
|
||
starsHtml += '<span class="star' + (si <= m.score ? ' filled' : '') + '" data-val="' + si + '">★</span>';
|
||
}
|
||
cardsHtml += '<div class="metric-item" data-metric="' + m.label + '">';
|
||
cardsHtml += '<div class="metric-label">' + m.label + '</div>';
|
||
cardsHtml += '<div class="star-rating" data-score="' + m.score + '">' + starsHtml + '<span class="star-score">' + (scoreLabels[m.score] || '未评') + '</span></div>';
|
||
cardsHtml += '<div class="metric-comment" data-metric-comment="' + m.label + '">' + m.comment + '</div>';
|
||
cardsHtml += '</div>';
|
||
});
|
||
cardsHtml += '</div></div></div>';
|
||
});
|
||
document.getElementById('cardsSlider').innerHTML = cardsHtml;
|
||
})();
|
||
|
||
// 渲染进度点
|
||
(function renderDots() {
|
||
var dotsHtml = '';
|
||
for (var i = 0; i < totalCards; i++) {
|
||
dotsHtml += '<div class="progress-dot' + (i === 0 ? ' active' : '') + '" onclick="goToCard(' + i + ')"></div>';
|
||
}
|
||
document.getElementById('progressDots').innerHTML = dotsHtml;
|
||
document.getElementById('pageIndicator').textContent = '1 / ' + totalCards;
|
||
})();
|
||
|
||
// 卡片切换
|
||
var allCards, sidePrevBtn, sideNextBtn, pageIndicatorEl, progressDots;
|
||
|
||
function initSliderRefs() {
|
||
allCards = document.querySelectorAll('.student-card');
|
||
sidePrevBtn = document.getElementById('sidePrevBtn');
|
||
sideNextBtn = document.getElementById('sideNextBtn');
|
||
pageIndicatorEl = document.getElementById('pageIndicator');
|
||
progressDots = document.querySelectorAll('.progress-dot');
|
||
updateSlider();
|
||
}
|
||
|
||
function updateSlider() {
|
||
if (!allCards) return;
|
||
allCards.forEach(function(card, i) {
|
||
card.classList.remove('active', 'prev');
|
||
if (i === currentCard) card.classList.add('active');
|
||
else if (i < currentCard) card.classList.add('prev');
|
||
});
|
||
if (pageIndicatorEl) pageIndicatorEl.textContent = (currentCard + 1) + ' / ' + totalCards;
|
||
if (sidePrevBtn) sidePrevBtn.disabled = currentCard === 0;
|
||
if (sideNextBtn) sideNextBtn.disabled = currentCard === totalCards - 1;
|
||
if (progressDots) progressDots.forEach(function(dot, i) { dot.classList.toggle('active', i === currentCard); });
|
||
}
|
||
|
||
function nextCard() { if (currentCard < totalCards - 1) { currentCard++; updateSlider(); } }
|
||
function prevCard() { if (currentCard > 0) { currentCard--; updateSlider(); } }
|
||
function goToCard(i) { currentCard = i; updateSlider(); }
|
||
|
||
document.addEventListener('keydown', function(e) {
|
||
if (e.key === 'ArrowLeft') prevCard();
|
||
if (e.key === 'ArrowRight') nextCard();
|
||
});
|
||
|
||
var touchStartX = 0;
|
||
document.getElementById('cardsSlider').addEventListener('touchstart', function(e) { touchStartX = e.changedTouches[0].screenX; });
|
||
document.getElementById('cardsSlider').addEventListener('touchend', function(e) {
|
||
var dx = e.changedTouches[0].screenX;
|
||
if (touchStartX - dx > 50) nextCard();
|
||
if (dx - touchStartX > 50) prevCard();
|
||
});
|
||
|
||
initSliderRefs();
|
||
|
||
// 知识点展开/收起
|
||
function toggleGoals() {
|
||
var list = document.getElementById('goalsList');
|
||
var btn = document.querySelector('.goals-toggle');
|
||
list.classList.toggle('collapsed');
|
||
btn.textContent = list.classList.contains('collapsed') ? '展开' : '收起';
|
||
}
|
||
|
||
// Toast 提示
|
||
function showToast(msg) {
|
||
var toast = document.getElementById('toast');
|
||
toast.textContent = msg;
|
||
toast.classList.add('show');
|
||
setTimeout(function() { toast.classList.remove('show'); }, 2000);
|
||
}
|
||
|
||
// 导出文本
|
||
function exportText() {
|
||
var sep = '═══════════════════════════════════════';
|
||
var text = PAGE.weekLabel + PAGE.classShort + '班课评\n';
|
||
text += PAGE.dateCN + ' · 《' + PAGE.courseName + '》 · ' + PAGE.teacher + '老师\n';
|
||
text += sep + '\n\n';
|
||
text += '🎯 本周知识点\n';
|
||
text += '─────────────────────────────────────\n';
|
||
GOALS.forEach(function(g, i) { text += (i + 1) + '. ' + g + '\n'; });
|
||
text += '\n' + sep + '\n\n';
|
||
|
||
STUDENTS.forEach(function(s) {
|
||
text += '【' + s.name + '】' + s.badgeText + '\n';
|
||
text += '─────────────────────────────────\n';
|
||
text += s.feedback + '\n\n';
|
||
});
|
||
|
||
navigator.clipboard.writeText(text).then(function() {
|
||
showToast('✓ 已复制到剪贴板,可直接粘贴发送');
|
||
}).catch(function() {
|
||
var ta = document.createElement('textarea');
|
||
ta.value = text; document.body.appendChild(ta); ta.select();
|
||
document.execCommand('copy'); document.body.removeChild(ta);
|
||
showToast('✓ 已复制到剪贴板');
|
||
});
|
||
}
|
||
|
||
// 📸 批量截图下载
|
||
function downloadAllScreenshots() {
|
||
var btn = document.getElementById('screenshotBtn');
|
||
var originalText = btn.textContent;
|
||
btn.disabled = true;
|
||
btn.textContent = '⏳ 截图准备中...';
|
||
|
||
var savedCard = currentCard;
|
||
var goalsEl = document.getElementById('goalsList');
|
||
var goalsCollapsed = goalsEl.classList.contains('collapsed');
|
||
var sidePrev = document.getElementById('sidePrevBtn');
|
||
var sideNext = document.getElementById('sideNextBtn');
|
||
var mainEl = document.querySelector('.main');
|
||
|
||
if (goalsCollapsed) goalsEl.classList.remove('collapsed');
|
||
|
||
function captureOne(i) {
|
||
if (i >= totalCards) {
|
||
goToCard(savedCard);
|
||
if (goalsCollapsed) goalsEl.classList.add('collapsed');
|
||
btn.disabled = false;
|
||
btn.textContent = originalText;
|
||
sidePrev.style.display = '';
|
||
sideNext.style.display = '';
|
||
mainEl.style.paddingBottom = '';
|
||
showToast('✓ ' + totalCards + '张截图已下载');
|
||
return;
|
||
}
|
||
|
||
btn.textContent = '⏳ 截图 ' + (i + 1) + '/' + totalCards;
|
||
goToCard(i);
|
||
sidePrev.style.display = 'none';
|
||
sideNext.style.display = 'none';
|
||
mainEl.style.paddingBottom = '40px';
|
||
|
||
setTimeout(function() {
|
||
html2canvas(mainEl, {
|
||
backgroundColor: '#faf6f1',
|
||
scale: 2,
|
||
useCORS: true
|
||
}).then(function(canvas) {
|
||
var link = document.createElement('a');
|
||
link.download = getScreenshotFilename(STUDENTS[i].name);
|
||
link.href = canvas.toDataURL('image/png');
|
||
link.click();
|
||
captureOne(i + 1);
|
||
}).catch(function() {
|
||
captureOne(i + 1);
|
||
});
|
||
}, 450);
|
||
}
|
||
|
||
captureOne(0);
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|