<!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>第07讲:和差问题入门(画图解题)</title>
<style>
/* ================= 全局基础设置 ================= */
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; outline: none; }
::-webkit-scrollbar { display: none; width: 0 !important; height: 0 !important; }
* { -ms-overflow-style: none; scrollbar-width: none; }
html, body {
margin: 0; padding: 0;
background: #f0f4f8;
overflow: hidden;
height: 100vh;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
#app {
height: 100vh;
max-width: 480px;
margin: 0 auto;
background: linear-gradient(160deg, #f6f8fb 0%, #eef2f7 100%);
display: flex;
flex-direction: column;
position: relative;
}
/* 顶部标题区 */
.page-title {
text-align: center; font-size: 22px; font-weight: 800; color: #2d3748;
padding: 20px 20px 15px;
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(10px);
border-radius: 0 0 24px 24px;
box-shadow: 0 4px 20px rgba(0,0,0,0.03);
z-index: 10;
flex-shrink: 0;
}
/* 内容滚动区 */
.content-area {
flex: 1;
overflow-y: auto;
padding: 20px;
padding-bottom: 100px; /* 给底部导航留空间 */
scroll-behavior: smooth;
}
/* ================= 卡片通用样式 (圆润 + 微投影) ================= */
.intro-card, .explain-card, .question-card, .math-area, .animation-area {
background: #ffffff;
border-radius: 24px; /* 更圆润 */
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.05), 0 5px 10px -5px rgba(0, 0, 0, 0.01); /* 微投影 */
border: 1px solid rgba(255,255,255,0.8);
overflow: hidden;
transition: transform 0.2s, box-shadow 0.2s;
}
/* ================= 底部导航 (玻璃拟态) ================= */
.bottom-nav {
position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%);
width: 90%; max-width: 440px; height: 70px;
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(15px);
border-radius: 35px; /* 胶囊状 */
display: flex; justify-content: space-around; align-items: center; z-index: 9999;
box-shadow: 0 10px 30px rgba(0,0,0,0.08);
border: 1px solid rgba(255,255,255,0.5);
}
.nav-item { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; cursor: pointer; color: #a0aec0; transition: all 0.3s; padding: 5px 0; }
.nav-item.active { color: #667eea; transform: translateY(-2px); }
.nav-icon { font-size: 22px; margin-bottom: 3px; filter: drop-shadow(0 2px 2px rgba(0,0,0,0.05)); }
.nav-label { font-size: 11px; font-weight: 600; }
/* ================= 页面特定样式 ================= */
/* 1. 概念页 */
.intro-page { padding: 0; }
.intro-card { padding: 30px; text-align: center; }
.intro-emoji { font-size: 72px; margin-bottom: 15px; filter: drop-shadow(0 4px 6px rgba(0,0,0,0.1)); }
.intro-title { font-size: 24px; font-weight: 800; color: #2d3748; margin-bottom: 15px; }
.intro-text { font-size: 17px; color: #4a5568; line-height: 1.7; text-align: left; margin-bottom: 25px; }
.intro-formula {
background: linear-gradient(135deg, #f8f9ff 0%, #f1f4ff 100%);
border: 1px dashed #c3cfe2;
border-radius: 16px; padding: 20px; margin: 20px 0;
font-size: 18px; color: #5a67d8; font-weight: bold; text-align: center;
}
/* 按钮样式优化 */
.listen-btn, .next-btn, .restart-btn, .step-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white; border: none; padding: 15px 35px; border-radius: 50px;
font-size: 17px; font-weight: bold; cursor: pointer;
box-shadow: 0 8px 15px rgba(102, 126, 234, 0.35);
transition: transform 0.2s active, box-shadow 0.2s;
text-shadow: 0 1px 2px rgba(0,0,0,0.1);
}
.listen-btn:active, .next-btn:active, .restart-btn:active, .step-btn:active { transform: scale(0.96); box-shadow: 0 4px 8px rgba(102, 126, 234, 0.3); }
/* 2. 演示页 */
.tab-nav { display: flex; margin-bottom: 15px; background: rgba(255,255,255,0.6); padding: 5px; border-radius: 16px; }
.tab-item {
flex: 1; padding: 10px; text-align: center; cursor: pointer;
border-radius: 12px; font-weight: bold; color: #718096; transition: all 0.3s;
}
.tab-item.active { background: #fff; color: #667eea; box-shadow: 0 2px 10px rgba(0,0,0,0.05); }
.animation-area {
min-height: 380px; max-height: 380px; padding: 0;
background: radial-gradient(circle at center, #ffffff 0%, #f7fafc 100%);
}
/* SVG 阴影增强 */
.pillar {
filter: drop-shadow(2px 4px 4px rgba(0,0,0,0.2));
stroke: rgba(0,0,0,0.1); stroke-width: 1px;
}
#total-rect { filter: drop-shadow(0 4px 6px rgba(76, 175, 80, 0.3)); }
#cut-piece, #add-piece { filter: drop-shadow(2px 4px 4px rgba(0,0,0,0.2)); }
.math-area {
background: linear-gradient(to right, #ffffff, #f8f9fa);
border: none; border-left: 5px solid #667eea;
color: #2d3748;
margin-top: 15px; padding: 15px;
}
.step-explanation {
background: rgba(255, 255, 255, 0.8);
border: 1px solid rgba(255,255,255,0.9);
box-shadow: 0 4px 15px rgba(0,0,0,0.03);
font-weight: 500;
padding: 15px; margin-top: 10px; border-radius: 16px;
}
.control-bar {
position: fixed; bottom: 100px; left: 50%; transform: translateX(-50%);
width: 85%; max-width: 400px; z-index: 10001;
display: flex; justify-content: space-between;
}
.step-btn { padding: 12px 20px; font-size: 15px; }
/* 2.5 解决演示页/讲解页Tab切换显示问题的CSS */
.demo-section, .tab-content { display: none; animation: fadeIn 0.3s ease; }
.demo-section.active, .tab-content.active { display: block; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: translateY(0); } }
/* 3. 讲解页 & 折叠卡片 */
.explain-card { padding: 0; margin-bottom: 15px; }
.explain-card-header {
padding: 20px; display: flex; justify-content: space-between; align-items: center;
font-size: 18px; font-weight: 700; color: #2d3748; background: #fff;
}
.explain-card-body { background: #fbfdff; padding: 0 20px; }
.explain-card.expanded .explain-card-body { padding-bottom: 20px; border-top: 1px solid #edf2f7; }
.example-answer {
background: #e6fffa; color: #2c7a7b;
border: 1px solid #b2f5ea; box-shadow: inset 0 1px 3px rgba(0,0,0,0.03);
padding: 5px 10px; border-radius: 8px; margin: 5px 0;
}
.example-explanation { background: #faf5ff; color: #553c9a; border: 1px solid #e9d8fd; padding: 10px; border-radius: 8px; }
/* 4. 练习页 & 选项 */
.question-card { padding: 25px 20px; }
.question-header { border-bottom: 1px dashed #e2e8f0; padding-bottom: 10px; margin-bottom: 15px; display: flex; justify-content: space-between; align-items: center; }
.question-text { font-size: 19px; color: #1a202c; margin-bottom: 20px; line-height: 1.5; }
.options-container { display: flex; flex-direction: column; gap: 12px; }
.option-btn {
background: #fff; border: 1px solid #e2e8f0;
box-shadow: 0 2px 5px rgba(0,0,0,0.02);
border-radius: 16px; padding: 18px;
font-weight: 500; text-align: left; width: 100%;
font-size: 16px; cursor: pointer; transition: all 0.2s;
}
.option-btn:hover { border-color: #cbd5e0; transform: translateY(-1px); }
.option-btn.correct { background: linear-gradient(90deg, #d4edda 0%, #c3e6cb 100%); border-color: #c3e6cb; color: #155724; }
.option-btn.wrong { background: linear-gradient(90deg, #f8d7da 0%, #f5c6cb 100%); border-color: #f5c6cb; color: #721c24; }
.difficulty-badge {
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
padding: 4px 12px; border-radius: 20px; background: #fff; font-size: 12px;
}
.feedback-area { margin-top: 20px; padding: 15px; border-radius: 16px; font-size: 15px; line-height: 1.6; }
.feedback-correct { background: #f0fff4; color: #2f855a; border: 1px solid #c6f6d5; }
.feedback-wrong { background: #fff5f5; color: #c53030; border: 1px solid #fed7d7; }
.completion-page { text-align: center; padding: 40px 20px; }
.completion-emoji { font-size: 80px; margin-bottom: 20px; }
.completion-title { font-size: 24px; font-weight: bold; color: #2d3748; }
.final-score { font-size: 48px; font-weight: 800; color: #667eea; margin: 20px 0; text-shadow: 2px 2px 0px rgba(0,0,0,0.1); }
/* 5. 秘籍页 (全屏滑动优化 - 核心修改) */
.secrets-container {
/* 布局重构 */
position: absolute; top: 0; left: 0; right: 0; bottom: 0;
padding-top: 80px; /* 避开标题 */
padding-bottom: 100px; /* 避开底部导航 */
display: flex;
overflow-x: auto; /* 开启横向滚动 */
scroll-snap-type: x mandatory; /* 强制吸附 */
scroll-behavior: smooth;
background: transparent;
align-items: center; /* 垂直居中 */
scrollbar-width: none;
}
.secret-slide {
/* 每个滑块占满宽度 */
flex: 0 0 100%;
width: 100%;
height: 100%;
padding: 20px;
scroll-snap-align: center; /* 吸附到中心 */
display: flex;
justify-content: center;
align-items: center;
}
.secret-card {
width: 100%;
height: 100%;
max-height: 520px; /* 限制最大高度 */
border-radius: 30px;
padding: 40px 30px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
box-shadow: 0 15px 40px rgba(0,0,0,0.15), inset 0 0 0 1px rgba(255,255,255,0.2);
position: relative;
overflow: hidden;
}
/* 为秘籍卡片添加装饰性背景 */
.secret-card::before {
content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%;
background: radial-gradient(circle, rgba(255,255,255,0.2) 0%, transparent 60%);
transform: rotate(30deg); pointer-events: none;
}
.secret-emoji {
font-size: 80px; margin-bottom: 30px;
filter: drop-shadow(0 8px 10px rgba(0,0,0,0.2));
transform: scale(1); transition: transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.secret-card:active .secret-emoji { transform: scale(1.1) rotate(10deg); }
.secret-title {
font-size: 32px; font-weight: 900; color: white;
margin-bottom: 30px;
text-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
.secret-content {
font-size: 22px; color: rgba(255,255,255,0.95); line-height: 1.6;
font-weight: 500;
background: rgba(255,255,255,0.15);
padding: 20px; border-radius: 16px;
backdrop-filter: blur(5px);
width: 100%;
}
/* 提示滑动的小箭头 */
.swipe-hint {
position: absolute; bottom: 120px; left: 0; width: 100%;
text-align: center; color: #a0aec0; font-size: 12px;
animation: fadeInOut 2s infinite; pointer-events: none;
}
@keyframes fadeInOut { 0%,100% {opacity: 0.3} 50% {opacity: 0.8} }
</style>
</head>
<body>
<div id="app">
<div class="content-area">
<div v-show="currentPage === 1" class="intro-page">
<div class="intro-card">
<div class="intro-emoji">🍬</div>
<div class="intro-title">分糖果里的数学</div>
<div class="intro-text">
哥哥和弟弟一起数糖果,一共有 <strong>10块</strong>。哥哥比弟弟多 <strong>2块</strong>。<br><br>
怎么才能知道哥哥和弟弟各有几块糖呢?我们可以用神奇的“线段图”来帮忙!
</div>
<div class="intro-formula">和 = 两数相加<br>差 = 两数相减</div>
<div class="intro-text">
学会了和差问题,我们就能解决生活中很多“一共有多少”和“谁比谁多多少”的问题!
</div>
<button class="listen-btn" @click="speak('哥哥和弟弟一共有10块糖,哥哥比弟弟多2块。怎么求他们各有几块呢?一起来学习吧!')">听老师讲解 🔊</button>
</div>
</div>
<div v-show="currentPage === 2" class="demo-page">
<div class="tab-nav">
<div class="tab-item" :class="{active: demoTab === 'direct'}" @click="switchDemoTab('direct')">动画演示</div>
<div class="tab-item" :class="{active: demoTab === 'theory'}" @click="switchDemoTab('theory')">公式推导</div>
</div>
<div class="demo-section" :class="{active: demoTab === 'direct'}">
<div class="animation-area">
<svg class="svg-container" viewBox="0 0 400 360" id="direct-svg">
<rect id="pillar-brother" class="pillar" x="100" y="150" width="80" height="120" fill="#667eea"/>
<rect id="pillar-sister" class="pillar" x="220" y="190" width="80" height="80" fill="#ff6b9d"/>
<line id="diff-line" class="diff-highlight" x1="140" y1="150" x2="260" y2="150" style="display: none; stroke: #ff4757; stroke-width: 2; stroke-dasharray: 5,5;"/>
<text id="diff-label" x="200" y="140" class="pillar-label" fill="#ff4757" font-weight="bold" text-anchor="middle" style="display: none;">差:2</text>
<text x="140" y="290" class="pillar-label" text-anchor="middle" fill="#555">哥哥</text>
<text x="260" y="290" class="pillar-label" text-anchor="middle" fill="#555">弟弟</text>
<rect id="total-rect" x="50" y="50" width="300" height="40" rx="20" fill="#4CAF50" opacity="0.9"/>
<text x="200" y="78" class="pillar-label" fill="white" font-size="18" text-anchor="middle" font-weight="bold">和:10</text>
<rect id="cut-piece" x="100" y="150" width="80" height="40" fill="#ffa502" opacity="0" stroke="#333" stroke-width="2"/>
<rect id="add-piece" x="220" y="190" width="80" height="40" fill="#00b894" opacity="0" stroke="#333" stroke-width="2"/>
</svg>
</div>
<div class="math-area">
<div class="math-formula" id="direct-formula" style="font-size: 18px; font-weight: bold; text-align: center;">哥哥 + 弟弟 = 10 | 哥哥 - 弟弟 = 2</div>
</div>
<div class="step-explanation" id="direct-explanation">哥哥和弟弟共有10块糖,哥哥比弟弟多2块。</div>
<div class="control-bar">
<button class="step-btn" @click="prevDirectStep" :disabled="directStep === 0">◀ 上一步</button>
<button class="step-btn" @click="nextDirectStep" :disabled="directStep === 3">下一步 ▶</button>
</div>
</div>
<div class="demo-section" :class="{active: demoTab === 'theory'}">
<div class="animation-area" style="display: flex; align-items: center; justify-content: center; flex-direction: column;">
<div style="font-size: 22px; font-weight: bold; color: #333; margin-bottom: 20px;">公式推导</div>
<div style="font-size: 18px; color: #555; text-align: center; line-height: 1.8;">
<div v-if="theoryStep >= 0">已知:大数 + 小数 = 和</div>
<div v-if="theoryStep >= 1">已知:大数 - 小数 = 差</div>
<div v-if="theoryStep >= 2" style="margin-top: 15px; color: #667eea;">两式相加:<br>(大数+小数)+(大数-小数) = 和+差</div>
<div v-if="theoryStep >= 3" style="color: #667eea;">2×大数 = 和+差</div>
<div v-if="theoryStep >= 4" style="font-weight: bold; color: #2e7d32; margin-top: 15px;">大数 = (和 + 差) ÷ 2</div>
<div v-if="theoryStep >= 5" style="margin-top: 20px; color: #ff6b9d;">两式相减可得:<br>小数 = (和 - 差) ÷ 2</div>
</div>
</div>
<div class="step-explanation" id="theory-explanation">让我们一步步推导出和差问题的公式。</div>
<div class="control-bar">
<button class="step-btn" @click="prevTheoryStep" :disabled="theoryStep === 0">◀ 上一步</button>
<button class="step-btn" @click="nextTheoryStep" :disabled="theoryStep === 5">下一步 ▶</button>
</div>
</div>
</div>
<div v-show="currentPage === 3" class="explain-page">
<div class="tab-nav">
<div class="tab-item" :class="{active: explainTab === 'direct'}" @click="switchExplainTab('direct')">直接判断</div>
<div class="tab-item" :class="{active: explainTab === 'core'}" @click="switchExplainTab('core')">核心原理</div>
<div class="tab-item" :class="{active: explainTab === 'example'}" @click="switchExplainTab('example')">典型例题</div>
</div>
<div class="tab-content" :class="{active: explainTab === 'direct'}">
<div class="explain-card">
<div class="explain-card-header">
<span>🧐 如何判断大数和小数?</span>
</div>
<div class="explain-card-body" style="max-height: none; padding-bottom: 20px;">
<div class="example-text" style="margin-top: 15px;">题目中通常会有明确提示:</div>
<div class="example-text" style="color: #667eea; margin: 10px 0;">“A比B多...” → A是大数</div>
<div class="example-text" style="color: #ff6b9d; margin: 10px 0;">“A比B少...” → A是小数</div>
<div class="example-text" style="color: #4CAF50; margin: 10px 0;">“大筐比小筐多...” → 大筐是大数</div>
<div class="example-text" style="margin-top: 15px; font-weight: bold;">先找到谁多谁少,才能正确选择公式!</div>
</div>
</div>
</div>
<div class="tab-content" :class="{active: explainTab === 'core'}">
<div class="explain-card">
<div class="explain-card-header">
<span>🎯 移多补少原理</span>
</div>
<div class="explain-card-body" style="max-height: none; padding-bottom: 20px;">
<div class="example-text" style="margin-top: 15px;">核心思想:让两个数量变得一样多。</div>
<div class="example-text" style="color: #667eea; margin-top: 15px;"><strong>方法一:把多的部分拿走</strong><br>从哥哥那里拿走多出的2块,两人糖果数就相等了,都变得和弟弟原来一样多。<br>总糖果数变为:10 - 2 = 8块。<br>每份:8 ÷ 2 = 4块 → 弟弟原来有4块。</div>
<div class="example-text" style="color: #ff6b9d; margin-top: 15px;"><strong>方法二:给少的补上</strong><br>给弟弟补上2块,两人糖果数就相等了,都变得和哥哥原来一样多。<br>总糖果数变为:10 + 2 = 12块。<br>每份:12 ÷ 2 = 6块 → 哥哥原来有6块。</div>
</div>
</div>
</div>
<div class="tab-content" :class="{active: explainTab === 'example'}">
<div class="explain-card" :class="{expanded: expandedExample === 0}" @click="toggleExample(0)">
<div class="explain-card-header">
<span>📝 例题1:基础题</span>
<span class="card-emoji">{{ expandedExample === 0 ? '👇' : '👉' }}</span>
</div>
<div class="explain-card-body" v-show="expandedExample === 0">
<div class="example-title" style="margin-top: 10px; font-weight: bold;">题目:</div>
<div class="example-text">两筐苹果共 20 个,大筐比小筐多 4 个。小筐有几个?</div>
<div class="example-title" style="margin-top: 10px; font-weight: bold;">答案:</div>
<div class="example-answer">8 个</div>
<div class="example-title" style="margin-top: 10px; font-weight: bold;">解析:</div>
<div class="example-explanation">(和 - 差) ÷ 2 = 小数。 (20 - 4) ÷ 2 = 8。</div>
</div>
</div>
<div class="explain-card" :class="{expanded: expandedExample === 1}" @click="toggleExample(1)">
<div class="explain-card-header">
<span>🚀 例题2:进阶题</span>
<span class="card-emoji">{{ expandedExample === 1 ? '👇' : '👉' }}</span>
</div>
<div class="explain-card-body" v-show="expandedExample === 1">
<div class="example-title" style="margin-top: 10px; font-weight: bold;">题目:</div>
<div class="example-text">小明和小红共有 18 支笔,小明给小红 2 支后,两人一样多。原来各几支?</div>
<div class="example-title" style="margin-top: 10px; font-weight: bold;">答案:</div>
<div class="example-answer">小明 11,小红 7</div>
<div class="example-title" style="margin-top: 10px; font-weight: bold;">解析:</div>
<div class="example-explanation">给 2 支一样多,说明原来相差 2+2=4 支!<br>(18+4)÷2=11(小明),11-4=7(小红)。</div>
</div>
</div>
<div class="explain-card" :class="{expanded: expandedExample === 2}" @click="toggleExample(2)">
<div class="explain-card-header">
<span>⚠️ 例题3:易错题</span>
<span class="card-emoji">{{ expandedExample === 2 ? '👇' : '👉' }}</span>
</div>
<div class="explain-card-body" v-show="expandedExample === 2">
<div class="example-title" style="margin-top: 10px; font-weight: bold;">题目:</div>
<div class="example-text">两数之和是 10,差是 10。这两个数是多少?</div>
<div class="example-title" style="margin-top: 10px; font-weight: bold;">答案:</div>
<div class="example-answer">10 和 0</div>
<div class="example-title" style="margin-top: 10px; font-weight: bold;">解析:</div>
<div class="example-explanation">【易错点】不敢相信有0。<br>大数:(10+10)÷2=10。小数:(10-10)÷2=0。</div>
</div>
</div>
</div>
</div>
<div v-show="currentPage === 4" class="practice-page">
<div v-if="!practiceCompleted">
<div class="question-card">
<div class="question-header">
<div class="question-number">第 {{currentQuestion + 1}}/{{practiceQuestions.length}} 题</div>
<div class="score-display">⭐ {{score}}分</div>
</div>
<div class="question-text" v-html="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
}"
@click="selectOption(index, option.correct)"
:disabled="answered"
>
{{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" style="width: 100%; margin-top: 20px;">
{{currentQuestion < practiceQuestions.length - 1 ? '下一题 →' : '完成练习 ✓'}}
</button>
</div>
</div>
<div v-else class="completion-page">
<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">
<div v-if="!olympiadCompleted">
<div class="question-card">
<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>
<div class="score-display">⭐ {{olympiadScore}}分</div>
</div>
<div class="question-text" v-html="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
}"
@click="selectOlympiadOption(index, option.correct)"
:disabled="olympiadAnswered"
>
{{option.text}}
</button>
</div>
<div v-if="wrongAttempts > 0 && !olympiadAnswered">
<div class="hint-box" v-if="wrongAttempts === 1" style="background: #fffbe6; padding: 10px; margin-top: 10px; border-radius: 8px;">
<strong>💡 提示1:</strong> {{olympiadQuestions[currentOlympiad].hint1}}
</div>
<div class="hint-box" v-if="wrongAttempts === 2" style="background: #fffbe6; padding: 10px; margin-top: 10px; border-radius: 8px;">
<strong>💡 提示2:</strong> {{olympiadQuestions[currentOlympiad].hint2}}
</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" style="width: 100%; margin-top: 20px;">
{{currentOlympiad < olympiadQuestions.length - 1 ? '下一题 →' : '完成挑战 ✓'}}
</button>
</div>
</div>
<div v-else class="completion-page">
<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">
<div class="secret-slide">
<div class="secret-card" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);">
<div class="secret-emoji">🧮</div>
<div class="secret-title">秘籍1:大数公式</div>
<div class="secret-content">(和 + 差) ÷ 2 = 大数</div>
</div>
</div>
<div class="secret-slide">
<div class="secret-card" style="background: linear-gradient(135deg, #ff9a9e 0%, #fecfef 99%, #fecfef 100%);">
<div class="secret-emoji">📐</div>
<div class="secret-title">秘籍2:小数公式</div>
<div class="secret-content" style="color: #d63384; background: rgba(255,255,255,0.6);">(和 - 差) ÷ 2 = 小数</div>
</div>
</div>
<div class="secret-slide">
<div class="secret-card" style="background: linear-gradient(135deg, #84fab0 0%, #8fd3f4 100%);">
<div class="secret-emoji">⚖️</div>
<div class="secret-title">秘籍3:移多补少</div>
<div class="secret-content" style="color: #00796b; background: rgba(255,255,255,0.5);">把多的拿走,或者把少的补上,让他俩变得一样多。</div>
</div>
</div>
<div class="swipe-hint" v-if="currentPage === 6">左右滑动查看更多</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: 'direct',
explainTab: 'direct',
directStep: 0,
theoryStep: 0,
expandedExample: null,
practiceQuestions: [
{
text: "两数和是 12,差是 2。小数是多少?",
options: [
{text: "A. 5", correct: true},
{text: "B. 7", correct: false},
{text: "C. 6", correct: false},
{text: "D. 4", correct: false}
],
explanation: "(和-差)÷2 = 小数。(12-2)÷2 = 10÷2 = 5。"
},
{
text: "两数和是 18,差是 6。大数是多少?",
options: [
{text: "A. 12", correct: true},
{text: "B. 6", correct: false},
{text: "C. 10", correct: false},
{text: "D. 14", correct: false}
],
explanation: "(和+差)÷2 = 大数。(18+6)÷2 = 24÷2 = 12。"
},
{
text: "爸爸买苹果和梨共 10 千克,苹果比梨多 2 千克。苹果多少千克?",
options: [
{text: "A. 4", correct: false},
{text: "B. 5", correct: false},
{text: "C. 6", correct: true},
{text: "D. 7", correct: false}
],
explanation: "苹果是大数。(10+2)÷2 = 12÷2 = 6千克。"
},
{
text: "两个班共有 40 人,一班比二班少 4 人。一班有几人?",
options: [
{text: "A. 18", correct: true},
{text: "B. 22", correct: false},
{text: "C. 20", correct: false},
{text: "D. 16", correct: false}
],
explanation: "一班是小数。(40-4)÷2 = 36÷2 = 18人。"
},
{
text: "长方形周长 20 厘米,长比宽多 2 厘米。长是多少?",
options: [
{text: "A. 6", correct: true},
{text: "B. 7", correct: false},
{text: "C. 12", correct: false},
{text: "D. 5", correct: false}
],
explanation: "长+宽 = 20÷2 = 10厘米。长是大数。(10+2)÷2 = 12÷2 = 6厘米。"
},
{
text: "两堆石子共20个,第一堆比第二堆多6个。第一堆有几个?",
options: [
{text: "A.13", correct: true},
{text: "B.7", correct: false},
{text: "C.14", correct: false},
{text: "D.10", correct: false}
],
explanation: "第一堆是大数。(20+6)÷2 = 26÷2 = 13个。"
},
{
text: "小明期中考试语文数学共得 190 分,数学比语文高 10 分。数学多少分?",
options: [
{text: "A. 90", correct: false},
{text: "B. 100", correct: true},
{text: "C. 95", correct: false},
{text: "D. 85", correct: false}
],
explanation: "数学是大数。(190+10)÷2 = 200÷2 = 100分。"
},
{
text: "甲乙两桶水共 30 千克,甲倒给乙 5 千克后,两桶一样重。甲原来多少千克?",
options: [
{text: "A. 15", correct: false},
{text: "B. 10", correct: false},
{text: "C. 20", correct: true},
{text: "D. 25", correct: false}
],
explanation: "给5千克一样重,说明原来多 5+5=10 千克。甲是大数。(30+10)÷2 = 40÷2 = 20千克。"
}
],
currentQuestion: 0,
answered: false,
selectedOption: null,
isCorrect: false,
score: 0,
practiceCompleted: false,
olympiadQuestions: [
{
text: "小红和小明一共有 50 本书,如果小红给小明 5 本,两人的书就一样多了。小红原来有多少本书?",
options: [
{text: "A. 25", correct: false},
{text: "B. 30", correct: true},
{text: "C. 35", correct: false},
{text: "D. 40", correct: false}
],
hint1: "给5本一样多,说明原来多 5×2=10 本。",
hint2: "和50,差10,求大数。",
hint3: "(50+10)÷2=30。",
explanation: "暗差问题。给5本一样多,说明原来小红比小明多 5×2=10 本。小红是大数。(50+10)÷2 = 30本。",
difficulty: 1,
difficultyText: "⭐"
},
{
text: "两筐水果共重 80 千克,第一筐卖掉 10 千克后,比第二筐还重 6 千克。第一筐原来重多少?",
options: [
{text: "A. 43", correct: false},
{text: "B. 48", correct: true},
{text: "C. 32", correct: false},
{text: "D. 53", correct: false}
],
hint1: "如果第一筐不卖,比第二筐重 10+6=16 千克。",
hint2: "和是80,差是16。",
hint3: "(80+16)÷2=48。",
explanation: "变化后的和差。第一筐卖掉10千克后还比第二筐重6千克,说明如果第一筐不卖,会比第二筐重 10+6=16 千克。第一筐是大数。(80+16)÷2 = 48千克。",
difficulty: 2,
difficultyText: "⭐⭐"
},
{
text: "小猫和小狗共钓了 24 条鱼,小猫钓的比小狗的 2 倍少 3 条。小狗钓了多少条?",
options: [
{text: "A. 7", correct: false},
{text: "B. 8", correct: false},
{text: "C. 9", correct: true},
{text: "D. 10", correct: false}
],
hint1: "把小狗看作1份。小猫是2份少3。",
hint2: "总数+3 = 3份小狗。",
hint3: "27÷3=9。",
explanation: "和倍问题。把小狗钓的鱼看作1份,小猫是2份少3条。如果小猫多钓3条,就是小狗的2倍,总数变成24+3=27条,对应3份。一份是27÷3=9条,即小狗钓了9条。",
difficulty: 2,
difficultyText: "⭐⭐"
},
{
text: "哥哥的钱给弟弟 10 元,两人就一样多;弟弟给哥哥 10 元,哥哥就是弟弟的 3 倍。哥哥有多少钱?",
options: [
{text: "A. 50", correct: true},
{text: "B. 70", correct: false},
{text: "C. 40", correct: false},
{text: "D. 30", correct: false}
],
hint1: "给10元一样多,说明差20元。",
hint2: "弟给哥10元,哥比弟多 20+10+10=40元。",
hint3: "此时哥是弟3倍,差2倍是40,1倍是20。弟现在20,原30。哥原50。",
explanation: "复杂和差。哥哥给弟弟10元后一样多,说明哥哥原来比弟弟多10+10=20元。弟弟给哥哥10元后,哥哥比弟弟多20+10+10=40元,此时哥哥是弟弟的3倍,即哥哥比弟弟多2倍。所以1倍是40÷2=20元(弟弟现在的钱)。弟弟原来有20+10=30元,哥哥原来有30+20=50元。",
difficulty: 3,
difficultyText: "⭐⭐⭐"
},
{
text: "有大、小两个水桶,共装水 20 千克。如果从大桶倒 2 千克水到小桶,大桶还比小桶多 2 千克。大桶原来装水多少?",
options: [
{text: "A. 13", correct: true},
{text: "B. 12", correct: false},
{text: "C. 14", correct: false},
{text: "D. 11", correct: false}
],
hint1: "大桶减少2,小桶增加2,差距缩小4。",
hint2: "现在差2,说明原来差 2+4=6。",
hint3: "(20+6)÷2=13。",
explanation: "操作后仍有差。倒水后,大桶减少2千克,小桶增加2千克,两桶差距缩小了4千克。倒水后大桶还比小桶多2千克,说明原来大桶比小桶多2+4=6千克。大桶是大数。(20+6)÷2 = 13千克。",
difficulty: 3,
difficultyText: "⭐⭐⭐"
},
{
text: "两数之和是 48,大数减去小数等于 24。大数是?",
options: [
{text: "A. 24", correct: false},
{text: "B. 36", correct: true},
{text: "C. 12", correct: false},
{text: "D. 30", correct: false}
],
hint1: "和是48,差是24。",
hint2: "求大数,用(和+差)÷2。",
hint3: "(48+24)÷2=36。",
explanation: "基本和差问题。大数 = (和+差)÷2 = (48+24)÷2 = 72÷2 = 36。",
difficulty: 1,
difficultyText: "⭐"
},
{
text: "箱子里有红球和白球共 30 个,红球比白球多 4 个。红球有几个?",
options: [
{text: "A. 13", correct: false},
{text: "B. 17", correct: true},
{text: "C. 15", correct: false},
{text: "D. 19", correct: false}
],
hint1: "红球是大数。(30+4)÷2。",
hint2: "34÷2=17。",
hint3: "红球有17个。",
explanation: "基本和差。红球是大数。(30+4)÷2 = 34÷2 = 17个。",
difficulty: 1,
difficultyText: "⭐"
},
{
text: "三年级有 3 个班,一班二班共 80 人,二班三班共 84 人,一班三班共 86 人。三个班各几人?",
options: [
{text: "A. 40, 40, 44", correct: false},
{text: "B. 41, 39, 45", correct: true},
{text: "C. 42, 38, 46", correct: false},
{text: "D. 40, 42, 46", correct: false}
],
hint1: "三个总和加起来 (80+84+86)=250 是总人数的2倍。",
hint2: "总人数 125。",
hint3: "三班=125-80=45。二班=84-45=39。一班=86-45=41。",
explanation: "重复相加。一班+二班=80,二班+三班=84,一班+三班=86。把这三个和相加:(80+84+86)=250,这相当于每个班都被加了两次,所以三个班总人数是250÷2=125人。三班人数=125-80=45人,二班人数=84-45=39人,一班人数=86-45=41人。",
difficulty: 3,
difficultyText: "⭐⭐⭐"
}
],
currentOlympiad: 0,
olympiadAnswered: false,
selectedOlympiadOption: null,
isOlympiadCorrect: false,
olympiadScore: 0,
wrongAttempts: 0,
olympiadCompleted: false,
directSteps: [
"哥哥和弟弟共有10块糖,哥哥比弟弟多2块。让我们用柱子来表示。",
"把哥哥多出来的2块拿走,他们俩的糖果就一样多了,都变得和弟弟原来一样多。总糖果数减少2块。",
"或者,给弟弟补上2块,他们俩的糖果也一样多了,都变得和哥哥原来一样多。总糖果数增加2块。",
"通过这两种方法,我们都能求出哥哥和弟弟原来各有几块糖。这就是和差问题的核心思想——移多补少!"
],
theorySteps: [
"我们有两个已知条件。",
"第二个已知条件。",
"把两个等式相加。",
"化简得到大数的公式。",
"大数公式推导完成!",
"用同样的方法相减,可以推导出小数公式。"
]
};
},
mounted() {
this.runDirectAnimation();
},
methods: {
switchPage(page) {
this.stopSpeak();
this.currentPage = page;
if (page === 2) {
this.directStep = 0;
this.theoryStep = 0;
this.runDirectAnimation();
} else if (page === 4) {
this.currentQuestion = 0;
this.answered = false;
this.selectedOption = null;
this.isCorrect = false;
this.score = 0;
this.practiceCompleted = false;
} else if (page === 5) {
this.currentOlympiad = 0;
this.olympiadAnswered = false;
this.selectedOlympiadOption = null;
this.isOlympiadCorrect = false;
this.olympiadScore = 0;
this.wrongAttempts = 0;
this.olympiadCompleted = false;
}
},
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.stopSpeak();
this.demoTab = tab;
if (tab === 'direct') {
this.directStep = 0;
this.runDirectAnimation();
} else {
this.theoryStep = 0;
}
},
switchExplainTab(tab) {
this.stopSpeak();
this.explainTab = tab;
this.expandedExample = null;
},
toggleExample(index) {
this.expandedExample = this.expandedExample === index ? null : index;
},
runDirectAnimation() {
if (typeof gsap === 'undefined') return;
const tl = gsap.timeline();
const svgNS = "http://www.w3.org/2000/svg";
tl.set("#diff-line, #diff-label, #cut-piece, #add-piece", {clearProps: "all"});
if (this.directStep === 0) {
tl.to("#pillar-brother", {y: 150, height: 120, duration: 0.8, ease: "bounce.out"})
.to("#pillar-sister", {y: 190, height: 80, duration: 0.8, ease: "bounce.out"}, "-=0.6")
.set("#diff-line", {attr: {x1: 140, y1: 150, x2: 260, y2: 150}, display: 'block'})
.set("#diff-label", {attr: {x: 200, y: 140}, display: 'block'});
document.getElementById('direct-formula').innerHTML = "哥哥 + 弟弟 = 10 | 哥哥 - 弟弟 = 2";
document.getElementById('direct-explanation').innerHTML = "哥哥和弟弟共有10块糖,哥哥比弟弟多2块。";
} else if (this.directStep === 1) {
tl.to("#pillar-brother", {height: 80, y: 190, duration: 0.8, ease: "power2.inOut"})
.set("#cut-piece", {attr: {x: 100, y: 150, width: 80, height: 40}, fill: '#ffa502', opacity: 1})
.to("#cut-piece", {y: 300, duration: 0.8, ease: "back.in(1.7)"}, "+=0.2")
.to("#total-rect", {attr: {width: 250}, x: 75, duration: 0.5}, "-=0.5");
document.getElementById('direct-formula').innerHTML = "10 - 2 = 8 | 8 ÷ 2 = 4 (弟弟)";
document.getElementById('direct-explanation').innerHTML = "把哥哥多出来的2块拿走,两人糖果数相等,都变成弟弟原来的数量。总糖果变成8块,每人4块。";
} else if (this.directStep === 2) {
tl.to("#pillar-sister", {height: 120, y: 150, duration: 0.8, ease: "power2.inOut"})
.set("#add-piece", {attr: {x: 220, y: 270, width: 80, height: 40}, fill: '#00b894', opacity: 1})
.to("#add-piece", {y: 190, duration: 0.8, ease: "bounce.out"}, "+=0.2")
.to("#total-rect", {attr: {width: 350}, x: 25, duration: 0.5}, "-=0.5");
document.getElementById('direct-formula').innerHTML = "10 + 2 = 12 | 12 ÷ 2 = 6 (哥哥)";
document.getElementById('direct-explanation').innerHTML = "给弟弟补上2块,两人糖果数相等,都变成哥哥原来的数量。总糖果变成12块,每人6块。";
} else if (this.directStep === 3) {
tl.to("#pillar-brother", {y: 150, height: 120, duration: 0.5})
.to("#pillar-sister", {y: 190, height: 80, duration: 0.5}, "-=0.3")
.to("#cut-piece", {opacity: 0, duration: 0.3})
.to("#add-piece", {opacity: 0, duration: 0.3})
.to("#total-rect", {attr: {width: 300}, x: 50, duration: 0.5});
document.getElementById('direct-formula').innerHTML = "哥哥 = 6块 | 弟弟 = 4块";
document.getElementById('direct-explanation').innerHTML = "通过这两种方法,我们都能求出哥哥有6块糖,弟弟有4块糖。这就是和差问题的核心思想——移多补少!";
}
},
nextDirectStep() {
if (this.directStep < 3) {
this.directStep++;
this.runDirectAnimation();
}
},
prevDirectStep() {
if (this.directStep > 0) {
this.directStep--;
this.runDirectAnimation();
}
},
nextTheoryStep() {
if (this.theoryStep < 5) this.theoryStep++;
},
prevTheoryStep() {
if (this.theoryStep > 0) this.theoryStep--;
},
selectOption(index, correct) {
if (this.answered) return;
this.answered = true;
this.selectedOption = index;
this.isCorrect = correct;
if (correct) {
this.score += 20;
if (typeof confetti !== 'undefined') {
confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 } });
}
}
},
nextQuestion() {
if (this.currentQuestion < this.practiceQuestions.length - 1) {
this.currentQuestion++;
this.answered = false;
this.selectedOption = null;
this.isCorrect = false;
} else {
this.practiceCompleted = true;
}
},
selectOlympiadOption(index, correct) {
if (this.olympiadAnswered) return;
this.selectedOlympiadOption = index;
if (correct) {
this.olympiadAnswered = true;
this.isOlympiadCorrect = true;
this.olympiadScore += 30;
this.wrongAttempts = 0;
if (typeof confetti !== 'undefined') {
confetti({ particleCount: 150, spread: 100, origin: { y: 0.6 } });
}
} else {
this.wrongAttempts++;
if (this.wrongAttempts >= 3) {
this.olympiadAnswered = true;
this.isOlympiadCorrect = false;
}
}
},
nextOlympiad() {
if (this.currentOlympiad < this.olympiadQuestions.length - 1) {
this.currentOlympiad++;
this.olympiadAnswered = false;
this.selectedOlympiadOption = null;
this.isOlympiadCorrect = false;
this.wrongAttempts = 0;
} else {
this.olympiadCompleted = true;
}
}
}
}).mount('#app');
</script>
</body>
</html>
💡 这段代码完全由 AI 生成。
登录后可复制完整代码