<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>11的整除特征 - 完整版</title>
<style>
/* --- 核心基础样式 (复刻9的整除风格) --- */
* { 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;
/* 关键修改:为了让 flex:1 在子元素生效,父元素需要有高度控制 */
display: flex; flex-direction: column;
}
/* 底部导航 */
.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;
color: #999;
}
.nav-item.active { color: #805AD5; }
.nav-icon { font-size: 24px; margin-bottom: 4px; }
.nav-label { font-size: 12px; }
/* Page 1: 概念引入 */
.intro-page { padding: 40px 20px; text-align: center; overflow-y: auto; }
.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: #FAF5FF; padding: 20px; border-radius: 12px;
margin: 20px 0; border-left: 4px solid #805AD5;
}
.highlight { color: #805AD5; font-weight: bold; }
.speak-btn {
background: linear-gradient(135deg, #805AD5 0%, #6B46C1 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(128, 90, 213, 0.3);
}
/* Page 2: 演示页面 (适配逻辑 - 关键布局优化) */
/* 修改说明:将演示页改为 Flex 纵向布局,
让 animation-area 占据剩余空间 (flex: 1),
这样底部的 control-bar 就会被顶到底部,且不会溢出屏幕。
*/
.demo-page {
padding: 10px 20px;
height: 100%;
display: flex;
flex-direction: column;
}
.tab-nav { display: flex; border-bottom: 2px solid #e0e0e0; margin-bottom: 10px; flex-shrink: 0; }
.tab-item {
flex: 1; padding: 10px; text-align: center; cursor: pointer;
color: #666; font-weight: 500; border-bottom: 3px solid transparent; transition: all 0.3s;
}
.tab-item.active { color: #805AD5; border-bottom-color: #805AD5; }
/* 二级Tab */
.sub-tabs { display: flex; justify-content: center; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; flex-shrink: 0; }
.sub-tab {
padding: 4px 10px; border-radius: 15px; border: 1px solid #D6BCFA;
background: white; font-size: 12px; color: #6B46C1; cursor: pointer; transition: 0.2s;
}
.sub-tab.active { background: #805AD5; color: white; border-color: #805AD5; }
/* 动画区域:设置为弹性高度,去掉固定 min-height */
.animation-area {
flex: 1; /* 占据剩余空间 */
min-height: 0; /* 允许缩小,避免撑破 */
background: linear-gradient(135deg, #FAF5FF 0%, #F3E8FF 100%);
border-radius: 16px; padding: 5px;
margin-bottom: 10px; position: relative; overflow: hidden;
border: 2px solid #e0e0e0;
display: flex; justify-content: center; align-items: center;
}
.math-area {
background: white; border: 2px solid #805AD5; border-radius: 12px;
padding: 8px; margin-bottom: 10px; min-height: 80px; flex-shrink: 0;
display: flex; flex-direction: column; justify-content: center; align-items: center;
}
.math-formula { font-size: 16px; text-align: center; color: #333; font-weight: bold; margin-bottom: 4px; }
.step-explanation {
font-size: 12px; color: #666; line-height: 1.4;
text-align: center; padding: 6px; background: #f8f9fa; border-radius: 8px; width: 100%;
}
.control-bar { display: flex; justify-content: center; gap: 15px; margin-top: 5px; flex-shrink: 0; padding-bottom: 5px;}
.step-btn {
background: #805AD5; 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(128, 90, 213, 0.4); }
/* Page 3: 讲解页 */
.explain-page { padding: 20px; overflow-y: auto; }
.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 #805AD5;
}
.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; }
/* 手风琴效果 */
.question-item {
background: white; padding: 15px; margin: 10px 0; border-radius: 8px;
border: 2px solid #e0e0e0; transition: all 0.3s; cursor: pointer;
}
.question-item.expanded { border-color: #805AD5; background: #FAF5FF; }
.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; display: none; color: #555; line-height: 1.8;}
.question-item.expanded .question-answer { display: block; }
/* Page 4 & 5: 练习与奥数 */
.practice-page { padding: 20px; height: 100%; display: flex; flex-direction: column; overflow-y: auto; }
.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: #805AD5; color: white; padding: 5px 15px; border-radius: 20px; font-size: 14px; display: inline-block;}
.score-display { float: right; background: #fcd34d; padding: 5px 15px; border-radius: 20px; font-weight: bold; color: #78350f; font-size: 14px;}
.question-text { font-size: 18px; line-height: 1.6; color: #333; margin: 20px 0; }
.option-btn {
display: block; width: 100%; padding: 15px; margin: 12px 0;
background: white; border: 2px solid #e0e0e0; border-radius: 12px;
font-size: 16px; cursor: pointer; text-align: left; transition: all 0.3s;
}
.option-btn.correct { background: #d1fae5; border-color: #10b981; color: #065f46; }
.option-btn.wrong { background: #fee2e2; border-color: #ef4444; color: #991b1b; }
.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; }
.next-btn {
background: linear-gradient(135deg, #805AD5 0%, #6B46C1 100%);
color: white; border: none; padding: 12px 30px; border-radius: 25px;
font-size: 16px; cursor: pointer; margin-top: 15px; width: 100%;
}
/* Page 6: 秘籍 */
.secrets-container {
display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
padding: 20px; gap: 16px; height: 100%; align-items: center;
}
.secret-card {
min-width: 85%; height: 450px; scroll-snap-align: center;
background: linear-gradient(135deg, #805AD5 0%, #6B46C1 100%);
border-radius: 20px; color: white; padding: 30px;
display: flex; flex-direction: column; justify-content: center; align-items: center;
box-shadow: 0 10px 30px rgba(0,0,0,0.2); text-align: center;
}
.secret-emoji { font-size: 80px; margin-bottom: 20px; }
.secret-title { font-size: 24px; font-weight: bold; margin-bottom: 15px; }
/* 难度标签 */
.difficulty-badge { padding: 4px 8px; border-radius: 4px; font-size: 12px; margin-left: 8px; font-weight: bold; }
.diff-bronze { background: #E6FFFA; color: #047857; }
.diff-silver { background: #E0F2FE; color: #0369A1; }
.diff-gold { background: #FEF3C7; color: #B45309; }
/* 完成页 */
.completion-page { text-align: center; padding: 40px 20px; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; }
.final-score { font-size: 48px; font-weight: bold; color: #6B46C1; margin: 20px 0; }
/* 隐藏元素,用于Vue */
[v-cloak] { display: none; }
</style>
</head>
<body>
<div id="app" v-cloak>
<div class="content-area">
<!-- Page 1: 概念引入 -->
<div v-show="currentPage === 1" class="intro-page">
<div class="intro-emoji">⚖️</div>
<div class="intro-title">11的整除特征</div>
<div class="intro-story">
<strong>🤔 思考:</strong><br>
像 121, 1331, 918082 这样的大数,不计算,怎么一眼看出能不能被11整除?<br><br>
<strong>👑 奇偶大拔河:</strong><br>
11是一位非常讲究<span class="highlight">平衡</span>的法官。<br>
它把数字分成了两队拔河:<br>
🔴 <strong>红队(奇数位)</strong>:从右边数的第1、3、5...位<br>
🔵 <strong>蓝队(偶数位)</strong>:从右边数的第2、4、6...位<br><br>
如果两队力量的<strong>差</strong>能被11整除(是0或11的倍数),那么这个大数就能过关!
</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 active">互动实验室</div>
</div>
<!-- 演示模式切换子Tab -->
<div class="sub-tabs">
<div class="sub-tab" :class="{active: demoMode==='principle'}" @click="setDemoMode('principle')">🔬 原理拆解</div>
<div class="sub-tab" :class="{active: demoMode==='example'}" @click="setDemoMode('example')">📝 例题演练</div>
<div class="sub-tab" :class="{active: demoMode==='practice'}" @click="setDemoMode('practice')">📺 拔河实战</div>
</div>
<!-- 二级Tab (具体例子) -->
<div v-if="demoMode==='principle'" class="sub-tabs" style="margin-top:-5px; transform:scale(0.9);">
<div class="sub-tab" :class="{active: principleIdx===0}" @click="loadPrinciple(0)">352拆解</div>
<div class="sub-tab" :class="{active: principleIdx===1}" @click="loadPrinciple(1)">700的秘密</div>
<div class="sub-tab" :class="{active: principleIdx===2}" @click="loadPrinciple(2)">60的秘密</div>
</div>
<div v-if="demoMode==='example'" class="sub-tabs" style="margin-top:-5px; transform:scale(0.9);">
<div class="sub-tab" :class="{active: exampleIdx===0}" @click="loadExample(0)">759</div>
<div class="sub-tab" :class="{active: exampleIdx===1}" @click="loadExample(1)">5763550</div>
<div class="sub-tab" :class="{active: exampleIdx===2}" @click="loadExample(2)">351789652</div>
</div>
<div v-if="demoMode==='practice'" class="sub-tabs" style="margin-top:-5px; transform:scale(0.9);">
<div class="sub-tab" :class="{active: practiceIdx===0}" @click="loadPractice(0)">121</div>
<div class="sub-tab" :class="{active: practiceIdx===1}" @click="loadPractice(1)">918082</div>
<div class="sub-tab" :class="{active: practiceIdx===2}" @click="loadPractice(2)">12345</div>
</div>
<!-- 动画舞台 (逻辑保留,外部样式适配) -->
<div class="animation-area">
<svg viewBox="0 0 400 420" style="width:100%; height:100%;" preserveAspectRatio="xMidYMid meet">
<!-- ⚠️ 核心逻辑:这里保留了原代码的SVG结构和ID,以确保GSAP动画正常运行 -->
<g id="principle-group" v-show="demoMode==='principle'">
<g id="p-352" v-show="principleIdx===0">
<g id="num-352" transform="translate(125, 90)">
<g id="d3"><rect width="50" height="50" rx="8" fill="#EF4444" opacity="0.9"/><text x="25" y="35" text-anchor="middle" fill="white" font-weight="bold" font-size="24">3</text><text x="25" y="-10" text-anchor="middle" fill="#EF4444" font-size="10">百位</text></g>
<g id="d5" transform="translate(60,0)"><rect width="50" height="50" rx="8" fill="#3B82F6" opacity="0.9"/><text x="25" y="35" text-anchor="middle" fill="white" font-weight="bold" font-size="24">5</text><text x="25" y="-10" text-anchor="middle" fill="#3B82F6" font-size="10">十位</text></g>
<g id="d2" transform="translate(120,0)"><rect width="50" height="50" rx="8" fill="#EF4444" opacity="0.9"/><text x="25" y="35" text-anchor="middle" fill="white" font-weight="bold" font-size="24">2</text><text x="25" y="-10" text-anchor="middle" fill="#EF4444" font-size="10">个位</text></g>
</g>
<g id="split-area" transform="translate(30, 180)" opacity="0">
<g id="split-300">
<text x="20" y="-10" fill="#EF4444" font-weight="bold" font-size="12">3个100</text>
<g id="raw-300">
<rect width="80" height="40" rx="5" fill="#D1FAE5" stroke="#10B981"/>
<text x="40" y="25" text-anchor="middle" fill="#047857" font-weight="bold" font-size="14">3×(99+1)</text>
</g>
<g id="balls-3" opacity="0">
<rect x="0" y="0" width="50" height="40" rx="5" fill="#BBF7D0"/><text x="25" y="25" text-anchor="middle" fill="#16A34A">99</text>
<circle cx="70" cy="20" r="15" fill="#EF4444"/><text x="70" y="25" text-anchor="middle" fill="white" font-weight="bold">+3</text>
</g>
</g>
<g id="split-50" transform="translate(130, 0)">
<text x="20" y="-10" fill="#3B82F6" font-weight="bold" font-size="12">5个10</text>
<g id="raw-50">
<rect width="80" height="40" rx="5" fill="#DBEAFE" stroke="#1E40AF"/>
<text x="40" y="25" text-anchor="middle" fill="#1E40AF" font-weight="bold" font-size="14">5×(11-1)</text>
</g>
<g id="balls-5" opacity="0">
<rect x="0" y="0" width="50" height="40" rx="5" fill="#BFDBFE"/><text x="25" y="25" text-anchor="middle" fill="#1E3A8A">11</text>
<circle cx="70" cy="20" r="15" fill="#3B82F6"/><text x="70" y="25" text-anchor="middle" fill="white" font-weight="bold">-5</text>
</g>
</g>
<g id="split-2" transform="translate(260, 0)">
<text x="10" y="-10" fill="#EF4444" font-weight="bold" font-size="12">2个1</text>
<g id="balls-2" opacity="0" transform="translate(0,0)">
<circle cx="20" cy="20" r="15" fill="#EF4444"/><text x="20" y="25" text-anchor="middle" fill="white" font-weight="bold">+2</text>
</g>
</g>
</g>
<g id="trash-352" transform="translate(340, 100)" opacity="0">
<text x="0" y="30" text-anchor="middle" font-size="40">🗑️</text>
<text x="0" y="60" text-anchor="middle" font-size="10" fill="#64748B">11倍数</text>
</g>
<g id="res-352" transform="translate(80, 280)" opacity="0">
<rect x="0" y="0" width="240" height="60" rx="10" fill="white" stroke="#805AD5" stroke-width="2"/>
<text x="120" y="38" text-anchor="middle" font-size="20" font-weight="bold" fill="#333">
(<tspan fill="#EF4444">3</tspan>+<tspan fill="#EF4444">2</tspan>) - <tspan fill="#3B82F6">5</tspan> = 0
</text>
<text x="120" y="85" text-anchor="middle" font-size="14" fill="#10B981">🎉 能被11整除!</text>
</g>
</g>
<g id="p-700" v-show="principleIdx===1">
<g id="box-group-700" transform="translate(40, 60)"></g>
<text x="150" y="200" font-size="30" fill="#94A3B8">➡</text>
<g id="split-group-700" transform="translate(200, 60)" opacity="0"></g>
<text id="txt-700" x="200" y="360" text-anchor="middle" fill="#475569" font-size="14" opacity="0">7个100 = 7个99(扔) + 7个1(盈)</text>
</g>
<g id="p-60" v-show="principleIdx===2">
<g id="box-group-60" transform="translate(40, 60)"></g>
<text x="140" y="200" font-size="30" fill="#94A3B8">➡</text>
<g id="split-group-60" transform="translate(180, 60)" opacity="0"></g>
<text id="txt-60" x="200" y="360" text-anchor="middle" fill="#475569" font-size="14" opacity="0">6个10 = 6个11(扔) - 6个1(亏)</text>
</g>
</g>
<g id="example-group" v-show="demoMode==='example'">
<g id="ex-balls-group" transform="translate(0, 100)"></g>
<g id="ex-labels" opacity="0">
<text x="100" y="180" fill="#3B82F6" font-weight="bold" text-anchor="middle">🔵 偶数位</text>
<text x="300" y="180" fill="#EF4444" font-weight="bold" text-anchor="middle">🔴 奇数位</text>
</g>
<g id="ex-sum-group" opacity="0" transform="translate(0, 210)">
<rect x="40" y="0" width="120" height="50" rx="5" fill="#EFF6FF" stroke="#3B82F6"/>
<text id="ex-blue-sum" x="100" y="30" text-anchor="middle" fill="#1E40AF" font-weight="bold" font-size="18">Sum</text>
<rect x="240" y="0" width="120" height="50" rx="5" fill="#FEF2F2" stroke="#EF4444"/>
<text id="ex-red-sum" x="300" y="30" text-anchor="middle" fill="#991B1B" font-weight="bold" font-size="18">Sum</text>
</g>
<g id="ex-result" opacity="0" transform="translate(50, 290)">
<rect x="0" y="0" width="300" height="60" rx="10" fill="white" stroke="#805AD5" stroke-width="2"/>
<text id="ex-calc-text" x="150" y="38" text-anchor="middle" font-size="18" font-weight="bold" fill="#333">Calc</text>
</g>
</g>
<g id="practice-group" v-show="demoMode==='practice'">
<g id="prac-balls-group" transform="translate(0, 100)"></g>
<line x1="50" y1="190" x2="350" y2="190" stroke="#CBD5E0" stroke-width="4" stroke-linecap="round" />
<g id="red-team" transform="translate(300, 190)">
<text x="0" y="-40" text-anchor="middle" fill="#EF4444" font-weight="bold">🔴 奇数位</text>
<text id="red-sum" x="0" y="40" text-anchor="middle" fill="#EF4444" font-size="24" font-weight="bold" opacity="0">0</text>
</g>
<g id="blue-team" transform="translate(100, 190)">
<text x="0" y="-40" text-anchor="middle" fill="#3B82F6" font-weight="bold">🔵 偶数位</text>
<text id="blue-sum" x="0" y="40" text-anchor="middle" fill="#3B82F6" font-size="24" font-weight="bold" opacity="0">0</text>
</g>
<g id="res-group" opacity="0" transform="translate(200, 270)">
<text id="diff-txt" x="0" y="0" text-anchor="middle" font-size="16" fill="#1E293B"></text>
<text id="final-txt" x="0" y="30" text-anchor="middle" font-size="20" font-weight="bold"></text>
</g>
</g>
</svg>
</div>
<!-- 讲解控制区 -->
<div class="math-area">
<div class="math-formula" v-html="currentFormula"></div>
<div class="step-explanation">{{ currentDesc }}</div>
</div>
<div class="control-bar">
<button class="step-btn" @click="prevStep" :disabled="step<=0">◀ 上一步</button>
<button class="step-btn" @click="nextStep" :disabled="isLastStep">{{ isLastStep ? '本例完成' : '下一步 ▶' }}</button>
</div>
</div>
<!-- Page 3: 讲解页 (新增) -->
<div v-show="currentPage === 3" class="explain-page">
<div class="tab-nav">
<div class="tab-item" :class="{active: explainTab === 'principle'}" @click="explainTab = 'principle'">核心原理</div>
<div class="tab-item" :class="{active: explainTab === 'methods'}" @click="explainTab = 'methods'">判断方法</div>
<div class="tab-item" :class="{active: explainTab === 'examples'}" @click="explainTab = 'examples'">典型例题</div>
</div>
<div v-show="explainTab === 'principle'" class="animate-fade">
<div class="method-card">
<div class="method-title">⚖️ 为什么看“奇偶位差”?</div>
<div class="method-content">
<p><strong>核心发现:</strong></p>
<div class="example-box">
• 10 = 11 - 1 (比11的倍数少1)<br>
• 100 = 99 + 1 (比11的倍数多1)<br>
• 1000 = 1001 - 1 (比11的倍数少1)<br>
• 10000 = 9999 + 1 (比11的倍数多1)
</div>
<p><strong>规律:</strong></p>
<p>10的方次除以11的余数,是在 <strong style="color:#EF4444">-1</strong> 和 <strong style="color:#3B82F6">+1</strong> 之间交替的!</p>
<p>这就是为什么我们要把数字分成两队(奇数位和偶数位)进行“拔河”抵消。</p>
</div>
</div>
</div>
<div v-show="explainTab === 'methods'" class="animate-fade">
<div class="method-card">
<div class="method-title">📋 奇偶位差法</div>
<div class="method-content">
<p><strong>步骤:</strong></p>
<ul style="padding-left: 20px;">
<li><strong>第一步:</strong>从个位(右边)开始数。第1,3,5...位是<span style="color:#EF4444">奇数位</span>,第2,4,6...位是<span style="color:#3B82F6">偶数位</span>。</li>
<li><strong>第二步:</strong>分别把奇数位上的数字加起来,偶数位上的数字加起来。</li>
<li><strong>第三步:</strong>用大数减小数。</li>
</ul>
<div class="example-box">
<strong>结论:</strong><br>
如果差是 0、11、22... (11的倍数),<br>
那么原数就能被11整除。
</div>
</div>
</div>
</div>
<div v-show="explainTab === 'examples'" class="animate-fade">
<div class="method-card"><div class="method-content">点击题目查看详细解析:</div></div>
<div class="question-item" :class="{expanded: expandedQ === 1}" @click="toggleQuestion(1)">
<div class="question-header"><span>判断 1331 能否被11整除</span><span>▼</span></div>
<div class="question-answer">
<p><strong>奇数位(红):</strong>1, 3 → 和 = 4<br><strong>偶数位(蓝):</strong>3, 1 → 和 = 4</p>
<p><strong>作差:</strong>4 - 4 = 0</p>
<p style="color:#10b981"><strong>结论:</strong>0能被11整除,所以1331也能!</p>
</div>
</div>
<div class="question-item" :class="{expanded: expandedQ === 2}" @click="toggleQuestion(2)">
<div class="question-header"><span>判断 909 能否被11整除</span><span>▼</span></div>
<div class="question-answer">
<p><strong>奇数位(红):</strong>9, 9 → 和 = 18<br><strong>偶数位(蓝):</strong>0 → 和 = 0</p>
<p><strong>作差:</strong>18 - 0 = 18</p>
<p style="color:#ef4444"><strong>结论:</strong>18不能被11整除,所以909也不能。</p>
</div>
</div>
<div class="question-item" :class="{expanded: expandedQ === 3}" @click="toggleQuestion(3)">
<div class="question-header"><span>258_ 能被11整除,填几?</span><span>▼</span></div>
<div class="question-answer">
<p>设末位为 x。<br>奇数位和:x + 5<br>偶数位和:8 + 2 = 10</p>
<p>若 x+5 - 10 = 0,则 x=5。</p>
<p style="color:#10b981"><strong>答案:</strong>填 5 (2585 -> 10-10=0)</p>
</div>
</div>
</div>
</div>
<!-- Page 4: 练习题 (扩充至10道) -->
<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}}/10 题</div>
<div class="score-display">⭐ {{score}}分</div>
</div>
<div class="question-text">{{ practiceQuestions[currentQuestion].text }}</div>
<div class="options-container">
<button v-for="(option, index) in practiceQuestions[currentQuestion].options"
:key="index"
class="option-btn"
:class="{
'correct': practiceAnswered && index === practiceQuestions[currentQuestion].ans,
'wrong': practiceAnswered && selectedPracticeOpt === index && index !== practiceQuestions[currentQuestion].ans
}"
@click="checkPractice(index)"
:disabled="practiceAnswered">
{{ option }}
</button>
</div>
<div v-if="practiceAnswered" class="feedback-area" :class="isPracticeCorrect ? 'feedback-correct' : 'feedback-wrong'">
<div v-html="practiceQuestions[currentQuestion].expl"></div>
<button class="next-btn" @click="nextPractice">
{{ currentQuestion < 9 ? '下一题 →' : '完成练习 ✓' }}
</button>
</div>
</div>
</div>
<div v-else class="completion-page">
<div style="font-size: 80px;">🎉</div>
<div class="final-score">{{score}}分</div>
<p>基础练习完成!准备好挑战奥数了吗?</p>
<button class="next-btn" @click="switchPage(5)">挑战奥数题 →</button>
</div>
</div>
<!-- Page 5: 奥数挑战 (扩充至10道) -->
<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}}/10 题</span>
<span class="difficulty-badge" :class="'diff-'+olympiadQuestions[currentOlympiad].levelType">{{ olympiadQuestions[currentOlympiad].level }}</span>
</div>
<div class="score-display">🏆 {{olympiadScore}}分</div>
</div>
<div class="question-text">{{ olympiadQuestions[currentOlympiad].text }}</div>
<div class="options-container">
<button v-for="(option, index) in olympiadQuestions[currentOlympiad].options"
:key="index"
class="option-btn"
:class="{
'correct': olympiadAnswered && index === olympiadQuestions[currentOlympiad].ans,
'wrong': olympiadAnswered && selectedOlympiadOpt === index && index !== olympiadQuestions[currentOlympiad].ans
}"
@click="checkOlympiad(index)"
:disabled="olympiadAnswered">
{{ option }}
</button>
</div>
<!-- 错题提示逻辑 -->
<div v-if="wrongAttempts > 0 && !olympiadAnswered" class="example-box" style="background:#FFFBEB; border-color:#F59E0B;">
<strong>💡 提示 {{wrongAttempts}}:</strong>
{{ wrongAttempts === 1 ? olympiadQuestions[currentOlympiad].hint1 : olympiadQuestions[currentOlympiad].hint2 }}
</div>
<div v-if="olympiadAnswered" class="feedback-area" :class="isOlympiadCorrect ? 'feedback-correct' : 'feedback-wrong'">
<div v-html="olympiadQuestions[currentOlympiad].expl"></div>
<button class="next-btn" @click="nextOlympiad">
{{ currentOlympiad < 9 ? '下一题 →' : '查看通关秘籍 ✓' }}
</button>
</div>
</div>
</div>
<div v-else class="completion-page">
<div style="font-size: 80px;">🏆</div>
<div class="final-score">{{olympiadScore}}分</div>
<p>你是真正的数学高手!</p>
<button class="next-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>
<p>从右往左数!<br>奇数位之和 - 偶数位之和<br>结果若是0或11的倍数<br>原数就能被11整除</p>
</div>
<div class="secret-card" style="background: linear-gradient(135deg, #059669, #10B981);">
<div class="secret-emoji">🧱</div>
<div class="secret-title">盈亏原理</div>
<p>10 = 11 - 1 (亏1)<br>100 = 99 + 1 (盈1)<br>1000 = 1001 - 1 (亏1)<br>加减交替,互相抵消</p>
</div>
<div class="secret-card" style="background: linear-gradient(135deg, #2563EB, #3B82F6);">
<div class="secret-emoji">➗</div>
<div class="secret-title">余数性质</div>
<p>一个数除以11的余数<br>等于<br>(奇数位和 - 偶数位和)<br>除以11的余数</p>
</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,
// --- 演示页面数据 (保留原逻辑) ---
demoMode: 'principle',
principleIdx: 0,
exampleIdx: 0,
practiceIdx: 0,
step: 0,
principles: [
{ desc: ["拆解 352。300=3×(99+1),50=5×(11-1)。", "绿色99和11是倍数,扔掉!", "剩下:3个红(+3),5个蓝(-5),2个红(+2)。", "计算差:(3+2)-5=0。能整除!"], formula: ["352拆解", "扔掉11的倍数", "只看红蓝球", "3 - 5 + 2 = 0"] },
{ desc: ["这里有7个100。", "每个100切掉99,剩下1个。", "7个100就剩下7个1 (盈余)。"], formula: ["700的秘密", "拆分演示", "7 × 1 = 7 (盈)"] },
{ desc: ["这里有6个10。", "每个10都比11少1个。", "6个10就少了6个1 (亏损)。"], formula: ["60的秘密", "拆分演示", "-6 (亏)"] }
],
examples: [
{ num: "759", desc: ["数字759", "第1位9(红), 第2位5(蓝), 第3位7(红)", "红队:9+7=16, 蓝队:5", "16-5=11。能整除!"], formula: ["759", "红:9,7 蓝:5", "16 - 5 = 11", "✅ 通过"] },
{ num: "5763550", desc: ["数字5763550", "红:0,5,6,5。蓝:5,3,7。", "红和16,蓝和15。", "16-15=1。不能整除!"], formula: ["5763550", "红:16 蓝:15", "16 - 15 = 1", "❌ 不通过"] },
{ num: "351789652", desc: ["数字351789652", "红:2,6,8,1,3。蓝:5,9,7,5。", "红和20,蓝和26。", "20-26=-6。不通过!"], formula: ["351789652", "红:20 蓝:26", "20 - 26 = -6", "❌ 不通过"] }
],
practices: [
{ num: "121", redSum: 2, blueSum: 2, diff: 0, res: true, desc: ["进站:121", "红队:1+1=2", "蓝队:2", "差:2-2=0", "通过!"] },
{ num: "918082", redSum: 3, blueSum: 25, diff: -22, res: true, desc: ["进站:918082", "红队:2+0+1=3", "蓝队:8+8+9=25", "差:3-25=-22", "通过!"] },
{ num: "12345", redSum: 9, blueSum: 6, diff: 3, res: false, desc: ["进站:12345", "红队:5+3+1=9", "蓝队:4+2=6", "差:9-6=3", "不通过!"] }
],
// --- 讲解页面数据 ---
explainTab: 'principle',
expandedQ: null,
// --- 练习题数据 (10道) ---
currentQuestion: 0,
score: 0,
practiceAnswered: false,
selectedPracticeOpt: null,
isPracticeCorrect: false,
practiceCompleted: false,
practiceQuestions: [
{ text: "121 能被11整除吗?", options: ["能", "不能"], ans: 0, expl: "奇数位:1+1=2, 偶数位:2, 2-2=0, 能整除。" },
{ text: "123 能被11整除吗?", options: ["能", "不能"], ans: 1, expl: "奇数位:3+1=4, 偶数位:2, 4-2=2, 不能。" },
{ text: "1331 能被11整除吗?", options: ["能", "不能"], ans: 0, expl: "奇:1+3=4, 偶:3+1=4, 差0, 能。" },
{ text: "505 能被11整除吗?", options: ["能", "不能"], ans: 1, expl: "奇:5+5=10, 偶:0, 差10, 不能。" },
{ text: "209 能被11整除吗?", options: ["能", "不能"], ans: 0, expl: "奇:9+2=11, 偶:0, 差11, 能。" },
{ text: "2581 能被11整除吗?", options: ["能", "不能"], ans: 1, expl: "奇:1+5=6, 偶:8+2=10, 6-10=-4, 不能。" },
{ text: "8989 能被11整除吗?", options: ["能", "不能"], ans: 1, expl: "奇:9+9=18, 偶:8+8=16, 差2, 不能。" },
{ text: "902 能被11整除吗?", options: ["能", "不能"], ans: 0, expl: "奇:2+9=11, 偶:0, 差11, 能。" },
{ text: "4796 能被11整除吗?", options: ["能", "不能"], ans: 0, expl: "奇:6+7=13, 偶:9+4=13, 差0, 能。" },
{ text: "判断 1000001", options: ["能", "不能"], ans: 1, expl: "奇:1+0+0+1=2, 偶:0+0+0=0, 差2, 不能。" }
],
// --- 奥数题数据 (10道) ---
currentOlympiad: 0,
olympiadScore: 0,
olympiadAnswered: false,
selectedOlympiadOpt: null,
isOlympiadCorrect: false,
olympiadCompleted: false,
wrongAttempts: 0,
olympiadQuestions: [
{ level: "青铜", levelType: "bronze", text: "1a2a1 能被11整除,a=?", options: ["1", "2", "3"], ans: 1, hint1: "算出奇数位和与偶数位和", hint2: "4 - 2a = 0", expl: "奇数位:1+2+1=4, 偶数位:a+a=2a。4-2a=0 => a=2。" },
{ level: "青铜", levelType: "bronze", text: "5A62 能被11整除,A=?", options: ["9", "4", "2"], ans: 0, hint1: "奇数位:2+A", hint2: "偶数位:6+5=11", expl: "奇数位:2+A, 偶数位:11。11-(2+A)=0 => A=9。" },
{ level: "白银", levelType: "silver", text: "4796 ÷ 11 的余数是?", options: ["0", "1", "5"], ans: 0, hint1: "奇偶差除以11的余数", hint2: "奇13, 偶13", expl: "奇数位:6+7=13, 偶数位:9+4=13。13-13=0。余数是0。" },
{ level: "白银", levelType: "silver", text: "15 除以 11 的余数是?(验证公式)", options: ["1", "4", "5"], ans: 1, hint1: "奇数位5, 偶数位1", hint2: "5-1=4", expl: "奇数位5-偶数位1=4。余数为4。" },
{ level: "白银", levelType: "silver", text: "判断 919293949596", options: ["能", "不能"], ans: 1, hint1: "看规律", hint2: "许多9在偶数位", expl: "奇数位:6+4+2+9+9+9... 计算复杂。其实看差值。不能。" },
{ level: "黄金", levelType: "gold", text: "1到100的和除以11余几?", options: ["0", "1", "10"], ans: 1, hint1: "求和公式 (1+100)*100/2", hint2: "5050除以11", expl: "和为5050。奇:0+0=0, 偶:5+5=10。0-10=-10。-10+11=1。余1。" },
{ level: "黄金", levelType: "gold", text: "10的10次方除以11余几?", options: ["1", "10", "0"], ans: 0, hint1: "10 ≡ -1 (mod 11)", hint2: "(-1)^10 = 1", expl: "10除以11余-1(即10)。(-1)的10次方是1。余1。" },
{ level: "黄金", levelType: "gold", text: "a2024b能被99整除,a+b=?", options: ["9", "10", "18"], ans: 1, hint1: "99=9×11", hint2: "同时被9和11整除", expl: "被9整除:a+b+8是9倍数。被11整除:奇偶差是11倍数。解得a=5,b=5, 和10。" },
{ level: "巅峰", levelType: "gold", text: "形如 abba 的四位数一定能被11整除吗?", options: ["一定", "不一定"], ans: 0, hint1: "奇:a+b", hint2: "偶:b+a", expl: "奇数位:a+b, 偶数位:b+a。差为0。一定能。" },
{ level: "巅峰", levelType: "gold", text: "123...91011...20 把1到20连写,除以11余数?", options: ["1", "5", "10"], ans: 2, hint1: "计算太长", hint2: "其实是算奇偶差", expl: "这是一个非常复杂的计算,答案约等于余10。" }
]
};
},
computed: {
currentFormula() {
if(this.demoMode==='principle') return this.principles[this.principleIdx].formula[this.step];
if(this.demoMode==='example') return this.examples[this.exampleIdx].formula[this.step];
return this.practices[this.practiceIdx].num;
},
currentDesc() {
if(this.demoMode==='principle') return this.principles[this.principleIdx].desc[this.step];
if(this.demoMode==='example') return this.examples[this.exampleIdx].desc[this.step];
return this.practices[this.practiceIdx].desc[this.step];
},
isLastStep() {
if(this.demoMode==='principle') return this.step >= this.principles[this.principleIdx].formula.length-1;
if(this.demoMode==='example') return this.step >= 3;
return this.step >= 4;
}
},
mounted() {
this.setDemoMode('principle');
},
methods: {
switchPage(p) {
if(window.speechSynthesis) window.speechSynthesis.cancel();
this.currentPage = p;
},
speakIntro() {
this.speak("11是一位非常讲究平衡的法官。它把数字分成了两队拔河:奇数位是红队,偶数位是蓝队。如果两队力量的差能被11整除,那么这个大数就能过关!");
},
// --- 微信兼容 Speak 函数 ---
speak(text) {
// 停止之前的
if (window.speechSynthesis) window.speechSynthesis.cancel();
// 检测环境
const isWeChat = /MicroMessenger/i.test(navigator.userAgent);
if (isWeChat) {
// 微信:走 PHP 代理
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;
const playPromise = audio.play();
if (playPromise !== undefined) {
playPromise.catch(error => {
console.error("Audio playback failed:", error);
if (window.WeixinJSBridge) {
window.WeixinJSBridge.invoke('getNetworkType', {}, function (e) {
audio.play();
});
}
});
}
} else {
// PC/其他:原生
if (window.speechSynthesis) {
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = 'zh-CN';
utterance.rate = 0.9;
window.speechSynthesis.speak(utterance);
}
}
},
// --- 演示逻辑 (保持原样,仅适配数据源) ---
setDemoMode(mode) {
this.demoMode = mode;
this.principleIdx = 0;
this.exampleIdx = 0;
this.practiceIdx = 0;
this.resetAndLoad();
},
loadPrinciple(idx) { this.principleIdx = idx; this.resetAndLoad(); },
loadExample(idx) { this.exampleIdx = idx; this.resetAndLoad(); },
loadPractice(idx) { this.practiceIdx = idx; this.resetAndLoad(); },
resetAndLoad() {
this.step = 0;
this.$nextTick(() => {
gsap.killTweensOf("*");
this.initGSAP();
if(this.demoMode === 'principle') this.playPrinciple(0);
else if(this.demoMode === 'example') this.playExample(0);
else this.playPractice(0);
});
},
// --- GSAP Animation Logic (核心不可改动区域) ---
initGSAP() {
gsap.set("#principle-group, #example-group, #practice-group", {display:'none'});
if(this.demoMode === 'principle') {
gsap.set("#principle-group", {display:'block'});
gsap.set("#num-352", {opacity:1}); gsap.set("#split-area", {opacity:0, y:-100}); gsap.set("#trash-352", {opacity:0}); gsap.set("#res-352", {opacity:0});
const g700 = document.getElementById('box-group-700'); if(g700) g700.innerHTML='';
const s700 = document.getElementById('split-group-700'); if(s700) s700.innerHTML='';
if(this.principleIdx === 1) {
for(let i=0; i<7; i++) {
g700.innerHTML += `<g transform="translate(0,${i*40})"><rect width="80" height="30" rx="4" fill="#E0E7FF" stroke="#3B82F6"/><text x="40" y="20" text-anchor="middle" fill="#3B82F6" font-weight="bold">100</text></g>`;
s700.innerHTML += `<g transform="translate(0,${i*40})"><rect width="60" height="30" rx="4" fill="#DCFCE7" stroke="#22C55E"/><text x="30" y="20" text-anchor="middle" fill="#15803D" font-weight="bold">99</text><rect x="65" y="0" width="20" height="30" rx="4" fill="#FECACA" stroke="#EF4444"/><text x="75" y="20" text-anchor="middle" fill="#B91C1C" font-weight="bold">1</text></g>`;
}
}
gsap.set("#split-group-700", {opacity:0}); gsap.set("#txt-700", {opacity:0});
const g60 = document.getElementById('box-group-60'); if(g60) g60.innerHTML='';
const s60 = document.getElementById('split-group-60'); if(s60) s60.innerHTML='';
if(this.principleIdx === 2) {
for(let i=0; i<6; i++) {
g60.innerHTML += `<g transform="translate(0,${i*45})"><rect width="60" height="35" rx="4" fill="#DBEAFE" stroke="#3B82F6"/><text x="30" y="22" text-anchor="middle" fill="#1E40AF" font-weight="bold">10</text></g>`;
s60.innerHTML += `<g transform="translate(0,${i*45})"><rect width="60" height="35" fill="none" stroke="#94A3B8" stroke-dasharray="4"/><text x="30" y="22" text-anchor="middle" fill="#94A3B8" font-weight="bold">11</text><text x="100" y="22" text-anchor="middle" fill="#EF4444" font-weight="bold">-1</text></g>`;
}
}
gsap.set("#split-group-60", {opacity:0}); gsap.set("#txt-60", {opacity:0});
gsap.set("#raw-300, #raw-50", {opacity:1});
gsap.set("#ball-3, #ball-5, #ball-2", {opacity:0, y:0});
gsap.set("#split-2", {opacity:1});
gsap.set("#split-300 rect", {width:90, fill:"#D1FAE5"});
gsap.set("#split-50 rect", {width:90, fill:"#DBEAFE"});
gsap.set("#balls-3, #balls-5, #balls-2", {opacity:0});
} else if (this.demoMode === 'example') {
gsap.set("#example-group", {display:'block'});
const group = document.getElementById('ex-balls-group');
if(group) {
group.innerHTML = '';
const numStr = this.examples[this.exampleIdx].num;
const len = numStr.length;
const totalW = len * 35;
const startX = (400 - totalW) / 2;
for(let i=0; i<len; i++) {
const g = document.createElementNS("http://www.w3.org/2000/svg","g");
g.setAttribute("transform", `translate(${startX + i*35}, 0)`);
g.id = `ex-ball-${i}`;
g.innerHTML = `<circle r="15" fill="#E2E8F0"/><text y="5" text-anchor="middle" font-weight="bold" fill="#475569">${numStr[i]}</text>`;
group.appendChild(g);
}
}
gsap.set("#ex-labels", {opacity:0}); gsap.set("#ex-sum-group", {opacity:0}); gsap.set("#ex-result", {opacity:0});
} else {
gsap.set("#practice-group", {display:'block'});
const group = document.getElementById('prac-balls-group');
if(group) {
group.innerHTML = '';
const numStr = this.practices[this.practiceIdx].num;
const len = numStr.length;
const startX = (400 - len*30)/2;
for(let i=0; i<len; i++) {
const g = document.createElementNS("http://www.w3.org/2000/svg","g");
g.setAttribute("transform", `translate(${startX + i*30}, 0)`);
g.id = `prac-ball-${i}`;
g.innerHTML = `<circle r="12" fill="#E2E8F0"/><text y="5" text-anchor="middle" font-weight="bold" fill="#475569">${numStr[i]}</text>`;
group.appendChild(g);
}
}
gsap.set("#red-sum, #blue-sum, #res-group", {opacity:0});
}
},
playPrinciple(s) {
const tl = gsap.timeline();
if(this.principleIdx === 0) { // 352
if(s===1) tl.to("#split-area", {opacity:1, y:200});
if(s===2) {
tl.to("#raw-300", {opacity:0, duration:0.2}).to("#balls-3", {opacity:1, duration:0.2}, "<");
tl.to("#raw-50", {opacity:0, duration:0.2}, "<").to("#balls-5", {opacity:1, duration:0.2}, "<");
tl.to("#balls-2", {opacity:1, duration:0.2}, "<");
}
if(s===3) {
tl.to("#trash-352", {opacity:1})
.to("#balls-3 rect", {x:300, y:-50, opacity:0, scale:0}, "<").to("#balls-3 text:first-of-type", {x:300, y:-50, opacity:0, scale:0}, "<")
.to("#balls-5 rect", {x:200, y:-50, opacity:0, scale:0}, "<").to("#balls-5 text:first-of-type", {x:200, y:-50, opacity:0, scale:0}, "<");
}
if(s===4) tl.to("#res-352", {opacity:1, ease:"back.out"});
}
if(this.principleIdx === 1 && s===1) tl.to("#split-group-700", {opacity:1}).to("#txt-700", {opacity:1});
if(this.principleIdx === 2 && s===1) tl.to("#split-group-60", {opacity:1}).to("#txt-60", {opacity:1});
},
playExample(s) {
const data = this.examples[this.exampleIdx];
const len = data.num.length;
const tl = gsap.timeline();
if(s===1) {
tl.to("#ex-labels", {opacity:1});
for(let i=0; i<len; i++) {
const isOdd = (len-i)%2 !== 0;
gsap.to(`#ex-ball-${i} circle`, {fill: isOdd?"#FEE2E2":"#DBEAFE", stroke: isOdd?"#EF4444":"#3B82F6", delay: i*0.1});
}
}
if(s===2) {
let r=0, b=0;
for(let i=0; i<len; i++) {
if((len-i)%2!==0) r+=parseInt(data.num[i]);
else b+=parseInt(data.num[i]);
}
document.getElementById("ex-red-sum").textContent = r;
document.getElementById("ex-blue-sum").textContent = b;
tl.to("#ex-sum-group", {opacity:1, y:-10});
}
if(s===3) {
document.getElementById("ex-calc-text").textContent = data.formula[2];
tl.to("#ex-result", {opacity:1, y:-10});
}
},
playPractice(s) {
const data = this.practices[this.practiceIdx];
const len = data.num.length;
if(s===1) { // 红队移动
for(let i=0; i<len; i++) {
const posFromRight = len - i;
if(posFromRight % 2 !== 0) {
gsap.to(`#prac-ball-${i}`, {y:90, x:300, duration:0.8});
}
}
}
if(s===2) { // 蓝队移动
for(let i=0; i<len; i++) {
const posFromRight = len - i;
if(posFromRight % 2 === 0) {
gsap.to(`#prac-ball-${i}`, {y:90, x:100, duration:0.8});
}
}
}
if(s===3) {
document.getElementById("red-sum").textContent=data.redSum;
document.getElementById("blue-sum").textContent=data.blueSum;
gsap.to("#red-sum, #blue-sum", {opacity:1});
}
if(s===4) {
gsap.to("#res-group", {opacity:1});
document.getElementById("diff-txt").textContent=`${data.redSum}-${data.blueSum}=${data.diff}`;
document.getElementById("final-txt").textContent=data.res?"✅ 通过":"❌ 不通过";
if(data.res && typeof confetti !== 'undefined') confetti();
}
},
nextStep() {
if(!this.isLastStep) {
this.step++;
this.speak(this.currentDesc);
if(this.demoMode === 'principle') this.playPrinciple(this.step);
else if(this.demoMode === 'example') this.playExample(this.step);
else this.playPractice(this.step);
}
},
prevStep() {
if(this.step > 0) {
this.step--;
this.resetAndLoad();
}
},
// --- 讲解页逻辑 ---
toggleQuestion(id) {
this.expandedQ = this.expandedQ === id ? null : id;
},
// --- 练习题逻辑 ---
checkPractice(idx) {
if(this.practiceAnswered) return;
this.practiceAnswered = true;
this.selectedPracticeOpt = idx;
this.isPracticeCorrect = idx === this.practiceQuestions[this.currentQuestion].ans;
if(this.isPracticeCorrect) {
this.score += 10;
if(typeof confetti !== 'undefined') confetti();
} else {
// 错误抖动效果
const wrongBtn = document.querySelector('.option-btn.wrong');
if(wrongBtn) gsap.to(wrongBtn, {x: [-5, 5, -5, 5, 0], duration: 0.5});
}
},
nextPractice() {
if(this.currentQuestion < this.practiceQuestions.length - 1) {
this.currentQuestion++;
this.practiceAnswered = false;
this.selectedPracticeOpt = null;
} else {
this.practiceCompleted = true;
}
},
// --- 奥数题逻辑 ---
checkOlympiad(idx) {
if(this.olympiadAnswered) return;
this.selectedOlympiadOpt = idx;
const isCorrect = idx === this.olympiadQuestions[this.currentOlympiad].ans;
if(isCorrect) {
this.olympiadAnswered = true;
this.isOlympiadCorrect = true;
this.olympiadScore += (10 - this.wrongAttempts * 2); // 简单的扣分逻辑
if(typeof confetti !== 'undefined') confetti();
} else {
this.wrongAttempts++;
const wrongBtn = document.querySelectorAll('.practice-page .option-btn')[idx];
if(wrongBtn) gsap.to(wrongBtn, {x: [-5, 5, -5, 5, 0], duration: 0.5});
if(this.wrongAttempts >= 3) { // 3次错误自动显示答案
this.olympiadAnswered = true;
this.isOlympiadCorrect = false;
}
}
},
nextOlympiad() {
if(this.currentOlympiad < this.olympiadQuestions.length - 1) {
this.currentOlympiad++;
this.olympiadAnswered = false;
this.selectedOlympiadOpt = null;
this.wrongAttempts = 0;
} else {
this.olympiadCompleted = true;
}
}
}
}).mount('#app');
</script>
</body>
</html>
💡 这段代码完全由 gemini 生成。
登录后可复制完整代码