<!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>第03讲:加减法巧算技巧</title>
<style>
/* =========================================
基础重置 & 全局样式 (保持风格统一)
========================================= */
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
::-webkit-scrollbar { display: none; width: 0 !important; height: 0 !important; }
* { -ms-overflow-style: none; scrollbar-width: none; }
html, body {
margin: 0; padding: 0;
background: linear-gradient(180deg, #fdfbfb 0%, #ebedee 100%);
overflow: hidden;
height: 100vh;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
#app {
height: 100vh;
max-width: 480px;
margin: 0 auto;
background: transparent;
display: flex;
flex-direction: column;
position: relative;
}
.content-area {
flex: 1;
overflow-y: auto;
padding-bottom: 90px;
scroll-behavior: smooth;
}
.dot-pattern-bg {
background-image: radial-gradient(#cbd5e1 1.5px, transparent 1.5px);
background-size: 24px 24px;
}
/* =========================================
UI 组件:圆润、微投影
========================================= */
.bottom-nav {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
width: 90%;
max-width: 440px;
height: 65px;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: 35px;
display: flex;
justify-content: space-around;
align-items: center;
z-index: 9999;
box-shadow: 0 10px 25px 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; cursor: pointer; transition: all 0.3s; color: #94a3b8; }
.nav-item.active { color: #667eea; transform: translateY(-4px); }
.nav-icon { font-size: 20px; margin-bottom: 2px; }
.nav-label { font-size: 10px; font-weight: 500; }
.page-container { padding: 24px 20px; }
.page-title { font-size: 24px; font-weight: 800; color: #1e293b; margin-bottom: 20px; text-align: center; letter-spacing: -0.5px; }
.emoji-intro { font-size: 72px; text-align: center; margin: 30px 0; filter: drop-shadow(0 4px 6px rgba(0,0,0,0.1)); }
.story-box {
background: #fff;
padding: 20px;
border-radius: 20px;
margin-bottom: 25px;
line-height: 1.8;
color: #475569;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
border: 1px solid rgba(0,0,0,0.03);
}
.concept-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 25px;
border-radius: 24px;
margin-bottom: 20px;
box-shadow: 0 10px 25px rgba(118, 75, 162, 0.3);
position: relative;
overflow: hidden;
}
.concept-card::before {
content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%;
background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 60%);
transform: rotate(30deg);
}
.listen-btn {
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
color: white; border: none; padding: 14px 45px; border-radius: 50px;
font-size: 16px; font-weight: bold; cursor: pointer; display: block; margin: 30px auto 0;
transition: transform 0.2s;
box-shadow: 0 8px 20px rgba(245, 87, 108, 0.35);
}
.listen-btn:active { transform: scale(0.95); }
.tab-nav { display: flex; background: #f1f5f9; border-radius: 16px; padding: 4px; margin-bottom: 25px; border: none; }
.tab-item {
flex: 1; padding: 10px; text-align: center; cursor: pointer;
border-radius: 12px; font-weight: 600; color: #64748b; transition: all 0.3s ease;
}
.tab-item.active {
background: white; color: #667eea;
box-shadow: 0 4px 6px rgba(0,0,0,0.05);
}
.animation-area {
background: white;
border-radius: 24px;
padding: 20px; height: 300px; /* 调整高度 */
position: relative;
display: flex; align-items: center; justify-content: center;
margin-bottom: 20px; overflow: hidden;
box-shadow: inset 0 2px 6px rgba(0,0,0,0.03);
border: 1px solid #f1f5f9;
}
.svg-container { width: 100%; height: 100%; }
/* 数字卡片样式 (用于SVG动画) */
.num-block { cursor: pointer; }
.num-bg { fill: #f0f9ff; stroke: #3b82f6; stroke-width: 2; rx: 10; ry: 10; }
.num-text { font-size: 24px; font-weight: bold; fill: #333; pointer-events: none; }
.sign-text { font-size: 24px; font-weight: bold; fill: #ef4444; pointer-events: none; }
.sign-plus { fill: #10b981; }
.math-area {
background: white;
background-image: linear-gradient(white, white), linear-gradient(135deg, #667eea, #764ba2);
background-origin: border-box;
background-clip: content-box, border-box;
border: 2px solid transparent;
border-radius: 20px;
padding: 15px; margin-bottom: 15px;
min-height: 90px;
display: flex; align-items: center; justify-content: center;
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.15);
}
.math-formula { font-size: 24px; font-weight: 800; color: #333; text-align: center; }
.step-explanation {
background: #f8fafc; padding: 18px; border-radius: 16px;
color: #475569; font-size: 15px; text-align: center; margin-bottom: 20px; line-height: 1.6;
border: 1px solid #e2e8f0;
}
.step-btn {
position: absolute; top: 50%; transform: translateY(-50%); z-index: 100;
background: rgba(255, 255, 255, 0.9);
color: #667eea; border: 1px solid #e2e8f0;
width: 44px; height: 44px; border-radius: 50%;
font-size: 18px; cursor: pointer;
box-shadow: 0 4px 10px rgba(0,0,0,0.1);
display: flex; align-items: center; justify-content: center;
}
.step-btn:hover { background: white; transform: translateY(-50%) scale(1.1); }
.step-btn-prev { left: 15px; }
.step-btn-next { right: 15px; }
.example-card, .question-card {
background: white; border-radius: 24px; padding: 25px; margin-bottom: 20px;
box-shadow: 0 10px 20px rgba(0,0,0,0.03), 0 2px 6px rgba(0,0,0,0.02);
border: 1px solid rgba(0,0,0,0.02);
}
.example-header { display: flex; justify-content: space-between; align-items: center; cursor: pointer; padding-bottom: 5px;}
.example-title { font-weight: 700; color: #3b82f6; font-size: 17px; }
.question-text { font-size: 19px; margin-bottom: 25px; line-height: 1.6; color: #1e293b; font-weight: 600;}
.options-container { display: flex; flex-direction: column; gap: 15px; margin-bottom: 20px; }
.option-btn {
padding: 18px 20px;
border: 2px solid #f1f5f9;
border-radius: 16px;
background: #fff;
font-size: 16px;
color: #475569;
text-align: left;
cursor: pointer;
transition: all 0.2s;
position: relative;
overflow: hidden;
}
.option-btn:active { transform: scale(0.98); background: #f8fafc; }
.option-btn.correct { background-color: #ecfdf5; border-color: #10b981; color: #047857; font-weight: bold; }
.option-btn.wrong { background-color: #fef2f2; border-color: #ef4444; color: #b91c1c; }
.next-btn {
display: block; width: 100%; padding: 18px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white; border: none; border-radius: 18px;
font-size: 17px; font-weight: bold;
cursor: pointer; margin-top: 25px;
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.3);
transition: transform 0.2s;
}
.difficulty-badge { padding: 4px 10px; border-radius: 12px; font-weight: bold; }
/* =========================================
秘籍卡片滑动容器 (核心需求)
========================================= */
.secrets-scroll-container {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
gap: 20px;
padding: 20px 20px 40px 20px;
height: calc(100vh - 150px);
align-items: center;
}
.secret-card {
flex: 0 0 100%;
width: 100%;
min-height: 500px;
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
border-radius: 30px;
padding: 40px 30px;
box-shadow: 0 20px 40px -10px rgba(0,0,0,0.15), 0 0 0 1px rgba(255,255,255,0.4) inset;
scroll-snap-align: center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
.secret-icon { font-size: 100px; margin-bottom: 30px; filter: drop-shadow(0 10px 10px rgba(0,0,0,0.1)); }
.secret-card h3 { font-size: 28px; color: #fff; margin: 0 0 20px 0; text-shadow: 0 2px 4px rgba(0,0,0,0.1); }
.secret-card p { font-size: 20px; line-height: 1.8; color: rgba(255,255,255,0.95); font-weight: 500; margin: 0; }
.swipe-hint { text-align: center; color: #94a3b8; font-size: 12px; margin-top: -10px; opacity: 0.8; }
</style>
</head>
<body>
<div id="app">
<div class="content-area">
<div v-show="currentPage === 1" class="intro-page page-container dot-pattern-bg">
<div class="page-title">加减法巧算技巧</div>
<div class="emoji-intro">🧙♂️</div>
<div class="story-box">
<p>数字王国里有两条重要的魔法规则,学会了它们,计算速度就能快如闪电!</p>
<p>第一条叫“<strong>带符号搬家</strong>”:数字要移动,必须带着它前面的“+”或“-”号一起走。</p>
<p>第二条叫“<strong>去括号变号</strong>”:括号前面是减号,去掉括号后,里面的符号都要变身(+变-,-变+)!</p>
</div>
<div class="concept-card">
<h3>📚 核心口诀</h3>
<p><strong>搬家规则</strong>:带着符号走,哪里需要哪里搬。</p>
<p style="margin-top:8px;"><strong>去括号(前有+)</strong>:括号直接去,符号都不变。</p>
<p style="margin-top:8px;"><strong>去括号(前有-)</strong>:括号前面是减号,去掉括号要变号。</p>
</div>
<button class="listen-btn" @click="speak('数字要移动,必须带着它前面的符号一起走。括号前面是减号,去掉括号要变号。+变-,-变+。')">🔊 听老师讲解</button>
</div>
<div v-show="currentPage === 2" class="demo-page page-container">
<div class="tab-nav">
<div class="tab-item active">带符号搬家演示</div>
</div>
<div class="demo-section">
<div class="animation-area">
<button class="step-btn step-btn-prev" @click="prevDirectStep" :disabled="directStep === 0">◀</button>
<button class="step-btn step-btn-next" @click="nextDirectStep" :disabled="directStep === 3">▶</button>
<svg class="svg-container" viewBox="0 0 400 300">
<g id="block1" transform="translate(40, 100)">
<rect width="80" height="60" class="num-bg" />
<text x="40" y="38" text-anchor="middle" class="num-text">128</text>
</g>
<g id="block2" transform="translate(140, 100)">
<rect width="80" height="60" class="num-bg" />
<text x="20" y="38" text-anchor="middle" class="sign-text sign-plus">+</text>
<text x="50" y="38" text-anchor="middle" class="num-text">59</text>
</g>
<g id="block3" transform="translate(240, 100)">
<rect width="80" height="60" class="num-bg" style="stroke:#ef4444; fill:#fef2f2;" />
<text x="20" y="38" text-anchor="middle" class="sign-text">-</text>
<text x="50" y="38" text-anchor="middle" class="num-text">28</text>
</g>
<path id="moveArrow" d="M280 170 Q 190 230 100 170" fill="none" stroke="#667eea" stroke-width="3" marker-end="url(#arrowhead)" opacity="0" />
<defs>
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#667eea" />
</marker>
</defs>
</svg>
</div>
<div class="math-area">
<div class="math-formula">{{ directStepFormulas[directStep] }}</div>
</div>
<div class="step-explanation">{{ directStepExplanations[directStep] }}</div>
</div>
</div>
<div v-show="currentPage === 3" class="explain-page page-container">
<div class="tab-nav">
<div class="tab-item" :class="{active: explainTab === 'basic'}" @click="explainTab='basic'">符号搬家</div>
<div class="tab-item" :class="{active: explainTab === 'advance'}" @click="explainTab='advance'">去括号</div>
<div class="tab-item" :class="{active: explainTab === 'tricky'}" @click="explainTab='tricky'">基准数</div>
</div>
<div v-show="explainTab === 'basic'">
<div class="example-card">
<div class="example-header" @click="toggleExample('basic')">
<div class="example-title">例题1:凑整法</div>
<div class="toggle-btn">{{ exampleOpen.basic ? '▲ 收起' : '▼ 展开' }}</div>
</div>
<div class="example-content" v-show="exampleOpen.basic">
<div class="question"><strong>题目</strong>:计算 234 - 88 + 66</div>
<div class="answer"><strong>思路</strong>:234 和 66 是好朋友,可以凑成 300。</div>
<div class="explanation">
原式 = 234 <span style="color:#e11d48; font-weight:bold;">+ 66</span> - 88 (带符号搬家)<br>
= 300 - 88<br>
= 212
</div>
</div>
</div>
</div>
<div v-show="explainTab === 'advance'">
<div class="example-card">
<div class="example-header" @click="toggleExample('advance')">
<div class="example-title">例题2:减号在括号前</div>
<div class="toggle-btn">{{ exampleOpen.advance ? '▲ 收起' : '▼ 展开' }}</div>
</div>
<div class="example-content" v-show="exampleOpen.advance">
<div class="question"><strong>题目</strong>:计算 500 - (120 - 80)</div>
<div class="answer"><strong>口诀</strong>:减号在门前,开门要变脸。</div>
<div class="explanation">
原式 = 500 - 120 <span style="color:#e11d48; font-weight:bold;">+</span> 80 (注意变号)<br>
= 380 + 80<br>
= 460
</div>
</div>
</div>
</div>
<div v-show="explainTab === 'tricky'">
<div class="example-card">
<div class="example-header" @click="toggleExample('tricky')">
<div class="example-title">例题3:基准数法</div>
<div class="toggle-btn">{{ exampleOpen.tricky ? '▲ 收起' : '▼ 展开' }}</div>
</div>
<div class="example-content" v-show="exampleOpen.tricky">
<div class="question"><strong>题目</strong>:98 + 99 + 101 + 102</div>
<div class="answer"><strong>思路</strong>:大家都很接近 100。</div>
<div class="explanation">
原式 = (100-2) + (100-1) + (100+1) + (100+2)<br>
= 400 - 2 - 1 + 1 + 2<br>
= 400 (抵消啦!)
</div>
</div>
</div>
</div>
</div>
<div v-show="currentPage === 4" class="practice-page page-container">
<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'" style="padding:15px; border-radius:12px; margin-top:15px; background:#f0fdf4;">
<div v-if="isCorrect" style="color:#15803d;">
<strong>🎉 正确!</strong><br>
{{practiceQuestions[currentQuestion].explanation}}
</div>
<div v-else style="color:#b91c1c;">
<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" style="text-align:center; padding:50px 20px;">
<div class="completion-emoji" style="font-size:80px; margin-bottom:20px;">🎊</div>
<div class="completion-title">练习完成!</div>
<div class="final-score" style="font-size:48px; font-weight:bold; color:#667eea; margin:20px 0;">{{score}}分</div>
<button class="restart-btn" @click="switchPage(5)" style="background:linear-gradient(135deg, #667eea, #764ba2); color:white; border:none; padding:15px 40px; border-radius:30px; font-size:18px;">挑战奥数真题 →</button>
</div>
</div>
<div v-show="currentPage === 5" class="practice-page page-container">
<div v-if="!olympiadCompleted">
<div class="question-card">
<div class="question-header">
<div>
<span class="question-number">第 {{currentOlympiad + 1}} 题</span>
<span class="difficulty-badge" :style="{backgroundColor: getDiffColor(olympiadQuestions[currentOlympiad].difficulty).bg, color: getDiffColor(olympiadQuestions[currentOlympiad].difficulty).text}">
{{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:#fef3c7; padding:12px; border-radius:8px; color:#92400e; margin-top:10px;">
<strong>💡 提示:</strong> {{olympiadQuestions[currentOlympiad].hint1}}
</div>
</div>
<div v-if="olympiadAnswered" class="feedback-area" style="padding:15px; border-radius:12px; margin-top:15px;" :style="{backgroundColor: isOlympiadCorrect?'#ecfdf5':'#fef2f2', color: isOlympiadCorrect?'#047857':'#b91c1c'}">
<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 >= 2" class="next-btn" @click="nextOlympiad">
{{currentOlympiad < olympiadQuestions.length - 1 ? '下一题 →' : '完成挑战 ✓'}}
</button>
</div>
</div>
<div v-else class="completion-page" style="text-align:center; padding:50px 20px;">
<div class="completion-emoji" style="font-size:80px; margin-bottom:20px;">🏆</div>
<div class="completion-title">奥数挑战完成!</div>
<div class="final-score" style="font-size:48px; font-weight:bold; color:#667eea; margin:20px 0;">{{olympiadScore}}分</div>
<button class="restart-btn" @click="switchPage(6)" style="background:linear-gradient(135deg, #f093fb, #f5576c); color:white; border:none; padding:15px 40px; border-radius:30px; font-size:18px;">查看通关秘籍 →</button>
</div>
</div>
<div v-show="currentPage === 6">
<div class="secrets-scroll-container">
<div class="secret-card">
<div class="secret-icon">🚚</div>
<h3>秘籍1:带符号搬家</h3>
<p>数字移动很自由,<br>前面符号跟着走。<br>例如:12 + 5 - 2 = 12 - 2 + 5</p>
</div>
<div class="secret-card" style="background: linear-gradient(135deg, #fbc2eb 0%, #a6c1ee 100%);">
<div class="secret-icon">🎭</div>
<h3>秘籍2:去括号变号</h3>
<p>括号前面是减号,<br>去掉括号要变号。<br>加变减,减变加!</p>
</div>
<div class="secret-card" style="background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%);">
<div class="secret-icon">🤝</div>
<h3>秘籍3:找朋友(凑整)</h3>
<p>尾数互补是朋友,<br>凑成整十整百走。<br>1和9,2和8,3和7...</p>
</div>
</div>
<div class="swipe-hint">← 左右滑动查看更多秘籍 →</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: 'basic',
directStep: 0,
exampleOpen: { basic: true, advance: false, tricky: false },
directStepFormulas: [
'计算:128 + 59 - 28',
'第一步:观察数字',
'第二步:带着符号搬家',
'结果:100 + 59 = 159'
],
directStepExplanations: [
'我们看到算式:128 加 59 减 28。按顺序算有点慢,有没有更快的办法?',
'发现了吗?128 和 28 的尾巴是一样的!如果先把它们减一下就好了。',
'关键动作:把“-28”整个搬到“+59”的前面。记住,搬家要带上前面的负号哦!',
'现在算式变成了 128 - 28 + 59。先算 128-28=100,再加 59,答案就是 159!'
],
// 课内练习 (8道)
practiceQuestions: [
{ text: "计算 25 + 13 - 5,最简便的方法是?", options: [{text: "按顺序算", correct: false}, {text: "先算 25-5", correct: true}, {text: "先算 13-5", correct: false}], explanation: "25-5=20,20+13=33。" },
{ text: "下面的搬家,哪个是对的?<br>12 - 3 + 5", options: [{text: "12 + 5 - 3", correct: true}, {text: "12 - 5 + 3", correct: false}, {text: "12 + 3 - 5", correct: false}], explanation: "搬家要带着符号走,-3搬走,+5搬来。" },
{ text: "计算 78 + 25 - 28", options: [{text: "70", correct: false}, {text: "75", correct: true}, {text: "80", correct: false}], explanation: "78 - 28 = 50,50 + 25 = 75。" },
{ text: "去括号:100 - (20 - 5)", options: [{text: "100 - 20 - 5", correct: false}, {text: "100 - 20 + 5", correct: true}, {text: "100 + 20 - 5", correct: false}], explanation: "括号前是减号,去掉括号要变号,-5变+5。" },
{ text: "去括号:100 + (30 - 10)", options: [{text: "100 + 30 - 10", correct: true}, {text: "100 + 30 + 10", correct: false}], explanation: "括号前是加号,去掉括号符号不变。" },
{ text: "47 - 8 - 2 等于?", options: [{text: "47 - (8 - 2)", correct: false}, {text: "47 - (8 + 2)", correct: true}], explanation: "连续减去两个数,等于减去这两个数的和。" },
{ text: "123 + 99 (用凑整法)", options: [{text: "123 + 100 + 1", correct: false}, {text: "123 + 100 - 1", correct: true}], explanation: "多加了1,要减掉。" },
{ text: "563 - 198 (用凑整法)", options: [{text: "563 - 200 + 2", correct: true}, {text: "563 - 200 - 2", correct: false}], explanation: "多减了2,要加回来。" }
],
// 奥数真题 (8道)
olympiadQuestions: [
{ text: "【希望杯】计算 478 - 128 + 122 - 72", options: [{text: "A. 300", correct: false}, {text: "B. 400", correct: true}, {text: "C. 350", correct: false}], hint1: "478-128=350", explanation: "478-128=350,122-72=50,350+50=400。", difficulty: 2, difficultyText: "⭐⭐" },
{ text: "【中环杯】计算 2000 - (2000 - 19)", options: [{text: "A. 19", correct: true}, {text: "B. 3981", correct: false}, {text: "C. 0", correct: false}], hint1: "拆括号,注意变号", explanation: "原式 = 2000 - 2000 + 19 = 19。", difficulty: 2, difficultyText: "⭐⭐" },
{ text: "【小机灵杯】100 - 99 + 98 - 97 + ... + 2 - 1", options: [{text: "A. 100", correct: false}, {text: "B. 50", correct: true}, {text: "C. 49", correct: false}], hint1: "两个一组", explanation: "(100-99) + (98-97) ... 共有50组,每组是1。1×50=50。", difficulty: 3, difficultyText: "⭐⭐⭐" },
{ text: "【华杯赛】9 + 99 + 999 + 9999 + 4", options: [{text: "A. 11110", correct: true}, {text: "B. 11114", correct: false}], hint1: "把4分成四个1", explanation: "4拆成1+1+1+1,分别补给四个9开头的数,变成10+100+1000+10000=11110。", difficulty: 3, difficultyText: "⭐⭐⭐" },
{ text: "【迎春杯】1000 - 36 - 64 - 25 - 75", options: [{text: "A. 900", correct: false}, {text: "B. 800", correct: true}, {text: "C. 700", correct: false}], hint1: "连续减,可以加括号", explanation: "1000 - (36+64) - (25+75) = 1000 - 100 - 100 = 800。", difficulty: 2, difficultyText: "⭐⭐" },
{ text: "【走美杯】325 - (125 - 83)", options: [{text: "A. 200", correct: false}, {text: "B. 117", correct: false}, {text: "C. 283", correct: true}], hint1: "拆括号,-125变+125?", hint2: "减号变加号", explanation: "325 - 125 + 83 = 200 + 83 = 283。", difficulty: 2, difficultyText: "⭐⭐" },
{ text: "【思维挑战】1 - 2 + 3 - 4 + 5 - ... - 98 + 99", options: [{text: "A. 49", correct: false}, {text: "B. 50", correct: true}, {text: "C. 0", correct: false}], hint1: "从后面往前分组", hint2: "99-98=1, 97-96=1...", explanation: "99 - (98-97) - (96-95)... 不对。正确分组:(1)单独,(-2+3)=1, (-4+5)=1... 共49个1,加上开头的1,共50。", difficulty: 3, difficultyText: "⭐⭐⭐" },
{ text: "【高难度】1234 + 567 - 234 + 433", options: [{text: "A. 2000", correct: true}, {text: "B. 1900", correct: false}], hint1: "带符号搬家,找好朋友", explanation: "(1234-234) + (567+433) = 1000 + 1000 = 2000。", difficulty: 3, difficultyText: "⭐⭐⭐" }
],
currentQuestion: 0,
answered: false,
selectedOption: null,
isCorrect: false,
score: 0,
practiceCompleted: false,
currentOlympiad: 0,
olympiadAnswered: false,
selectedOlympiadOption: null,
isOlympiadCorrect: false,
olympiadScore: 0,
olympiadCompleted: false,
wrongAttempts: 0
};
},
methods: {
switchPage(page) {
this.stopSpeak();
this.currentPage = page;
if (page === 2) {
this.directStep = 0;
this.runDirectAnimation();
}
if (page === 4) {
this.currentQuestion = 0; this.answered = false; this.selectedOption = null; this.score = 0; this.practiceCompleted = false;
}
if (page === 5) {
this.currentOlympiad = 0; this.olympiadAnswered = false; this.selectedOlympiadOption = null; this.olympiadScore = 0; this.olympiadCompleted = false; this.wrongAttempts = 0;
}
},
getDiffColor(level) {
if(level===1) return {bg:'#d1fae5', text:'#065f46'};
if(level===2) return {bg:'#fef3c7', text:'#92400e'};
return {bg:'#fee2e2', text:'#991b1b'};
},
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);
}
},
runDirectAnimation() {
if (typeof gsap === 'undefined') return;
gsap.killTweensOf("#block1, #block2, #block3, #moveArrow, #formulaText");
const tl = gsap.timeline();
// 初始位置
const pos1 = 40, pos2 = 140, pos3 = 240;
if (this.directStep === 0) {
// 还原位置
gsap.set("#block1", { x: pos1, opacity: 1 });
gsap.set("#block2", { x: pos2, opacity: 1 });
gsap.set("#block3", { x: pos3, opacity: 1 });
gsap.set("#moveArrow", { opacity: 0 });
} else if (this.directStep === 1) {
// 强调 Block1 和 Block3
tl.to("#block1, #block3", { scale: 1.1, duration: 0.3, transformOrigin: "center center", yoyo: true, repeat: 1 });
} else if (this.directStep === 2) {
// 搬家动画:Block3 移到 Block2 前面
tl.to("#moveArrow", { opacity: 1, duration: 0.5 });
tl.to("#block3", { x: pos2, duration: 0.8, ease: "power2.inOut" }, "+=0.2");
tl.to("#block2", { x: pos3, duration: 0.8, ease: "power2.inOut" }, "<"); // 同时移动
tl.to("#moveArrow", { opacity: 0, duration: 0.3 });
}
},
nextDirectStep() { if (this.directStep < 3) { this.directStep++; this.runDirectAnimation(); } },
prevDirectStep() { if (this.directStep > 0) { this.directStep--; this.runDirectAnimation(); } },
toggleExample(key) { this.exampleOpen[key] = !this.exampleOpen[key]; },
selectOption(index, correct) {
if (this.answered) return;
this.answered = true; this.selectedOption = index; this.isCorrect = correct;
if (correct) { this.score += 12.5; 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; } else { this.practiceCompleted = true; }
},
selectOlympiadOption(index, correct) {
if (this.olympiadAnswered) return;
this.selectedOlympiadOption = index;
if (correct) {
this.olympiadAnswered = true; this.isOlympiadCorrect = true; this.olympiadScore += 12.5; this.wrongAttempts = 0;
if (typeof confetti !== 'undefined') confetti({ particleCount: 150, spread: 80, origin: { y: 0.6 } });
} else {
this.wrongAttempts++;
if (navigator.vibrate) navigator.vibrate(200);
if (this.wrongAttempts >= 2) { 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 生成。
登录后可复制完整代码