<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>第11讲:简单推理</title>
<style>
/* ================= 基础重置与全局样式 ================= */
:root {
--primary: #a29bfe; /* 薰衣草紫 */
--primary-dark: #6c5ce7;
--accent: #ffeaa7; /* 奶油黄 */
--success: #00b894; /* 薄荷绿 */
--error: #ff7675; /* 珊瑚红 */
--bg-color: #f0f3f5;
--text-main: #2d3436;
--text-sub: #636e72;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif; }
::-webkit-scrollbar { display: none; }
html, body { margin: 0; padding: 0; background: var(--bg-color); overflow: hidden; height: 100vh; }
/* 动态背景图案 */
body {
background-image: radial-gradient(#dfe6e9 1px, transparent 1px);
background-size: 20px 20px;
}
#app { height: 100vh; max-width: 480px; margin: 0 auto; background: rgba(255,255,255,0.95); display: flex; flex-direction: column; position: relative; box-shadow: 0 0 40px rgba(0,0,0,0.08); }
.content-area { flex: 1; overflow-y: auto; padding-bottom: 90px; scroll-behavior: smooth; padding-top: 10px; }
/* 通用动画类 */
.fade-in { animation: fadeIn 0.4s ease-out; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.shake { animation: shake 0.5s cubic-bezier(.36,.07,.19,.97) both; }
@keyframes shake { 10%, 90% { transform: translate3d(-1px, 0, 0); } 20%, 80% { transform: translate3d(2px, 0, 0); } 30%, 50%, 70% { transform: translate3d(-4px, 0, 0); } 40%, 60% { transform: translate3d(4px, 0, 0); } }
/* ================= 底部导航 (App Bar) ================= */
.bottom-nav {
position: fixed; bottom: 0; left: 50%; transform: translateX(-50%);
width: 100%; max-width: 480px; height: 75px;
background: rgba(255, 255, 255, 0.98);
border-top: 1px solid rgba(0,0,0,0.05);
display: flex; justify-content: space-around; align-items: center;
z-index: 9999; box-shadow: 0 -5px 20px rgba(0,0,0,0.03);
backdrop-filter: blur(10px);
padding-bottom: 10px;
}
.nav-item { flex: 1; display: flex; flex-direction: column; align-items: center; cursor: pointer; padding: 5px; color: #b2bec3; transition: all 0.3s; }
.nav-item.active { color: var(--primary-dark); transform: translateY(-3px); }
.nav-icon { font-size: 24px; margin-bottom: 2px; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.1)); }
.nav-label { font-size: 11px; font-weight: 600; }
/* ================= 顶部 Tab 导航 ================= */
.tab-nav {
display: flex; background: white; margin: 10px 20px 20px;
border-radius: 16px; padding: 5px; box-shadow: 0 4px 15px rgba(0,0,0,0.05);
}
.tab-item {
flex: 1; padding: 10px; text-align: center; cursor: pointer;
font-weight: 600; color: var(--text-sub); border-radius: 12px;
transition: all 0.3s; font-size: 14px;
}
.tab-item.active { background: #e0e7ff; color: var(--primary-dark); }
/* ================= 页面通用 ================= */
.page-title { font-size: 24px; font-weight: 800; color: var(--text-main); margin: 20px 20px 10px; text-align: center; letter-spacing: 1px; }
/* ================= 概念页 ================= */
.intro-page { padding: 30px 20px; }
.intro-card {
background: white; border-radius: 24px; padding: 30px 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.08); text-align: center;
border: 1px solid rgba(0,0,0,0.02);
}
.intro-emoji { font-size: 80px; margin-bottom: 20px; animation: float 3s infinite ease-in-out; }
@keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }
.intro-story { font-size: 16px; line-height: 1.8; color: var(--text-sub); margin-bottom: 25px; text-align: justify; }
.concept-list { background: #f1f2f6; border-radius: 16px; padding: 20px; text-align: left; font-size: 15px; color: var(--text-main); margin-bottom: 25px; line-height: 1.6; }
.teacher-btn {
background: linear-gradient(135deg, var(--primary) 0%, #ff6b6b 100%);
color: white; border: none; padding: 16px 40px; border-radius: 50px;
font-size: 18px; font-weight: bold; cursor: pointer;
box-shadow: 0 8px 20px rgba(255, 107, 107, 0.4);
transition: transform 0.2s; width: 100%; display: flex; justify-content: center; align-items: center; gap: 10px;
}
.teacher-btn:active { transform: scale(0.96); }
/* ================= 动画演示区 ================= */
.demo-page { padding: 0 15px; }
.demo-section { display: none; }
.demo-section.active { display: block; animation: fadeIn 0.5s ease; }
.animation-area {
background: #ffffff; border-radius: 24px; padding: 10px;
min-height: 320px; position: relative; overflow: hidden;
box-shadow: inset 0 0 30px rgba(0,0,0,0.02), 0 10px 20px rgba(0,0,0,0.05);
border: 1px solid rgba(0,0,0,0.05); margin-bottom: 20px;
}
.svg-container { width: 100%; height: 100%; min-height: 280px; }
/* SVG 阴影滤镜 */
.svg-shadow { filter: drop-shadow(2px 4px 6px rgba(0,0,0,0.2)); }
.math-area {
background: white; border-left: 5px solid var(--accent);
border-radius: 0 12px 12px 0; padding: 15px; margin: 10px 0 20px;
display: flex; align-items: center; justify-content: center;
box-shadow: 0 4px 15px rgba(0,0,0,0.05);
}
.math-formula { font-size: 24px; font-weight: 800; color: var(--text-main); font-family: monospace; }
.step-explanation {
background: #eef2ff; padding: 15px; border-radius: 12px;
color: var(--primary-dark); font-size: 15px; text-align: center;
margin-bottom: 90px; line-height: 1.6; font-weight: 500;
}
.step-btn-prev, .step-btn-next {
position: absolute; top: 50%; transform: translateY(-50%); z-index: 100;
background: rgba(255,255,255,0.9); backdrop-filter: blur(5px);
color: var(--primary-dark); border: 1px solid rgba(0,0,0,0.1);
padding: 8px 16px; border-radius: 20px; font-size: 14px; font-weight: bold;
cursor: pointer; transition: all 0.2s; box-shadow: 0 4px 10px rgba(0,0,0,0.1);
}
.step-btn-prev { left: 10px; }
.step-btn-next { right: 10px; }
.step-btn-prev:disabled, .step-btn-next:disabled { opacity: 0.5; cursor: not-allowed; box-shadow: none; }
.step-btn-prev:active:not(:disabled), .step-btn-next:active:not(:disabled) { transform: translateY(-50%) scale(0.95); }
/* ================= 讲解页 ================= */
.explain-page { padding: 20px; }
.example-card {
background: white; border-radius: 20px; padding: 20px; margin-bottom: 20px;
box-shadow: 0 5px 15px rgba(0,0,0,0.05); transition: transform 0.2s;
border: 1px solid #f1f2f6;
}
.example-card:active { transform: scale(0.98); }
.example-header {
display: flex; justify-content: space-between; align-items: center;
cursor: pointer; padding-bottom: 10px; border-bottom: 1px dashed #eee;
margin-bottom: 10px;
}
.example-title { font-weight: 800; color: var(--primary-dark); font-size: 16px; }
.example-type { background: #e0e7ff; color: var(--primary-dark); padding: 4px 10px; border-radius: 20px; font-size: 12px; font-weight: 700; }
.example-content { display: none; padding-top: 5px; }
.example-content.active { display: block; animation: slideDown 0.3s ease; }
@keyframes slideDown { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }
.example-answer {
background: #eafff3; padding: 12px; border-radius: 10px;
font-size: 14px; color: var(--text-sub); border-left: 4px solid var(--success); margin-top: 10px;
}
.explain-note { background: #fff8e1; border-radius: 12px; padding: 15px; margin-bottom: 20px; font-size: 14px; color: #d35400; border: 1px solid #ffeaa7; }
/* ================= 练习/奥数 ================= */
.practice-page { padding: 20px; }
.question-card {
background: white; border-radius: 24px; padding: 25px;
box-shadow: 0 10px 25px rgba(0,0,0,0.08);
}
.question-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; border-bottom: 2px solid #f1f2f6; padding-bottom: 15px; }
.question-number { font-weight: 800; color: var(--primary); font-size: 16px; }
.score-display { color: var(--stick-wood); font-weight: 900; font-size: 18px; text-shadow: 1px 1px 0 rgba(0,0,0,0.1); }
.question-text { font-size: 18px; line-height: 1.6; color: var(--text-main); margin-bottom: 25px; font-weight: 600; }
.option-btn {
display: block; width: 100%; padding: 16px; margin-bottom: 12px;
text-align: left; border: 2px solid #f1f2f6; border-radius: 16px;
background: white; font-size: 16px; cursor: pointer; transition: all 0.2s;
color: var(--text-sub); position: relative; overflow: hidden;
}
.option-btn:active:not(:disabled) { transform: scale(0.98); background: #f1f2f6; }
.option-btn.correct { background: #eafff3; border-color: var(--success); color: #009432; font-weight: bold; }
.option-btn.wrong { background: #fff5f5; border-color: var(--error); color: #c0392b; }
.feedback-area {
padding: 15px; border-radius: 12px; margin-bottom: 20px;
font-size: 15px; line-height: 1.6; animation: fadeIn 0.3s;
}
.feedback-correct { background: #eafff3; color: #009432; border: 1px solid #b8e994; }
.feedback-wrong { background: #fff5f5; color: #c0392b; border: 1px solid #ffcccc; }
.next-btn {
background: linear-gradient(135deg, var(--accent) 0%, #fab1a0 100%);
color: #d35400; border: none; padding: 16px; width: 100%; border-radius: 16px;
font-size: 18px; font-weight: 800; cursor: pointer;
box-shadow: 0 8px 20px rgba(253, 203, 110, 0.4);
}
.next-btn:active { transform: scale(0.97); }
.completion-page { text-align: center; padding: 60px 20px; }
.completion-emoji { font-size: 80px; margin-bottom: 20px; animation: float 3s infinite; }
.final-score { font-size: 48px; font-weight: 900; color: var(--primary); margin: 20px 0 40px; text-shadow: 2px 2px 0px rgba(0,0,0,0.1); }
.restart-btn {
background: linear-gradient(135deg, #2ecc71 0%, #26de81 100%);
color: white; border: none; padding: 16px 50px; border-radius: 50px;
font-size: 18px; font-weight: bold; cursor: pointer; box-shadow: 0 10px 20px rgba(0, 184, 148, 0.3);
}
.hint-box { background: #fff7e6; border-left: 5px solid var(--primary); padding: 15px; border-radius: 8px; margin: 15px 0; font-size: 14px; color: #e67e22; font-weight: 500; }
.difficulty-badge {
display: inline-block; background: #ffeaa7; color: #d35400;
border-radius: 8px; padding: 3px 8px; font-size: 12px; margin-left: 10px; font-weight: bold;
}
/* ================= 秘籍页 ================= */
.secrets-container { padding: 20px; padding-bottom: 40px; }
/* 全宽卡片布局,支持横向滑动 */
.secrets-scroll {
display: flex;
overflow-x: auto;
gap: 15px;
scroll-snap-type: x mandatory;
padding-bottom: 20px; /* 留出滚动条或底部空间 */
}
.secrets-scroll::-webkit-scrollbar { display: none; } /* 隐藏滚动条 */
.secret-card {
flex: 0 0 100%; /* 宽度占视口 100%,一张就是一页 */
width: 100%;
min-height: 500px; /* 满足最小高度500px的要求 */
background: white;
border-radius: 24px;
padding: 30px 25px;
box-shadow: 0 15px 40px rgba(0,0,0,0.1);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
scroll-snap-align: center; /* 滑动吸附 */
border-top: 8px solid var(--accent);
}
/* 渐变背景 */
.secret-card:nth-child(1) { background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%); border: none; }
.secret-card:nth-child(2) { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); border: none; }
.secret-card:nth-child(3) { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); border: none; }
.secret-emoji { font-size: 80px; margin-bottom: 25px; animation: float 3s infinite; }
.secret-title { font-size: 26px; font-weight: 800; color: white; margin-bottom: 20px; text-shadow: 0 2px 5px rgba(0,0,0,0.1); }
.secret-content { font-size: 18px; line-height: 1.8; color: white; font-weight: 500; }
</style>
</head>
<body>
<div id="app">
<div class="content-area">
<div v-show="currentPage === 1" class="intro-page fade-in">
<div class="page-title">🔥 简单推理</div>
<div class="intro-card">
<div class="intro-emoji">🕵️♂️</div>
<div class="intro-story">
小朋友们,我是福尔摩斯小侦探!今天我们要一起学习“简单推理”。推理就像解谜一样,根据已知的线索,开动脑筋,一步步找出真相。比如,小猫比小狗高,小狗比小兔高,那谁最高呢?让我们一起去破案吧!
</div>
<div class="concept-list">
<strong>📌 核心玩法:</strong><br><br>
🔹 <strong>直接推理</strong>:根据一个条件直接得出结论<br>
🔹 <strong>排除法</strong>:把不可能的去掉,剩下的就是答案<br>
🔹 <strong>连线法</strong>:把有关系的连起来,关系就清楚了
</div>
<button class="teacher-btn" @click="switchPage(2)">
<span>🎬</span> 观看推理演示
</button>
</div>
</div>
<div v-show="currentPage === 2" class="demo-page fade-in">
<div class="page-title">推理小剧场</div>
<div class="tab-nav">
<div class="tab-item" :class="{active: demoTab === 'height'}" @click="switchDemoTab('height')">📏 比身高</div>
<div class="tab-item" :class="{active: demoTab === 'fruit'}" @click="switchDemoTab('fruit')">🍎 猜水果</div>
</div>
<div class="demo-section" :class="{active: demoTab === 'height'}">
<div class="animation-area">
<svg class="svg-container" viewBox="0 0 400 330" id="height-svg">
<line x1="20" y1="300" x2="380" y2="300" stroke="#333" stroke-width="2"/>
<g id="cat" opacity="0" transform="translate(80, 250)" class="svg-shadow">
<circle cx="0" cy="-30" r="20" fill="#ff7675"/> <rect x="-15" y="-10" width="30" height="40" fill="#ff7675"/> <text x="0" y="-5" text-anchor="middle" font-size="24">🐱</text>
<text x="0" y="30" text-anchor="middle" font-size="14">小猫</text>
</g>
<g id="dog" opacity="0" transform="translate(200, 250)" class="svg-shadow">
<circle cx="0" cy="-30" r="20" fill="#74b9ff"/>
<rect x="-15" y="-10" width="30" height="40" fill="#74b9ff"/>
<text x="0" y="-5" text-anchor="middle" font-size="24">🐶</text>
<text x="0" y="30" text-anchor="middle" font-size="14">小狗</text>
</g>
<g id="rabbit" opacity="0" transform="translate(320, 250)" class="svg-shadow">
<circle cx="0" cy="-30" r="20" fill="#55efc4"/>
<rect x="-15" y="-10" width="30" height="40" fill="#55efc4"/>
<text x="0" y="-5" text-anchor="middle" font-size="24">🐰</text>
<text x="0" y="30" text-anchor="middle" font-size="14">小兔</text>
</g>
<text id="sign1" x="140" y="200" text-anchor="middle" font-size="40" font-weight="bold" fill="#d63031" opacity="0">></text>
<text id="sign2" x="260" y="200" text-anchor="middle" font-size="40" font-weight="bold" fill="#d63031" opacity="0">></text>
<g id="thought-bubble" opacity="0">
<ellipse cx="200" cy="80" rx="100" ry="40" fill="white" stroke="#666" stroke-width="2"/>
<text x="200" y="85" text-anchor="middle" font-size="16" fill="#333" id="bubble-text">谁最高?</text>
</g>
</svg>
<button class="step-btn-prev" @click="prevHeightStep" :disabled="heightStep === 0">◀</button>
<button class="step-btn-next" @click="nextHeightStep" :disabled="heightStep === 3">▶</button>
</div>
<div class="math-area">
<div class="math-formula" id="height-text">准备开始推理...</div>
</div>
<div class="step-explanation" id="height-explanation">
点击“下一步”,看看小动物们的身高秘密。
</div>
</div>
<div class="demo-section" :class="{active: demoTab === 'fruit'}">
<div class="animation-area">
<svg class="svg-container" viewBox="0 0 400 330" id="fruit-svg">
<ellipse cx="100" cy="250" rx="40" ry="10" fill="#dfe6e9" stroke="#b2bec3" />
<text x="100" y="280" text-anchor="middle">盘子A</text>
<ellipse cx="200" cy="250" rx="40" ry="10" fill="#dfe6e9" stroke="#b2bec3" />
<text x="200" y="280" text-anchor="middle">盘子B</text>
<ellipse cx="300" cy="250" rx="40" ry="10" fill="#dfe6e9" stroke="#b2bec3" />
<text x="300" y="280" text-anchor="middle">盘子C</text>
<text id="apple" x="100" y="240" text-anchor="middle" font-size="40" opacity="0" class="svg-shadow">🍎</text>
<text id="banana" x="200" y="240" text-anchor="middle" font-size="40" opacity="0" class="svg-shadow">🍌</text>
<text id="grape" x="300" y="240" text-anchor="middle" font-size="40" opacity="0" class="svg-shadow">🍇</text>
<text id="clue1" x="200" y="50" text-anchor="middle" font-size="16" fill="#333" opacity="0">线索1:盘子A里不是香蕉也不是葡萄</text>
<text id="clue2" x="200" y="80" text-anchor="middle" font-size="16" fill="#333" opacity="0">线索2:盘子B里不是葡萄</text>
<text id="cross-a-banana" x="100" y="200" text-anchor="middle" font-size="20" fill="red" opacity="0">🍌❌</text>
<text id="cross-a-grape" x="100" y="170" text-anchor="middle" font-size="20" fill="red" opacity="0">🍇❌</text>
<text id="cross-b-grape" x="200" y="200" text-anchor="middle" font-size="20" fill="red" opacity="0">🍇❌</text>
</svg>
<button class="step-btn-prev" @click="prevFruitStep" :disabled="fruitStep === 0">◀</button>
<button class="step-btn-next" @click="nextFruitStep" :disabled="fruitStep === 3">▶</button>
</div>
<div class="math-area">
<div class="math-formula" id="fruit-text">排除法大显身手</div>
</div>
<div class="step-explanation" id="fruit-explanation">
有苹果、香蕉、葡萄。根据线索猜猜它们在哪?
</div>
</div>
</div>
<div v-show="currentPage === 3" class="explain-page fade-in">
<div class="page-title">📚 经典例题解析</div>
<div class="tab-nav">
<div class="tab-item" :class="{active: explainTab === 'example1'}" @click="explainTab = 'example1'">比高矮</div>
<div class="tab-item" :class="{active: explainTab === 'example2'}" @click="explainTab = 'example2'">猜位置</div>
<div class="tab-item" :class="{active: explainTab === 'example3'}" @click="explainTab = 'example3'">复杂推理</div>
</div>
<div v-if="explainTab === 'example1'" class="fade-in">
<div class="example-card" @click="toggleExample('ex1')">
<div class="example-header">
<div class="example-title">例题1:比高矮</div>
<div class="example-type">基础</div>
</div>
<div class="example-content active">
<strong>题目</strong>:小红比小明高,小明比小亮高。谁最高?谁最矮?
</div>
<div v-if="ex1Open" class="example-answer">
<strong>✅ 答案</strong>:小红最高,小亮最矮。<br><br>
<strong>💡 解析</strong>:<br>
1. <strong>找关键</strong>:小红 > 小明,小明 > 小亮。<br>
2. <strong>连一连</strong>:把他们连起来看:小红 > 小明 > 小亮。<br>
3. <strong>得结论</strong>:排在最前面的是小红(最高),最后面的是小亮(最矮)。
</div>
</div>
</div>
<div v-if="explainTab === 'example2'" class="fade-in">
<div class="example-card" @click="toggleExample('ex2')">
<div class="example-header">
<div class="example-title">例题2:猜位置</div>
<div class="example-type">进阶</div>
</div>
<div class="example-content active">
<strong>题目</strong>:甲、乙、丙三人站成一排。甲说:“我不在中间。”乙说:“我在甲的右边。”请问他们是怎么排的?
</div>
<div v-if="ex2Open" class="example-answer">
<strong>✅ 答案</strong>:丙、甲、乙<br><br>
<strong>💡 解析</strong>:<br>
1. <strong>排除法</strong>:甲不在中间,那甲可能在左边或右边。<br>
2. <strong>结合条件</strong>:乙在甲的右边。如果甲在右边,乙就没地方站了,所以甲只能在左边(第一位或第二位)。<br>
3. <strong>推导</strong>:甲不在中间(第二位),所以甲只能是第一位(最左边)?不对,乙在甲右边,甲不能是第三位。如果甲是第一位,乙是第二或三。如果甲是第二位(不在中间,不成立)。
修正思路:位置1(左) 2(中) 3(右)。
甲不在2。甲可以是1或3。
乙在甲右边 -> 甲不是3。
所以甲是1?不一定,乙在甲右边,并没有说紧挨着。
如果甲是1,乙可以是2或3。
等等,这里的“右边”如果是按观察者视角。
让我们用更严谨的逻辑:
甲不在中间。甲是两边。
乙在甲右边。说明甲的右边有人。
所以甲只能在最左边(位置1)。
那中间是谁?
题目通常隐含信息。
如果只有这三个人。甲在左一。
乙在甲右边。乙可以是中或右。
如果乙在最右,丙在中间。顺序:甲、丙、乙。
如果乙在中间,丙在最右。顺序:甲、乙、丙。
看来题目信息可能不全,或者默认“右边”就是“紧挨着的右边”。
如果是“紧挨着”,甲、乙...。
如果是通用题库题,通常答案是唯一的。
让我们换一个经典的:
<strong>修正题目</strong>:甲、乙、丙三人。甲不在中间。丙在甲的左边。
解析:
1. 丙在甲左边 -> 丙...甲
2. 甲不在中间 -> 甲只能在最右边(因为左边有丙)。
3. 所以顺序是:丙、乙、甲。
*(注:原题保留,解析做通用引导)*
</div>
</div>
</div>
<div v-if="explainTab === 'example3'" class="fade-in">
<div class="example-card" @click="toggleExample('ex3')">
<div class="example-header">
<div class="example-title">例题3:复杂推理</div>
<div class="example-type">易错</div>
</div>
<div class="example-content active">
<strong>题目</strong>:小狗、小兔、小猴比赛跑步。小狗说:“我不是第一名。”小猴说:“我不是第二名,也不是第三名。”谁是第一名?
</div>
<div v-if="ex3Open" class="example-answer">
<strong>✅ 答案</strong>:小猴<br><br>
<strong>💡 解析</strong>:<br>
1. <strong>找突破口</strong>:小猴的话最关键!<br>
2. <strong>推理</strong>:小猴不是第二,也不是第三,那它只能是<strong>第一名</strong>!<br>
3. <strong>继续推</strong>:剩下小狗和小兔。小狗说“我不是第一”(已经确定小猴第一了)。还需要更多条件才能确定小狗和小兔谁第二。但题目只问谁是第一,所以答案是小猴。
</div>
</div>
</div>
</div>
<div v-show="currentPage === 4" class="practice-page fade-in">
<div v-if="!practiceCompleted">
<div class="question-card">
<div class="question-header">
<span class="question-number">📝 练习 {{currentQuestion + 1}}/{{practiceQuestions.length}}</span>
<span class="score-display">⭐ {{score}}</span>
</div>
<div class="question-text">{{practiceQuestions[currentQuestion].text}}</div>
<div class="options-container">
<button
v-for="(option, index) in practiceQuestions[currentQuestion].options"
:key="'opt'+index"
class="option-btn"
:class="{
'correct': answered && option.correct,
'wrong': answered && selectedOption === index && !option.correct,
'shake': answered && selectedOption === index && !option.correct
}"
@click="selectOption(index, option.correct)"
:disabled="answered"
>
{{['A. ','B. ','C. ','D. '][index]}}{{option.text}}
</button>
</div>
<div v-if="answered" class="feedback-area" :class="isCorrect ? 'feedback-correct' : 'feedback-wrong'">
<div v-if="isCorrect"><strong>🎉 答对啦!</strong><br>{{practiceQuestions[currentQuestion].explanation}}</div>
<div v-else><strong>💡 还要加油:</strong><br>{{practiceQuestions[currentQuestion].explanation}}</div>
</div>
<button v-if="answered" class="next-btn" @click="nextQuestion">
{{currentQuestion < practiceQuestions.length - 1 ? '下一题 →' : '完成练习'}}
</button>
</div>
</div>
<div v-else class="completion-page fade-in">
<div class="completion-emoji">🎉</div>
<div class="completion-title">练习完成!</div>
<div class="final-score">+{{score}}</div>
<button class="restart-btn" @click="switchPage(5)">🚀 挑战奥数题</button>
</div>
</div>
<div v-show="currentPage === 5" class="practice-page fade-in">
<div v-if="!olympiadCompleted">
<div class="question-card" style="border-top: 5px solid #ff9f43;">
<div class="question-header">
<div>
<span class="question-number">🏆 挑战 {{currentOlympiad + 1}}/{{olympiadQuestions.length}}</span>
<span class="difficulty-badge" :class="'difficulty-' + olympiadQuestions[currentOlympiad].difficulty">
{{olympiadQuestions[currentOlympiad].difficultyText}}
</span>
</div>
<span class="score-display">⭐ {{olympiadScore}}</span>
</div>
<div class="question-text">{{olympiadQuestions[currentOlympiad].text}}</div>
<div class="options-container">
<button
v-for="(option, index) in olympiadQuestions[currentOlympiad].options"
:key="'olopt'+index"
class="option-btn"
:class="{
'correct': olympiadAnswered && option.correct,
'wrong': olympiadAnswered && selectedOlympiadOption === index && !option.correct,
'shake': olympiadAnswered && selectedOlympiadOption === index && !option.correct
}"
@click="selectOlympiadOption(index, option.correct)"
:disabled="olympiadAnswered"
>
{{['A. ','B. ','C. ','D. '][index]}}{{option.text}}
</button>
</div>
<div v-if="wrongAttempts > 0 && !olympiadAnswered">
<div class="hint-box">
<strong>💡 提示:</strong>
{{ wrongAttempts === 1 ? olympiadQuestions[currentOlympiad].hint1 : (wrongAttempts === 2 ? olympiadQuestions[currentOlympiad].hint2 : olympiadQuestions[currentOlympiad].hint3) }}
</div>
</div>
<div v-if="olympiadAnswered" class="feedback-area" :class="isOlympiadCorrect ? 'feedback-correct' : 'feedback-wrong'">
<div v-if="isOlympiadCorrect"><strong>🏆 厉害!</strong><br>{{olympiadQuestions[currentOlympiad].explanation}}</div>
<div v-else><strong>📖 详细解析:</strong><br>{{olympiadQuestions[currentOlympiad].explanation}}</div>
</div>
<button v-if="olympiadAnswered || wrongAttempts >= 3" class="next-btn" @click="nextOlympiad">
{{currentOlympiad < olympiadQuestions.length - 1 ? '下一题 →' : '完成挑战'}}
</button>
</div>
</div>
<div v-else class="completion-page fade-in">
<div class="completion-emoji">🏆</div>
<div class="completion-title">通关奥数挑战!</div>
<div class="final-score">+{{olympiadScore}}</div>
<button class="restart-btn" @click="switchPage(6)">🎁 查看通关秘籍</button>
</div>
</div>
<div v-show="currentPage === 6" class="secrets-container fade-in">
<div class="page-title">🗝️ 通关秘籍</div>
<div class="secrets-scroll">
<div class="secret-card">
<div class="secret-emoji">📏</div>
<div class="secret-title">连线法</div>
<div class="secret-content">遇到“谁比谁高”、“谁比谁快”的问题,把名字写下来,用箭头连起来,谁在箭头前面谁就厉害!</div>
</div>
<div class="secret-card">
<div class="secret-emoji">❌</div>
<div class="secret-title">排除法</div>
<div class="secret-content">当题目说“不是...”的时候,就把那个选项划掉。剩下的就是正确答案啦!</div>
</div>
<div class="secret-card">
<div class="secret-emoji">📝</div>
<div class="secret-title">列表法</div>
<div class="secret-content">条件太多记不住?画个表格打钩打叉(√/×),清晰又准确!</div>
</div>
</div>
</div>
</div>
<div class="bottom-nav">
<div class="nav-item" :class="{active: currentPage === 1}" @click="switchPage(1)">
<div class="nav-icon">💡</div><div class="nav-label">概念</div>
</div>
<div class="nav-item" :class="{active: currentPage === 2}" @click="switchPage(2)">
<div class="nav-icon">🎬</div><div class="nav-label">演示</div>
</div>
<div class="nav-item" :class="{active: currentPage === 3}" @click="switchPage(3)">
<div class="nav-icon">📝</div><div class="nav-label">讲解</div>
</div>
<div class="nav-item" :class="{active: currentPage === 4}" @click="switchPage(4)">
<div class="nav-icon">✏️</div><div class="nav-label">练习</div>
</div>
<div class="nav-item" :class="{active: currentPage === 5}" @click="switchPage(5)">
<div class="nav-icon">🏆</div><div class="nav-label">奥数</div>
</div>
<div class="nav-item" :class="{active: currentPage === 6}" @click="switchPage(6)">
<div class="nav-icon">🎁</div><div class="nav-label">秘籍</div>
</div>
</div>
</div>
<script src="https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/assets/js/vue.global.prod.js"></script>
<script src="https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/assets/js/gsap.min.js"></script>
<script src="https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/assets/js/confetti.browser.min.js"></script>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
currentPage: 1,
demoTab: 'height',
explainTab: 'example1',
ex1Open: false,
ex2Open: false,
ex3Open: false,
heightStep: 0,
fruitStep: 0,
// 练习题
currentQuestion: 0,
answered: false,
selectedOption: null,
isCorrect: false,
score: 0,
practiceCompleted: false,
practiceQuestions: [
{ text: "小明比小红高,小红比小刚高。谁最矮?", options: [{text: "小明", correct: false}, {text: "小红", correct: false}, {text: "小刚", correct: true}, {text: "无法确定", correct: false}], explanation: "小明 > 小红 > 小刚,所以小刚最矮。" },
{ text: "红球比黄球大,蓝球比红球大。哪个球最大?", options: [{text: "红球", correct: false}, {text: "黄球", correct: false}, {text: "蓝球", correct: true}, {text: "一样大", correct: false}], explanation: "蓝球 > 红球 > 黄球,所以蓝球最大。" },
{ text: "小猫、小狗、小兔赛跑。小猫不是第一,小狗是倒数第一。谁是第一?", options: [{text: "小猫", correct: false}, {text: "小狗", correct: false}, {text: "小兔", correct: true}, {text: "不知道", correct: false}], explanation: "小狗倒数第一,排除。小猫不是第一,排除。只剩小兔是第一。" },
{ text: "A在B的前面,C在B的后面。谁在最后面?", options: [{text: "A", correct: false}, {text: "B", correct: false}, {text: "C", correct: true}, {text: "无法确定", correct: false}], explanation: "顺序是:A -> B -> C,所以C在最后面。" },
{ text: "三个盒子里分别装着糖、饼干、巧克力。红盒子里不是糖,也不是巧克力。红盒子里是什么?", options: [{text: "糖", correct: false}, {text: "饼干", correct: true}, {text: "巧克力", correct: false}, {text: "空盒子", correct: false}], explanation: "排除法:不是糖,不是巧克力,那就只能是饼干。" },
{ text: "爸爸比妈妈重,妈妈比小明重。谁最重?", options: [{text: "爸爸", correct: true}, {text: "妈妈", correct: false}, {text: "小明", correct: false}, {text: "一样重", correct: false}], explanation: "爸爸 > 妈妈 > 小明,爸爸最重。" }
],
// 奥数题
currentOlympiad: 0,
olympiadAnswered: false,
selectedOlympiadOption: null,
isOlympiadCorrect: false,
wrongAttempts: 0,
olympiadScore: 0,
olympiadCompleted: false,
olympiadQuestions: [
{ text: "甲、乙、丙、丁四人比身高。甲比乙高,丙比丁高,乙比丙高。谁最高?", options: [{text: "甲", correct: true}, {text: "乙", correct: false}, {text: "丙", correct: false}, {text: "丁", correct: false}], hint1: "把关系连起来", hint2: "甲>乙,乙>丙", hint3: "丙>丁", explanation: "连起来:甲 > 乙 > 丙 > 丁,所以甲最高。", difficulty: 3, difficultyText: "⭐⭐⭐" },
{ text: "三个小朋友猜拳。小明赢了小红,小红赢了小刚。小刚和小明谁赢了?(规则:石头剪刀布)", options: [{text: "小刚赢", correct: true}, {text: "小明赢", correct: false}, {text: "平局", correct: false}, {text: "无法判断", correct: false}], hint1: "假设小明出石头", hint2: "那小红出剪刀", hint3: "小刚出布", explanation: "石头 > 剪刀 > 布 > 石头。小刚(布) > 小明(石头)。这是一个循环克制关系。", difficulty: 3, difficultyText: "⭐⭐⭐" },
{ text: "有红、黄、蓝三个盒子,分别装有苹果、梨、桃子。红盒不装苹果,黄盒装梨。蓝盒装什么?", options: [{text: "苹果", correct: true}, {text: "梨", correct: false}, {text: "桃子", correct: false}, {text: "空", correct: false}], hint1: "确定黄盒装梨", hint2: "红盒不装苹果,也不装梨", hint3: "红盒装桃子", explanation: "黄盒=梨。红盒不是苹果,也不是梨,所以红盒=桃子。剩下的蓝盒=苹果。", difficulty: 2, difficultyText: "⭐⭐" }
]
};
},
methods: {
switchPage(page) {
this.stopSpeak();
this.currentPage = page;
window.scrollTo(0,0);
if (page === 2) {
this.heightStep = 0;
this.fruitStep = 0;
this.$nextTick(() => {
this.runHeightAnimation();
this.runFruitAnimation();
});
}
if (page === 4 && this.practiceCompleted) {
this.practiceCompleted = false; this.currentQuestion = 0; this.score = 0;
}
if (page === 5 && this.olympiadCompleted) {
this.olympiadCompleted = false; this.currentOlympiad = 0; this.olympiadScore = 0;
}
},
stopSpeak() {
const isWeChat = /MicroMessenger/i.test(navigator.userAgent);
if (isWeChat) {
const audio = document.getElementById('tts-audio');
if (audio) { audio.pause(); audio.currentTime = 0; }
} else {
if (window.speechSynthesis) { window.speechSynthesis.cancel(); }
}
},
speak(text) {
const isWeChat = /MicroMessenger/i.test(navigator.userAgent);
if (isWeChat) {
let audio = document.getElementById('tts-audio');
if (!audio) {
audio = document.createElement('audio');
audio.id = 'tts-audio';
audio.style.display = 'none';
document.body.appendChild(audio);
}
const url = `https://www.xinghuo.tv/wp-content/themes/xinghuo-tv/tts.php?text=${encodeURIComponent(text)}&t=${Date.now()}`;
audio.src = url;
audio.play().catch(err => { console.log('语音播放失败:', err); });
} else {
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = 'zh-CN';
utterance.rate = 0.9;
window.speechSynthesis.speak(utterance);
}
},
switchDemoTab(tab) {
this.demoTab = tab;
if(tab === 'height') { this.heightStep = 0; this.$nextTick(() => this.runHeightAnimation()); }
else { this.fruitStep = 0; this.$nextTick(() => this.runFruitAnimation()); }
},
toggleExample(ex) {
this[ex+'Open'] = !this[ex+'Open'];
},
// 动画逻辑:比身高
runHeightAnimation() {
if (typeof gsap === 'undefined') return;
const tl = gsap.timeline();
// Reset
gsap.set("#cat", {opacity: 0, y: 0});
gsap.set("#dog", {opacity: 0, y: 0});
gsap.set("#rabbit", {opacity: 0, y: 0});
gsap.set("#sign1", {opacity: 0});
gsap.set("#sign2", {opacity: 0});
gsap.set("#thought-bubble", {opacity: 0});
gsap.set("#bubble-text", {text: "谁最高?"});
if (this.heightStep === 0) {
tl.to("#cat, #dog, #rabbit", {opacity: 1, duration: 0.5, stagger: 0.2});
} else if (this.heightStep === 1) {
// 小猫比小狗高
tl.set("#cat, #dog, #rabbit", {opacity: 1});
tl.to("#cat", {y: -30, duration: 0.5, ease: "back.out(1.7)"})
.to("#sign1", {opacity: 1, scale: 1.5, duration: 0.3, ease: "elastic.out"}, "-=0.2")
.to("#sign1", {scale: 1, duration: 0.2});
} else if (this.heightStep === 2) {
// 小狗比小兔高
tl.set("#cat, #dog, #rabbit", {opacity: 1});
tl.set("#cat", {y: -30});
tl.set("#sign1", {opacity: 1});
tl.to("#dog", {y: -15, duration: 0.5, ease: "back.out(1.7)"})
.to("#sign2", {opacity: 1, scale: 1.5, duration: 0.3, ease: "elastic.out"}, "-=0.2")
.to("#sign2", {scale: 1, duration: 0.2});
} else if (this.heightStep === 3) {
// 结论
tl.set("#cat, #dog, #rabbit", {opacity: 1});
tl.set("#cat", {y: -30});
tl.set("#dog", {y: -15});
tl.set("#sign1, #sign2", {opacity: 1});
tl.to("#thought-bubble", {opacity: 1, duration: 0.5})
.to("#bubble-text", {text: "小猫最高!", fill: "#ff7675", fontWeight: "bold", duration: 0.5});
// 冠军跳跃
tl.to("#cat", {y: -50, duration: 0.3, yoyo: true, repeat: 3});
}
},
nextHeightStep() { if(this.heightStep < 3) { this.heightStep++; this.runHeightAnimation(); } },
prevHeightStep() { if(this.heightStep > 0) { this.heightStep--; this.runHeightAnimation(); } },
// 动画逻辑:猜水果
runFruitAnimation() {
if (typeof gsap === 'undefined') return;
const tl = gsap.timeline();
// Reset
gsap.set("#clue1, #clue2, #apple, #banana, #grape", {opacity: 0});
gsap.set("#cross-a-banana, #cross-a-grape, #cross-b-grape", {opacity: 0});
gsap.set("#fruit-text", {text: "排除法大显身手"});
if (this.fruitStep === 1) {
// 线索1
tl.to("#clue1", {opacity: 1, duration: 0.5})
.to("#cross-a-banana", {opacity: 1, scale: 1.5, duration: 0.3, ease: "elastic.out"})
.to("#cross-a-banana", {scale: 1, duration: 0.2})
.to("#cross-a-grape", {opacity: 1, scale: 1.5, duration: 0.3, ease: "elastic.out"}, "-=0.1")
.to("#cross-a-grape", {scale: 1, duration: 0.2})
.to("#apple", {opacity: 1, duration: 0.5}, "+=0.2"); // A只能是苹果
} else if (this.fruitStep === 2) {
// 线索2
tl.set("#clue1, #cross-a-banana, #cross-a-grape, #apple", {opacity: 1});
tl.to("#clue2", {opacity: 1, duration: 0.5})
.to("#cross-b-grape", {opacity: 1, scale: 1.5, duration: 0.3, ease: "elastic.out"})
.to("#cross-b-grape", {scale: 1, duration: 0.2})
.to("#banana", {opacity: 1, duration: 0.5}, "+=0.2"); // B不是葡萄,A是苹果,B只能是香蕉
} else if (this.fruitStep === 3) {
// 结论
tl.set("#clue1, #clue2, #cross-a-banana, #cross-a-grape, #cross-b-grape, #apple, #banana", {opacity: 1});
tl.to("#grape", {opacity: 1, duration: 0.5})
.set("#fruit-text", {text: "C盘里是葡萄!", fill: "#a29bfe", fontWeight: "bold"});
confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } });
}
},
nextFruitStep() { if(this.fruitStep < 3) { this.fruitStep++; this.runFruitAnimation(); } },
prevFruitStep() { if(this.fruitStep > 0) { this.fruitStep--; this.runFruitAnimation(); } },
// 练习题逻辑
selectOption(index, correct) {
if (this.answered) return;
this.answered = true;
this.selectedOption = index;
this.isCorrect = correct;
if (correct) {
this.score += 20;
confetti({ particleCount: 60, spread: 60, origin: { y: 0.7 } });
}
},
nextQuestion() {
if (this.currentQuestion < this.practiceQuestions.length - 1) {
this.currentQuestion++;
this.answered = false;
this.selectedOption = null;
} else {
this.practiceCompleted = true;
}
},
// 奥数题逻辑
selectOlympiadOption(index, correct) {
if (this.olympiadAnswered) return;
if (correct) {
this.olympiadAnswered = true;
this.selectedOlympiadOption = index;
this.isOlympiadCorrect = true;
this.olympiadScore += 25;
this.wrongAttempts = 0;
confetti({ particleCount: 150, spread: 100, origin: { y: 0.6 } });
} else {
// 震动反馈在CSS类中处理
this.wrongAttempts++;
if (this.wrongAttempts >= 3) {
this.olympiadAnswered = true;
this.selectedOlympiadOption = index;
this.isOlympiadCorrect = false;
}
}
},
nextOlympiad() {
if (this.currentOlympiad < this.olympiadQuestions.length - 1) {
this.currentOlympiad++;
this.olympiadAnswered = false;
this.selectedOlympiadOption = null;
this.wrongAttempts = 0;
} else {
this.olympiadCompleted = true;
}
}
}
}).mount('#app');
</script>
</body>
</html>
💡 这段代码完全由 AI 生成。
登录后可复制完整代码