<!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>2的整除特征 - 完整版</title>
<style>
* {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent;
}
html, body {
margin: 0;
padding: 0;
background: #F0F0F0;
overflow: hidden;
height: 100vh;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
#app {
height: 100vh;
width: 100%;
max-width: 480px;
margin: 0 auto;
background: #fff;
display: flex;
flex-direction: column;
position: relative;
box-shadow: 0 0 20px rgba(0,0,0,0.05);
}
.content-area {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
padding-bottom: 80px;
position: relative;
}
.bottom-nav {
position: fixed;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 100%;
max-width: 480px;
height: 70px;
background: white;
border-top: 1px solid #e0e0e0;
display: flex;
justify-content: space-around;
align-items: center;
z-index: 1000;
box-shadow: 0 -2px 10px rgba(0,0,0,0.05);
}
.nav-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
padding: 8px;
transition: all 0.3s;
}
.nav-item.active {
color: #667eea;
}
.nav-icon {
font-size: 24px;
margin-bottom: 4px;
}
.nav-label {
font-size: 12px;
}
/* Page 1: 概念引入 */
.intro-page {
padding: 40px 20px;
text-align: center;
}
.intro-emoji {
font-size: 80px;
margin: 20px 0;
animation: bounce 2s infinite;
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
.intro-title {
font-size: 28px;
font-weight: bold;
color: #333;
margin: 20px 0;
}
.intro-story {
font-size: 16px;
line-height: 1.8;
color: #666;
text-align: left;
background: #f8f9fa;
padding: 20px;
border-radius: 12px;
margin: 20px 0;
border-left: 4px solid #667eea;
}
.highlight {
color: #667eea;
font-weight: bold;
}
.speak-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 12px 30px;
border-radius: 25px;
font-size: 16px;
cursor: pointer;
margin-top: 20px;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
}
/* 演示页面样式 */
.demo-page {
padding: 20px;
}
/* 标签导航 */
.tab-nav {
display: flex;
border-bottom: 2px solid #e0e0e0;
margin-bottom: 20px;
}
.tab-item {
flex: 1;
padding: 12px;
text-align: center;
cursor: pointer;
color: #666;
font-weight: 500;
border-bottom: 3px solid transparent;
transition: all 0.3s;
}
.tab-item.active {
color: #667eea;
border-bottom-color: #667eea;
}
.demo-section {
display: none;
}
.demo-section.active {
display: block;
animation: fadeIn 0.3s;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.animation-area {
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
border-radius: 16px;
padding: 20px;
min-height: 320px;
max-height: 320px;
margin-bottom: 20px;
position: relative;
overflow: hidden;
border: 2px solid #e0e0e0;
}
.math-area {
background: white;
border: 2px solid #667eea;
border-radius: 12px;
padding: 12px;
margin-bottom: 15px;
min-height: 90px;
}
.math-formula {
font-size: 16px;
text-align: center;
color: #333;
line-height: 2;
font-weight: 500;
}
.step-explanation {
font-size: 14px;
color: #666;
margin-top: 10px;
line-height: 1.6;
text-align: center;
padding: 10px;
background: #f8f9fa;
border-radius: 8px;
}
.control-bar {
display: flex;
justify-content: center;
gap: 15px;
margin-top: 20px;
}
.step-btn {
background: #667eea;
color: white;
border: none;
padding: 10px 25px;
border-radius: 20px;
font-size: 14px;
cursor: pointer;
transition: all 0.3s;
}
.step-btn:disabled {
background: #ccc;
cursor: not-allowed;
}
.step-btn:hover:not(:disabled) {
transform: scale(1.05);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}
/* SVG动画样式 */
.svg-container {
width: 100%;
height: 100%;
min-height: 280px;
}
/* 讲解页面样式 */
.explain-page {
padding: 20px;
}
.explain-section {
display: none;
}
.explain-section.active {
display: block;
animation: fadeIn 0.3s;
}
.method-card {
background: white;
border-radius: 12px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 10px rgba(0,0,0,0.08);
border-left: 4px solid #667eea;
}
.method-title {
font-size: 18px;
font-weight: bold;
color: #333;
margin-bottom: 15px;
display: flex;
align-items: center;
gap: 8px;
}
.method-content {
font-size: 15px;
line-height: 1.8;
color: #555;
}
.example-box {
background: #f8f9fa;
padding: 15px;
border-radius: 8px;
margin: 10px 0;
border-left: 3px solid #10b981;
}
.example-title {
font-weight: bold;
color: #10b981;
margin-bottom: 8px;
}
.steps-list {
list-style: none;
padding: 0;
margin: 15px 0;
}
.steps-list li {
padding: 10px;
margin: 8px 0;
background: #f8f9fa;
border-radius: 8px;
position: relative;
padding-left: 40px;
}
.steps-list li::before {
content: attr(data-step);
position: absolute;
left: 10px;
top: 50%;
transform: translateY(-50%);
width: 24px;
height: 24px;
background: #667eea;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: bold;
}
.question-examples {
margin-top: 20px;
}
.question-item {
background: white;
padding: 15px;
margin: 10px 0;
border-radius: 8px;
border: 2px solid #e0e0e0;
transition: all 0.3s;
cursor: pointer;
}
.question-item:hover {
border-color: #667eea;
transform: translateX(5px);
}
.question-item.expanded {
border-color: #667eea;
background: #f8f9fa;
}
.question-header {
font-weight: bold;
color: #333;
display: flex;
justify-content: space-between;
align-items: center;
}
.question-answer {
margin-top: 15px;
padding-top: 15px;
border-top: 1px dashed #e0e0e0;
color: #555;
line-height: 1.8;
display: none;
}
.question-item.expanded .question-answer {
display: block;
}
.expand-icon {
color: #667eea;
transition: transform 0.3s;
}
.question-item.expanded .expand-icon {
transform: rotate(180deg);
}
/* 练习题样式 */
.practice-page {
padding: 20px;
height: 100%;
display: flex;
flex-direction: column;
}
.question-card {
background: white;
border-radius: 16px;
padding: 25px;
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
margin-bottom: 20px;
}
.question-number {
background: #667eea;
color: white;
padding: 5px 15px;
border-radius: 20px;
font-size: 14px;
}
.score-display {
background: #fef3c7;
padding: 5px 15px;
border-radius: 20px;
font-weight: bold;
color: #92400e;
}
.difficulty-badge {
display: inline-block;
padding: 4px 12px;
border-radius: 12px;
font-size: 12px;
font-weight: bold;
margin-left: 10px;
}
.difficulty-bronze { background: #fed7aa; color: #9a3412; }
.difficulty-silver { background: #e5e7eb; color: #374151; }
.difficulty-gold { background: #fef3c7; color: #92400e; }
.question-text {
font-size: 18px;
line-height: 1.6;
color: #333;
margin: 20px 0;
}
.options-container {
display: flex;
flex-direction: column;
gap: 12px;
margin: 20px 0;
}
.option-btn {
background: white;
border: 2px solid #e0e0e0;
border-radius: 12px;
padding: 15px;
text-align: left;
font-size: 16px;
cursor: pointer;
transition: all 0.3s;
}
.option-btn:hover {
border-color: #667eea;
transform: translateX(5px);
}
.option-btn.correct {
background: #d1fae5;
border-color: #10b981;
}
.option-btn.wrong {
background: #fee2e2;
border-color: #ef4444;
}
.option-btn:disabled {
cursor: not-allowed;
}
.feedback-area {
margin-top: 20px;
padding: 15px;
border-radius: 12px;
font-size: 14px;
line-height: 1.6;
}
.feedback-correct {
background: #d1fae5;
color: #065f46;
}
.feedback-wrong {
background: #fee2e2;
color: #991b1b;
}
.hint-box {
background: #fffbeb;
border-left: 4px solid #f59e0b;
padding: 15px;
border-radius: 8px;
margin: 15px 0;
font-size: 14px;
line-height: 1.6;
}
.next-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 12px 30px;
border-radius: 25px;
font-size: 16px;
cursor: pointer;
margin-top: 15px;
width: 100%;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
}
/* 通关秘籍 */
.secrets-container {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
padding: 20px;
gap: 16px;
height: 100%;
align-items: center;
-webkit-overflow-scrolling: touch;
}
.secrets-container::-webkit-scrollbar {
display: none;
}
.secret-card {
min-width: 85%;
height: 450px;
scroll-snap-align: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 20px;
color: white;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 30px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
flex-shrink: 0;
}
.secret-emoji {
font-size: 80px;
margin-bottom: 20px;
}
.secret-title {
font-size: 24px;
font-weight: bold;
margin-bottom: 15px;
text-align: center;
}
.secret-rule {
font-size: 20px;
background: rgba(255,255,255,0.2);
padding: 15px 25px;
border-radius: 15px;
margin: 20px 0;
text-align: center;
font-weight: bold;
}
.secret-explanation {
font-size: 15px;
line-height: 1.8;
text-align: center;
opacity: 0.95;
}
/* 完成页面 */
.completion-page {
padding: 40px 20px;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
}
.completion-emoji {
font-size: 100px;
margin: 20px 0;
}
.completion-title {
font-size: 32px;
font-weight: bold;
color: #667eea;
margin: 20px 0;
}
.final-score {
font-size: 48px;
font-weight: bold;
color: #667eea;
margin: 20px 0;
}
.restart-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 15px 40px;
border-radius: 30px;
font-size: 18px;
cursor: pointer;
margin-top: 20px;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
}
</style>
</head>
<body>
<div id="app">
<div class="content-area">
<!-- Page 1: 概念引入 -->
<div v-show="currentPage === 1" class="intro-page">
<div class="intro-emoji">👦👧</div>
<div class="intro-title">2的整除特征</div>
<div class="intro-story">
<strong>🍬 分糖果的故事</strong><br><br>
小明的妈妈买了一袋糖果,想要<span class="highlight">平均分给小明和妹妹两个人</span>。<br><br>
妈妈使用<span class="highlight">"打包魔法"</span>:把糖果每10个装进一个盒子📦里。<br><br>
因为 <strong>10 ÷ 2 = 5</strong>,所以<span class="highlight">每一个盒子都能平均分给2个人</span>,不管有多少盒糖果,统统都能分光!<br><br>
<strong>关键</strong>:剩下的就是<span class="highlight">散落在外面的零糖(个位)</span>。<br><br>
如果零糖是 <strong>偶数(0,2,4,6,8)</strong>,正好分完!<br>
如果是奇数,就分不匀了。😢
</div>
<button class="speak-btn" @click="speakIntro">🔊 听老师讲解</button>
</div>
<!-- Page 2: 演示动画 -->
<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 330" preserveAspectRatio="xMidYMid meet">
<!-- 标题 -->
<text id="direct-title" x="200" y="25" text-anchor="middle" font-size="18" font-weight="bold" fill="#333">
方法一: 看个位数字
</text>
<!-- 步骤0: 显示数字358 -->
<g id="direct-number-group" opacity="1">
<text x="200" y="90" text-anchor="middle" font-size="50" font-weight="bold" fill="#667eea">358</text>
<text x="200" y="120" text-anchor="middle" font-size="14" fill="#666">判断这个数能否被2整除?</text>
</g>
<!-- 步骤1: 拆分显示各位 -->
<g id="direct-split-group" opacity="0">
<rect x="50" y="75" width="80" height="65" rx="12" fill="#f3f4f6" stroke="#cbd5e0" stroke-width="2"/>
<text x="90" y="112" text-anchor="middle" font-size="32" fill="#666">3</text>
<text x="90" y="152" text-anchor="middle" font-size="10" fill="#999">百位</text>
<rect x="140" y="75" width="80" height="65" rx="12" fill="#f3f4f6" stroke="#cbd5e0" stroke-width="2"/>
<text x="180" y="112" text-anchor="middle" font-size="32" fill="#666">5</text>
<text x="180" y="152" text-anchor="middle" font-size="10" fill="#999">十位</text>
<rect id="direct-ones-box" x="230" y="75" width="120" height="65" rx="12" fill="#eef2ff" stroke="#667eea" stroke-width="3"/>
<text id="direct-ones-digit" x="290" y="112" text-anchor="middle" font-size="32" font-weight="bold" fill="#667eea">8</text>
<text x="290" y="152" text-anchor="middle" font-size="10" font-weight="bold" fill="#667eea">个位</text>
</g>
<!-- 步骤2: 判断偶数 -->
<g id="direct-judge-group" opacity="0">
<rect x="50" y="165" width="300" height="50" rx="12" fill="#fffbeb" stroke="#f59e0b" stroke-width="2"/>
<text x="200" y="185" text-anchor="middle" font-size="12" fill="#92400e" font-weight="bold">
判断个位是偶数还是奇数
</text>
<text id="direct-judge-text" x="200" y="204" text-anchor="middle" font-size="14" font-weight="bold" fill="#f59e0b">
8 是偶数
</text>
</g>
<!-- 步骤3: 结论 -->
<g id="direct-result-group" opacity="0">
<circle cx="200" cy="260" r="32" fill="#d1fae5" stroke="#10b981" stroke-width="3"/>
<text x="200" y="270" text-anchor="middle" font-size="32">✓</text>
<text x="200" y="305" text-anchor="middle" font-size="12" font-weight="bold" fill="#10b981">能被2整除</text>
</g>
</svg>
</div>
<div class="math-area">
<div class="math-formula">
<div v-if="directStep === 0">358 能被2整除吗?</div>
<div v-if="directStep === 1">
核心: 只看个位!<br>
<small style="color: #666;">个位是偶数(0,2,4,6,8) → 能整除</small>
</div>
<div v-if="directStep === 2">
个位是 <strong style="color: #667eea;">8</strong> (偶数)<br>
<small style="color: #666;">0,2,4,6,8 都是偶数</small>
</div>
<div v-if="directStep === 3">
✓ 358 能被2整除<br>
<small style="color: #10b981;">验算: 358 ÷ 2 = 179</small>
</div>
</div>
</div>
<div class="step-explanation" v-if="directStep === 0">
准备判断358这个数
</div>
<div class="step-explanation" v-if="directStep === 1">
把数字拆开,重点关注个位!
</div>
<div class="step-explanation" v-if="directStep === 2">
判断个位8是偶数还是奇数
</div>
<div class="step-explanation" v-if="directStep === 3">
因为个位是偶数,所以能被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">
<svg class="svg-container" viewBox="0 0 400 330" preserveAspectRatio="xMidYMid meet">
<!-- 标题 -->
<text id="theory-title" x="200" y="30" text-anchor="middle" font-size="18" font-weight="bold" fill="#333">
位值原理: 为什么只看个位?
</text>
<!-- 步骤0: 显示1234 -->
<g id="theory-number-group" opacity="1">
<text x="200" y="100" text-anchor="middle" font-size="50" font-weight="bold" fill="#667eea">1234</text>
<text x="200" y="135" text-anchor="middle" font-size="14" fill="#666">能被2整除吗?</text>
</g>
<!-- 步骤1: 拆分公式 -->
<g id="theory-split-group" opacity="0">
<text x="200" y="80" text-anchor="middle" font-size="16" fill="#333">
拆包魔法: 任何数 = 整十部分 + 个位
</text>
<rect x="60" y="100" width="120" height="70" rx="10" fill="#eef2ff" stroke="#667eea" stroke-width="2"/>
<text x="120" y="130" text-anchor="middle" font-size="28" font-weight="bold" fill="#667eea">1230</text>
<text x="120" y="155" text-anchor="middle" font-size="12" fill="#667eea">整十部分</text>
<text x="200" y="140" text-anchor="middle" font-size="24" fill="#333">+</text>
<rect x="220" y="100" width="120" height="70" rx="10" fill="#fee2e2" stroke="#ef4444" stroke-width="2"/>
<text x="280" y="130" text-anchor="middle" font-size="28" font-weight="bold" fill="#ef4444">4</text>
<text x="280" y="155" text-anchor="middle" font-size="12" fill="#ef4444">个位</text>
</g>
<!-- 步骤2: 整十部分分析 -->
<g id="theory-tens-group" opacity="0">
<rect x="50" y="200" width="300" height="80" rx="12" fill="#d1fae5" stroke="#10b981" stroke-width="2"/>
<text x="200" y="225" text-anchor="middle" font-size="14" font-weight="bold" fill="#065f46">
整十部分分析
</text>
<text x="200" y="250" text-anchor="middle" font-size="16" fill="#065f46">
1230 = 123 × 10
</text>
<text x="200" y="272" text-anchor="middle" font-size="14" fill="#047857">
因为 10 ÷ 2 = 5
</text>
</g>
<!-- 步骤3: 个位分析 -->
<g id="theory-ones-group" opacity="0">
<rect x="50" y="295" width="140" height="60" rx="10" fill="#fee2e2" stroke="#ef4444" stroke-width="2"/>
<text x="120" y="320" text-anchor="middle" font-size="14" font-weight="bold" fill="#991b1b">
个位部分
</text>
<text x="120" y="342" text-anchor="middle" font-size="16" fill="#991b1b">
4 ÷ 2 = 2 ✓
</text>
<text x="210" y="330" text-anchor="middle" font-size="24" fill="#10b981" font-weight="bold">→</text>
<rect x="230" y="295" width="120" height="60" rx="10" fill="#d1fae5" stroke="#10b981" stroke-width="2"/>
<text x="290" y="320" text-anchor="middle" font-size="14" font-weight="bold" fill="#065f46">
结论
</text>
<text x="290" y="342" text-anchor="middle" font-size="14" fill="#065f46">
能被2整除 ✓
</text>
</g>
</svg>
</div>
<div class="math-area">
<div class="math-formula">
<div v-if="theoryStep === 0">1234 = ?</div>
<div v-if="theoryStep === 1">
1234 = 1230 + 4<br>
<small style="color: #666;">(整十部分 + 个位)</small>
</div>
<div v-if="theoryStep === 2">
1230 = 123 × 10<br>
10 ÷ 2 = 5 → <strong style="color: #10b981;">整十部分一定能被2整除</strong>
</div>
<div v-if="theoryStep === 3">
4 ÷ 2 = 2 ✓<br>
<small style="color: #10b981;">两部分都能整除,所以1234能被2整除!</small>
</div>
</div>
</div>
<div class="step-explanation" v-if="theoryStep === 0">
让我们探索为什么只看个位就够了
</div>
<div class="step-explanation" v-if="theoryStep === 1">
第一步: 把数字拆成整十部分和个位
</div>
<div class="step-explanation" v-if="theoryStep === 2">
关键: 因为10能被2整除,所以整十部分一定能被2整除!
</div>
<div class="step-explanation" v-if="theoryStep === 3">
只要个位也能被2整除,整个数就能被2整除!
</div>
<div class="control-bar">
<button class="step-btn" @click="prevTheoryStep" :disabled="theoryStep === 0">
◀ 上一步
</button>
<button class="step-btn" @click="nextTheoryStep" :disabled="theoryStep === 3">
下一步 ▶
</button>
</div>
</div>
</div>
<!-- Page 3: 讲解页 -->
<div v-show="currentPage === 3" class="explain-page">
<div class="tab-nav">
<div class="tab-item" :class="{active: explainTab === 'direct'}" @click="explainTab = 'direct'">
直接判断
</div>
<div class="tab-item" :class="{active: explainTab === 'theory'}" @click="explainTab = 'theory'">
位值原理
</div>
<div class="tab-item" :class="{active: explainTab === 'examples'}" @click="explainTab = 'examples'">
拆分验证
</div>
</div>
<!-- 直接判断 -->
<div class="explain-section" :class="{active: explainTab === 'direct'}">
<div class="method-card">
<div class="method-title">
<span>🎯</span> 方法一: 看个位数字
</div>
<div class="method-content">
<p><strong>核心口诀:</strong> "不管前面多少位,只看个位那一位!"</p>
<div class="example-box">
<div class="example-title">判断规则:</div>
个位是 <strong style="color: #10b981;">0, 2, 4, 6, 8</strong> (偶数) → 能被2整除 ✓<br>
个位是 <strong style="color: #ef4444;">1, 3, 5, 7, 9</strong> (奇数) → 不能被2整除 ✗
</div>
<ul class="steps-list">
<li data-step="1">找到个位数字</li>
<li data-step="2">判断是偶数还是奇数</li>
<li data-step="3">得出结论</li>
</ul>
<div class="example-box">
<div class="example-title">实例:</div>
• 358 → 个位是8(偶数) → <strong style="color: #10b981;">能整除</strong><br>
• 12345 → 个位是5(奇数) → <strong style="color: #ef4444;">不能整除</strong><br>
• 9876540 → 个位是0(偶数) → <strong style="color: #10b981;">能整除</strong>
</div>
</div>
</div>
<div class="method-card">
<div class="method-title">
<span>⚡</span> 秒杀技巧
</div>
<div class="method-content">
<p>遇到超大数字也不用慌:</p>
<div class="example-box">
123456789012345678 → 只看最后一位: 8 → <strong style="color: #10b981;">能整除</strong>
</div>
<p style="margin-top: 10px; color: #667eea;">
💡 前面有多少位都不重要,一秒锁定个位!
</p>
</div>
</div>
</div>
<!-- 位值原理 -->
<div class="explain-section" :class="{active: explainTab === 'theory'}">
<div class="method-card">
<div class="method-title">
<span>📐</span> 为什么只看个位?
</div>
<div class="method-content">
<p><strong>核心原理:</strong> 10是2的倍数!</p>
<div class="example-box">
<div class="example-title">拆包魔法:</div>
任何数 = 整十部分 + 个位<br><br>
<strong>例如:</strong> 1234 = 1230 + 4<br>
<span style="color: #667eea;">= 123 × 10 + 4</span>
</div>
<ul class="steps-list">
<li data-step="1">
整十部分: 123 × 10<br>
<small style="color: #666;">因为10 ÷ 2 = 5,所以一定能被2整除</small>
</li>
<li data-step="2">
个位部分: 4<br>
<small style="color: #666;">4是偶数,也能被2整除</small>
</li>
<li data-step="3">
结论: 两部分都能整除,所以1234能被2整除!
</li>
</ul>
<div class="example-box">
<div class="example-title">反例:</div>
1235 = 1230 + 5<br>
• 整十部分1230能被2整除 ✓<br>
• 个位5不能被2整除 ✗<br>
→ 所以1235不能被2整除
</div>
</div>
</div>
<div class="method-card">
<div class="method-title">
<span>🔍</span> 数学证明
</div>
<div class="method-content">
<p>设任意数为 N = 10a + b (其中b是个位)</p>
<div class="example-box">
N ÷ 2 = (10a + b) ÷ 2<br>
= 10a ÷ 2 + b ÷ 2<br>
= 5a + b ÷ 2
</div>
<p style="margin-top: 15px;">
因为 <strong>5a</strong> 一定是整数,所以:<br>
<span style="color: #667eea;">N能被2整除 ⟺ b能被2整除 ⟺ b是偶数</span>
</p>
</div>
</div>
</div>
<!-- 拆分验证 -->
<div class="explain-section" :class="{active: explainTab === 'examples'}">
<div class="method-card">
<div class="method-title">
<span>🧮</span> 实战演练
</div>
<div class="method-content">
<p>点击题目查看详细解析:</p>
</div>
</div>
<div class="question-examples">
<div class="question-item" :class="{expanded: expandedQ === 1}" @click="toggleQuestion(1)">
<div class="question-header">
<span>判断 358 能否被2整除</span>
<span class="expand-icon">▼</span>
</div>
<div class="question-answer">
<strong>📝 完整过程:</strong><br><br>
<strong>步骤1:</strong> 拆分数字<br>
358 = 350 + 8<br>
= 35 × 10 + 8<br><br>
<strong>步骤2:</strong> 分析整十部分<br>
35 × 10 ÷ 2 = 35 × 5 = 175 ✓<br>
(整十部分一定能被2整除)<br><br>
<strong>步骤3:</strong> 分析个位<br>
8 ÷ 2 = 4 ✓<br>
(8是偶数,能被2整除)<br><br>
<strong style="color: #10b981;">✅ 结论: 358能被2整除</strong><br>
验算: 358 ÷ 2 = 179
</div>
</div>
<div class="question-item" :class="{expanded: expandedQ === 2}" @click="toggleQuestion(2)">
<div class="question-header">
<span>判断 12345 能否被2整除</span>
<span class="expand-icon">▼</span>
</div>
<div class="question-answer">
<strong>📝 完整过程:</strong><br><br>
<strong>步骤1:</strong> 拆分数字<br>
12345 = 12340 + 5<br>
= 1234 × 10 + 5<br><br>
<strong>步骤2:</strong> 分析整十部分<br>
1234 × 10 ÷ 2 = 1234 × 5 = 6170 ✓<br>
(整十部分一定能被2整除)<br><br>
<strong>步骤3:</strong> 分析个位<br>
5 ÷ 2 = 2 余 1 ✗<br>
(5是奇数,不能被2整除)<br><br>
<strong style="color: #ef4444;">❌ 结论: 12345不能被2整除</strong><br>
验算: 12345 ÷ 2 = 6172.5
</div>
</div>
<div class="question-item" :class="{expanded: expandedQ === 3}" @click="toggleQuestion(3)">
<div class="question-header">
<span>四位数 37□8 的□里填什么都能被2整除?</span>
<span class="expand-icon">▼</span>
</div>
<div class="question-answer">
<strong>📝 完整分析:</strong><br><br>
<strong>关键发现:</strong><br>
个位已经是8(偶数),所以这个数一定能被2整除!<br><br>
<strong>原理:</strong><br>
37□8 = 3700 + □×10 + 8<br><br>
• 3700 能被2整除 ✓ (整百)<br>
• □×10 能被2整除 ✓ (整十)<br>
• 8 能被2整除 ✓ (偶数)<br><br>
<strong style="color: #10b981;">✅ 答案: □里可以填0-9任意数字,共10种!</strong><br><br>
验证:<br>
3708 ÷ 2 = 1854 ✓<br>
3738 ÷ 2 = 1869 ✓<br>
3798 ÷ 2 = 1899 ✓
</div>
</div>
<div class="question-item" :class="{expanded: expandedQ === 4}" @click="toggleQuestion(4)">
<div class="question-header">
<span>用1,2,3组成能被2整除的三位数(不重复)</span>
<span class="expand-icon">▼</span>
</div>
<div class="question-answer">
<strong>📝 完整思路:</strong><br><br>
<strong>步骤1:</strong> 确定个位<br>
要被2整除,个位必须是偶数<br>
可选: 2(唯一的偶数)<br><br>
<strong>步骤2:</strong> 排列剩余数字<br>
个位固定为2,剩下1和3排百位和十位<br><br>
可能的组合:<br>
• 百位1,十位3 → <strong>132</strong> ✓<br>
• 百位3,十位1 → <strong>312</strong> ✓<br><br>
<strong style="color: #10b981;">✅ 答案: 2个 (132和312)</strong><br><br>
验算:<br>
132 ÷ 2 = 66 ✓<br>
312 ÷ 2 = 156 ✓
</div>
</div>
</div>
</div>
</div>
<!-- Page 4: 课内练习 -->
<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">
{{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>
<div style="font-size: 18px; color: #666; margin: 20px 0;">
{{score >= 60 ? '太棒了!可以挑战奥数题了!' : '继续加油哦!'}}
</div>
<button class="restart-btn" @click="switchPage(5)">
挑战奥数题 →
</button>
</div>
</div>
<!-- Page 5: 奥数挑战 -->
<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">
<strong>💡 提示1:</strong> {{olympiadQuestions[currentOlympiad].hint1}}
</div>
<div class="hint-box" v-if="wrongAttempts === 2">
<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">
{{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>
<div style="font-size: 18px; color: #666; margin: 20px 0;">
{{olympiadScore >= 60 ? '你是真正的数学高手!' : '继续努力,你会更棒!'}}
</div>
<button class="restart-btn" @click="switchPage(6)">
查看通关秘籍 →
</button>
</div>
</div>
<!-- Page 6: 通关秘籍 -->
<div v-show="currentPage === 6" class="secrets-container">
<div class="secret-card">
<div class="secret-emoji">🎯</div>
<div class="secret-title">核心口诀</div>
<div class="secret-rule">
"不管前面多少位,<br>只看个位那一位!"
</div>
<div class="secret-explanation">
个位是 0,2,4,6,8 的数,<br>
都能被 2 整除。<br><br>
记住:只看个位是偶数还是奇数!
</div>
</div>
<div class="secret-card" style="background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);">
<div class="secret-emoji">📦</div>
<div class="secret-title">打包魔法</div>
<div class="secret-rule">
任何数 = 盒子 + 零糖
</div>
<div class="secret-explanation">
盒子(整十部分)一定能被2整除,<br>
因为10 ÷ 2 = 5<br><br>
所以只需要判断零糖(个位)!<br><br>
例: 1234 = 1230 + 4<br>
只看4能不能被2整除
</div>
</div>
<div class="secret-card" style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);">
<div class="secret-emoji">⚡</div>
<div class="secret-title">秒杀技巧</div>
<div class="secret-rule">
看个位,一秒搞定!
</div>
<div class="secret-explanation">
遇到很大的数也不怕:<br><br>
123456 → 个位是6 → ✓<br>
999998 → 个位是8 → ✓<br>
7777777 → 个位是7 → ✗<br><br>
前面的数字再多也不管它!
</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: 'direct',
explainTab: 'direct',
expandedQ: null,
directStep: 0,
theoryStep: 0,
// 课内练习
currentQuestion: 0,
score: 0,
answered: false,
isCorrect: false,
selectedOption: null,
practiceCompleted: false,
practiceQuestions: [
{
text: '下面哪些数能被2整除?',
options: [
{ text: '135', correct: false },
{ text: '246', correct: true },
{ text: '7891', correct: false },
{ text: '1000', correct: true }
],
explanation: '看末尾! 246(尾6)✅, 1000(尾0)✅。其他个位不是偶数,都不能被2整除。'
},
{
text: '1到20中,有多少个数能被2整除?',
options: [
{ text: '5个', correct: false },
{ text: '8个', correct: false },
{ text: '10个', correct: true },
{ text: '12个', correct: false }
],
explanation: '2, 4, 6, 8...一直到20。用20÷2=10个。每隔2个就有一个!'
},
{
text: '四位数37□8能被2整除,方框里可以填哪些数字?',
options: [
{ text: '只能填0', correct: false },
{ text: '只能填偶数', correct: false },
{ text: '0-9都可以', correct: true },
{ text: '只能填2,4,6,8', correct: false }
],
explanation: '个位已经是8了,所以这个数一定能被2整除! 方框在十位,填什么都行。0-9共10个数字。'
},
{
text: '一个三位数,百位是2,个位是3,它能被2整除吗?',
options: [
{ text: '能', correct: false },
{ text: '不能', correct: true }
],
explanation: '只看个位! 个位是3,不是偶数,所以不能被2整除。百位是什么不重要。'
},
{
text: '数字12346的个位是6,它能被2整除吗?',
options: [
{ text: '能', correct: true },
{ text: '不能', correct: false }
],
explanation: '个位是6,偶数,所以12346能被2整除! 12346 ÷ 2 = 6173。'
}
],
// 奥数挑战
currentOlympiad: 0,
olympiadScore: 0,
olympiadAnswered: false,
isOlympiadCorrect: false,
selectedOlympiadOption: null,
wrongAttempts: 0,
olympiadCompleted: false,
olympiadQuestions: [
{
difficulty: 'bronze',
difficultyText: '🥉 青铜',
text: '一个四位数37□8能被2整除,方框里可以填几个数字?',
options: [
{ text: '1个', correct: false },
{ text: '5个', correct: false },
{ text: '10个', correct: true },
{ text: '0个', correct: false }
],
hint1: '个位已经是8了,这意味着什么?',
hint2: '只要个位是偶数,整个数就能被2整除。方框在十位,对整除性没有影响。',
explanation: '因为个位是8(偶数),所以这个数一定能被2整除!方框在十位上,对整除性没有影响。所以0-9任意数字都可以填,共10种填法。'
},
{
difficulty: 'bronze',
difficultyText: '🥉 青铜',
text: '算式1×2×3×...×2025的结果,能被2整除吗?',
options: [
{ text: '能', correct: true },
{ text: '不能', correct: false }
],
hint1: '这串乘法里有偶数吗?',
hint2: '只要有一个偶数因子,整个积就是偶数。',
explanation: '1×2×3×...×2025里包含因子2(以及4,6,8...所有偶数),所以乘积一定是偶数,能被2整除。'
},
{
difficulty: 'silver',
difficultyText: '🥈 白银',
text: '用1、2、3这三张数字卡片,能组成多少个没有重复数字且能被2整除的三位数?',
options: [
{ text: '1个', correct: false },
{ text: '2个', correct: true },
{ text: '3个', correct: false },
{ text: '6个', correct: false }
],
hint1: '个位必须是偶数,从1,2,3中选哪个?',
hint2: '个位必须是2,然后排列剩下的1和3。',
explanation: '个位必须是2(唯一的偶数)。剩下1,3排前两位:132和312。总共2个。'
},
{
difficulty: 'silver',
difficultyText: '🥈 白银',
text: '五位数4□7□8能被6整除,这个五位数最小是多少?(6=2×3)',
options: [
{ text: '40728', correct: false },
{ text: '41748', correct: false },
{ text: '40758', correct: true },
{ text: '42738', correct: false }
],
hint1: '能被6整除=既能被2整除,又能被3整除。',
hint2: '个位是8,满足被2整除。要被3整除,各位数字和必须是3的倍数。',
explanation: '个位8满足被2整除。要被3整除:4+万位+7+十位+8=19+两框,需是3的倍数。为了最小,万位填0。19+0+十位,最小填5使24是3的倍数。答案:40758。'
},
{
difficulty: 'silver',
difficultyText: '🥈 白银',
text: '从1到100的所有整数相加,和能被2整除吗?',
options: [
{ text: '能', correct: true },
{ text: '不能', correct: false }
],
hint1: '算出总和是多少。公式:(1+100)×100÷2',
hint2: '总和是5050,看个位。',
explanation: '总和=(1+100)×100÷2=5050。个位是0,偶数,能被2整除。'
},
{
difficulty: 'gold',
difficultyText: '🥇 黄金',
text: '一个数除以2余1,除以3也余1,这个数最小是多少?',
options: [
{ text: '1', correct: true },
{ text: '3', correct: false },
{ text: '5', correct: false },
{ text: '7', correct: false }
],
hint1: '除以2余1,个位是奇数。',
hint2: '同时满足两个条件的最小数是多少?',
explanation: '除以2余1的数:1,3,5,7,9... 除以3余1的数:1,4,7,10... 同时满足的最小数是1。验证:1÷2=0余1✓,1÷3=0余1✓。'
},
{
difficulty: 'gold',
difficultyText: '🥇 黄金',
text: '在123456789中,最少划去几个数字,能让剩下的数被2整除?',
options: [
{ text: '0个', correct: false },
{ text: '1个', correct: true },
{ text: '2个', correct: false },
{ text: '3个', correct: false }
],
hint1: '要被2整除,个位必须是偶数。',
hint2: '原数个位是9(奇数),只需要划掉它。',
explanation: '原数个位是9(奇数),不能被2整除。只需划掉个位的9,剩下12345678,个位是8(偶数),能被2整除。最少划1个。'
},
{
difficulty: 'gold',
difficultyText: '🥇 黄金',
text: '六位数abcde8除以2后变成4bcde4,个位数字e是多少?',
options: [
{ text: '4', correct: false },
{ text: '8', correct: true },
{ text: '2', correct: false },
{ text: '6', correct: false }
],
hint1: '原数个位是8,除以2后个位应该是什么?',
hint2: '8÷2=4,新数个位应该是4。观察原数十位。',
explanation: '原数个位是8,8÷2=4。新数4bcde4的个位是4。观察原数abcde8,e在十位。新数e在十位也保持不变。通过对比可知e=8。验证:原数末两位是88,88÷2=44✓。'
}
]
};
},
mounted() {
console.log('2的整除特征完整版已加载!');
},
methods: {
switchPage(page) {
if (window.speechSynthesis) {
window.speechSynthesis.cancel();
}
const audio = document.getElementById('tts-audio');
if (audio) audio.pause();
this.currentPage = page;
// 切换到演示页时触发初始语音
if (page === 2) {
setTimeout(() => {
if (this.demoTab === 'direct') {
this.speakDirectStep();
} else {
this.speakTheoryStep();
}
}, 300);
}
},
switchDemoTab(tab) {
this.demoTab = tab;
if (tab === 'direct') {
this.directStep = 0;
this.$nextTick(() => {
this.initDirectAnimation();
this.speakDirectStep();
});
} else {
this.theoryStep = 0;
this.$nextTick(() => {
this.initTheoryAnimation();
this.speakTheoryStep();
});
}
},
toggleQuestion(num) {
this.expandedQ = this.expandedQ === num ? null : num;
},
speak(text) {
if (window.speechSynthesis) window.speechSynthesis.cancel();
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 themePath = 'https://www.xinghuo.tv/wp-content/themes/xinghuo-tv';
const url = `${themePath}/tts.php?text=${encodeURIComponent(text)}&t=${Date.now()}`;
audio.src = url;
audio.play().catch(error => {
console.error("Audio playback failed:", error);
});
} else {
if (window.speechSynthesis) {
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = 'zh-CN';
utterance.rate = 0.9;
window.speechSynthesis.speak(utterance);
}
}
},
speakIntro() {
this.speak('小明的妈妈买了一袋糖果,想要平均分给小明和妹妹两个人。我们使用打包魔法,把糖果每10个装进一个盒子里。');
},
// ========== 直接判断动画 ==========
initDirectAnimation() {
if (typeof gsap === 'undefined') return;
gsap.set("#direct-number-group", {opacity: 1});
gsap.set("#direct-split-group", {opacity: 0});
gsap.set("#direct-judge-group", {opacity: 0});
gsap.set("#direct-result-group", {opacity: 0});
},
nextDirectStep() {
if (this.directStep < 3) {
this.directStep++;
this.$nextTick(() => {
this.runDirectAnimation();
this.speakDirectStep();
});
}
},
prevDirectStep() {
if (this.directStep > 0) {
this.directStep--;
this.$nextTick(() => {
this.runDirectAnimation();
this.speakDirectStep();
});
}
},
speakDirectStep() {
const texts = [
'让我们来判断358这个数能不能被2整除',
'第一步,把数字拆开,重点关注个位!个位是8',
'第二步,判断个位8是偶数还是奇数。8是偶数',
'因为个位是偶数,所以358能被2整除!验算:358除以2等于179'
];
this.speak(texts[this.directStep]);
},
runDirectAnimation() {
if (typeof gsap === 'undefined') return;
const tl = gsap.timeline();
if (this.directStep === 0) {
tl.to("#direct-number-group", {opacity: 1, duration: 0.3})
.to("#direct-split-group", {opacity: 0, duration: 0.2}, "<")
.to("#direct-judge-group", {opacity: 0, duration: 0.2}, "<")
.to("#direct-result-group", {opacity: 0, duration: 0.2}, "<");
}
if (this.directStep === 1) {
tl.to("#direct-number-group", {opacity: 0, y: -20, duration: 0.4})
.to("#direct-split-group", {opacity: 1, duration: 0.5})
.from("#direct-split-group rect", {
scale: 0,
stagger: 0.15,
ease: "back.out(1.7)",
duration: 0.6
}, "<0.2")
.to("#direct-ones-box", {
scale: 1.1,
duration: 0.3,
yoyo: true,
repeat: 1
});
}
if (this.directStep === 2) {
tl.to("#direct-judge-group", {opacity: 1, duration: 0.5})
.from("#direct-judge-group", {y: 20, duration: 0.5}, "<")
.to("#direct-ones-box", {
fill: "#d1fae5",
stroke: "#10b981",
duration: 0.4
})
.to("#direct-ones-digit", {
fill: "#10b981",
scale: 1.2,
duration: 0.3,
yoyo: true,
repeat: 1
}, "<");
}
if (this.directStep === 3) {
tl.to("#direct-result-group", {opacity: 1, scale: 1, duration: 0.5})
.from("#direct-result-group circle", {
scale: 0,
rotation: 360,
ease: "back.out(2)",
duration: 0.8
}, "<");
if (typeof confetti !== 'undefined') {
setTimeout(() => {
confetti({
particleCount: 80,
spread: 60,
origin: { y: 0.6 }
});
}, 400);
}
}
},
// ========== 位值原理动画 ==========
initTheoryAnimation() {
if (typeof gsap === 'undefined') return;
gsap.set("#theory-number-group", {opacity: 1});
gsap.set("#theory-split-group", {opacity: 0});
gsap.set("#theory-tens-group", {opacity: 0});
gsap.set("#theory-ones-group", {opacity: 0});
},
nextTheoryStep() {
if (this.theoryStep < 3) {
this.theoryStep++;
this.$nextTick(() => {
this.runTheoryAnimation();
this.speakTheoryStep();
});
}
},
prevTheoryStep() {
if (this.theoryStep > 0) {
this.theoryStep--;
this.$nextTick(() => {
this.runTheoryAnimation();
this.speakTheoryStep();
});
}
},
speakTheoryStep() {
const texts = [
'让我们探索为什么只看个位就够了。来看1234这个数',
'第一步,把数字拆成整十部分和个位。1234等于1230加4',
'关键来了!因为10能被2整除,所以整十部分1230肯定能被2整除',
'只要个位4也能被2整除,整个数就能被2整除!所以1234能被2整除'
];
this.speak(texts[this.theoryStep]);
},
runTheoryAnimation() {
if (typeof gsap === 'undefined') return;
const tl = gsap.timeline();
if (this.theoryStep === 0) {
tl.to("#theory-number-group", {opacity: 1, duration: 0.3})
.to("#theory-split-group", {opacity: 0, duration: 0.2}, "<")
.to("#theory-tens-group", {opacity: 0, duration: 0.2}, "<")
.to("#theory-ones-group", {opacity: 0, duration: 0.2}, "<");
}
if (this.theoryStep === 1) {
tl.to("#theory-number-group", {opacity: 0, y: -30, duration: 0.4})
.to("#theory-split-group", {opacity: 1, duration: 0.5})
.from("#theory-split-group rect", {
scale: 0,
y: 50,
stagger: 0.2,
ease: "back.out(1.5)",
duration: 0.7
}, "<0.2");
}
if (this.theoryStep === 2) {
tl.to("#theory-tens-group", {opacity: 1, duration: 0.5})
.from("#theory-tens-group rect", {
scale: 0,
rotation: -10,
ease: "elastic.out(1, 0.5)",
duration: 0.8
}, "<0.2")
.to("#theory-split-group rect:first-child", {
fill: "#d1fae5",
stroke: "#10b981",
duration: 0.4
});
}
if (this.theoryStep === 3) {
tl.to("#theory-ones-group", {opacity: 1, duration: 0.5})
.from("#theory-ones-group rect", {
scale: 0,
x: -30,
stagger: 0.15,
ease: "back.out(1.5)",
duration: 0.6
}, "<0.2");
if (typeof confetti !== 'undefined') {
setTimeout(() => {
confetti({
particleCount: 100,
spread: 70,
origin: { y: 0.6 }
});
}, 500);
}
}
},
// ========== 练习题逻辑 ==========
selectOption(index, correct) {
if (this.answered) return;
this.answered = true;
this.isCorrect = correct;
this.selectedOption = index;
if (correct) {
this.score += 20;
if (typeof confetti !== 'undefined') {
confetti({
particleCount: 100,
spread: 70,
origin: { y: 0.6 }
});
}
} else {
if (typeof gsap !== 'undefined') {
const wrongBtn = document.querySelector('.option-btn.wrong');
if (wrongBtn) {
gsap.to(wrongBtn, {
x: [-5, 5, -5, 5, 0],
duration: 0.5
});
}
}
}
},
nextQuestion() {
if (this.currentQuestion < this.practiceQuestions.length - 1) {
this.currentQuestion++;
this.answered = false;
this.isCorrect = 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;
if (this.wrongAttempts === 0) {
this.olympiadScore += 15;
} else if (this.wrongAttempts === 1) {
this.olympiadScore += 10;
} else {
this.olympiadScore += 5;
}
if (typeof confetti !== 'undefined') {
confetti({
particleCount: 150,
spread: 80,
origin: { y: 0.6 }
});
}
} else {
this.wrongAttempts++;
if (typeof gsap !== 'undefined') {
setTimeout(() => {
const wrongBtn = document.querySelector('.option-btn.wrong');
if (wrongBtn) {
gsap.to(wrongBtn, {
x: [-5, 5, -5, 5, 0],
duration: 0.5
});
}
}, 50);
}
if (this.wrongAttempts >= 3) {
this.olympiadAnswered = true;
this.isOlympiadCorrect = false;
}
setTimeout(() => {
this.selectedOlympiadOption = null;
}, 500);
}
},
nextOlympiad() {
if (this.currentOlympiad < this.olympiadQuestions.length - 1) {
this.currentOlympiad++;
this.olympiadAnswered = false;
this.isOlympiadCorrect = false;
this.selectedOlympiadOption = null;
this.wrongAttempts = 0;
} else {
this.olympiadCompleted = true;
}
}
}
}).mount('#app');
</script>
</body>
</html>
💡 这段代码完全由 gemini 生成。
登录后可复制完整代码