从音标起步 → 语音进阶 → 教材同步 → 生活对话 → 儿歌跟唱
选一个学习计划,开始你的英语之旅吧!
🏠 我的学习计划

选一个适合你的学习周期,系统会自动把全部课程拆成每天的任务。坚持打卡,你会惊喜地发现英语越来越简单!

💡 计划怎么选?

30 天速成:每天 20–30 分钟,只学最核心的音标、拼读和高频词汇,快速入门。
90 天标准:每天 15–20 分钟,完整覆盖音标、拼读、语音进阶、词汇、句型和生活用语,稳步提升。
180 天精学:每天 10–15 分钟,全部内容 + 语法 + 阅读策略 + 儿歌,学得扎实又轻松。
元音发音

元音是英语的心脏,声音要饱满、嘴巴形状很重要。点一点卡片,先听一遍,再跟着读两遍。✅ 表示你已经练过啦。

🌞 短元音(声音短促,像小皮球)

点击整张卡片可听发音

🌙 长元音(嘴巴拉长,像小火车呜——)

注意口型大小变化

💧 双元音(一个音滑向另一个音)

像滑滑梯,从前往后滑
🌟 延伸学习 · 更多元音乐趣
绕口令 Tongue Twisters:练 /æ/ 说 "A big black cat sat on a fat mat.";练 /iː/ 说 "Three green trees."
最小对立对 Minimal Pairs:/ɪ/ vs /iː/ — ship vs sheep(船 vs 羊);/æ/ vs /e/ — bad vs bed(坏 vs 床)。听辨练习超有用!
趣味小任务:对着镜子看口型,录下自己的发音,和真人发音对比,找出不一样的元音。
辅音发音

辅音像小积木,和元音拼在一起就成了单词。轻辅音(清脆无声)和浊辅音(带声带振动)要分清哦。

🫧 清辅音(声带不振动,轻快)

手放喉咙,感觉不到震动

🥁 浊辅音(声带振动,饱满)

手放喉咙,能感到震动
🌟 延伸学习 · 辅音小挑战
清浊对比:把手指放在喉咙上,读 "pig / big"、"tea / deer",感觉 /p/ /t/ /k/ 不振动、/b/ /d/ /g/ 会振动。
咬舌音专练:/θ/ 和 /ð/ 是中文没有的音。练 "three, thank, this, that",舌尖一定要轻轻伸出齿间。
绕口令:"She sells seashells by the seashore."(练 /ʃ/ 和 /s/);"Red lorry, yellow lorry."(练 /r/ 和 /l/)。
自然拼读 Phonics

看到字母组合,就能读出单词!这是英语国家小朋友认字的方法。学会它,你见词能读、听音能写。

🔤 字母的发音

字母名 ≠ 字母音,两样都要会

🧩 拼读小练习(一个音一个音连起来)

先听分解音,再听完整读音

✨ 高频字母组合

记住这些,能读成百上千个词
🌟 延伸学习 · 拼读闯关
更多字母组合:ai/ay 发 /eɪ/(rain, play)、oa/ow 发 /əʊ/(boat, snow)、ou/ow 发 /aʊ/(house, cow)。
魔法 e 家族:cap→cape、kit→kite、cut→cute、rob→robe,试着找规律。
拼读打卡:每天用拼读法读 5 个新单词,读对了给自己一颗小星星 ⭐。
语音进阶 📈

48 个音标只是起点。这一级按「音节 → 重音 → 连读 → 弱读 → 语调」五个台阶逐级加深——这是"听懂美国人说话"的关键。每个规则都有 📖 中文解析和例句示范,点 🔊 听给你听。

分类词汇

按主题学单词,最容易记住。先听发音,再大声说出来,最后试着说一个完整句子。

教材同步 📚

参考美国小学语文(Wonders / Journeys 等)低中年级教学大纲的三大核心:高频词(见字就读)、核心语法(12 条规则)、阅读策略(6 把金钥匙)。每条规则都有 📖 中文解析 + 例句跟读。

简单句子

会说句子,才真正会用英语。点 🔊 反复听,注意语调——疑问句末尾要上扬,陈述句末尾下降。

生活用语 💬

把英语用起来!8 个真实生活场景,都是美国小朋友每天真正在说的话。每句配中文翻译 + 用法解析(什么时候说、对谁说、怎么回)。先点 🔊 听,再自己说一遍。

日常对话

真实场景练起来!先听整段对话,再点每句话逐句跟读。学会了就能和外国小朋友聊天啦。

儿歌跟唱 🎵

15 首美国 7–10 岁孩子几乎都会唱的传统经典儿歌。每首都有逐句中英对照、关键词汇解析和句型解析,还能逐句播放或整首连播。跟着唱,英语自然就顺口了!

听力小测验

听一听,选一选。看看你记住多少!答对会变成绿色,答错再听一遍就好。

第 1 题
apple
点击下面的按钮听发音
得分:0 / 0
🦉 选一个学习计划(30 / 90 / 180 天),系统会帮你把全部课程拆成每天的任务。
每个知识点都有「中文解析 + 真人发音按钮」,还能切换男声/女声、美音/英音、调节语速。坚持打卡,英语越来越顺口!
const isHuawei = /huawei|honor/i.test((navigator.userAgent||'')); const isIOS = /iphone|ipad|ipod/i.test((navigator.userAgent||'')); gender: 'female', accent: 'US', rate: 0.85, audio: null, voices: [], // 有道真人发音可选音色(真实录音) youdaoType(){ return this.accent==='UK' ? 1 : 2; }, // Google 神经语音 locale gLocale(){ return ({US:'en-US', UK:'en-GB', AU:'en-AU'})[this.accent] || 'en-US'; }, loadSystemVoices(){ try{ if(typeof speechSynthesis === 'undefined') return; const pick = () => { try{ this.voices = speechSynthesis.getVoices() || []; }catch(e){ this.voices = []; } }; /* 全局事件委托:解决部分浏览器(尤其 iOS Safari)在切换标签、重绘后动态元素点击失效的问题 */ (function(){ function triggerPlay(el){ if(!el) return; try{ const ev = new MouseEvent('click', {bubbles:true, cancelable:true}); el.dispatchEvent(ev); }catch(ex){ try{ el.click(); }catch(e){} } } const handler = function(e){ const target = e.target; if(!target || !target.closest) return; const btn = target.closest('.play, .play-round, .big-play'); if(!btn) return; // 对 iOS 更友好:不阻止默认,仅在 touchend 确保能触发 if(e.type === 'touchend'){ // 触发一次 click 确保处理器生效 setTimeout(function(){ triggerPlay(btn); }, 0); } }; document.addEventListener('touchend', handler, {passive:true, capture:true}); document.addEventListener('click', handler, {capture:true}); })(); pick(); speechSynthesis.onvoiceschanged = pick; }catch(e){ this.voices = []; } }, stop(){ if(this.audio){ this.audio.pause(); this.audio = null; } try{ speechSynthesis.cancel(); }catch(e){} }, // 优先真人录音(单词/短语),其次网络TTS(长句),最后系统语音 speak(text, {slow=false, onend, forceSystem=false}={}){ this.stop(); if(!text) return; const rate = slow ? Math.max(0.55, this.rate-0.25) : this.rate; // 判断是否为短词/短语(有道真人录音只支持较短文本) const isShort = text.replace(/[^A-Za-z' -]/g,'').split(/\s+/).filter(Boolean).length <= 3 && text.length <= 34; let finished = false; const done = () => { if(!finished){ finished = true; if(onend) onend(); } }; // 依次尝试的音频源:短词优先有道真人录音;长句优先 Google TTS;并列互相兜底 const enc = encodeURIComponent(text); const youdao = `https://dict.youdao.com/dictvoice?audio=${enc}&type=${this.youdaoType()}`; const google = `https://translate.google.com/translate_tts?ie=UTF-8&q=${enc}&tl=${this.gLocale()}&client=tw-ob&ttsspeed=${rate.toFixed(2)}`; const gapi = `https://translate.googleapis.com/translate_tts?ie=UTF-8&q=${enc}&tl=${this.gLocale()}&client=tw-ob&ttsspeed=${rate.toFixed(2)}`; const sources = forceSystem ? [] : (isShort ? [youdao, google, gapi] : [google, gapi, youdao]); let i = 0; const tryNext = () => { if(finished) return; if(i >= sources.length){ // 网络音频全部失败 → 系统语音兜底;若系统语音也不可用则给出提示 const ok = this.speakSystem(text, rate, done); if(!ok){ VoiceUI.fail(); done(); } else { /* 系统语音已排队,若 2.5 秒仍无声音则提示 */ setTimeout(()=>{ if(!finished && this._systemFailed){ this._systemFailed=false; VoiceUI.fail(); done(); } }, 2500); } return; } const url = sources[i++]; this.playUrl(url, rate, done, tryNext); }; tryNext(); }, // 播放单个音频地址;成功→结束,失败/被拦截→调用 onfail 尝试下一个 playUrl(url, rate, done, onfail){ try{ const a = new Audio(); a.preload = 'auto'; a.src = url; a.playbackRate = Math.min(1.3, Math.max(0.6, rate)); this.audio = a; let settled = false; const fail = () => { if(settled) return; settled = true; if(this.audio===a) this.audio=null; onfail && onfail(); }; a.onended = () => { if(settled) return; settled = true; done(); }; a.onerror = fail; const p = a.play(); if(p && p.catch) p.catch(fail); // 3.5 秒还没开始出声,视为失败(网络被拦截) setTimeout(()=>{ if(!settled && (a.readyState<2 || a.paused)) fail(); }, 3500); }catch(e){ onfail && onfail(); } }, speakSystem(text, rate, done){ try{ if(typeof speechSynthesis === 'undefined' || typeof SpeechSynthesisUtterance === 'undefined') return false; this._systemFailed = false; try{ speechSynthesis.cancel(); }catch(e){} if(!this.voices.length){ try{ this.voices = speechSynthesis.getVoices() || []; }catch(e){ this.voices = []; } } const langPref = this.gLocale() || 'en-US'; const en = this.voices.filter(v=>/^en/i.test(v.lang)); let v = en.find(x=>x.lang===langPref && (/female/i.test(x.name)||/samantha|zira|google|aria|microsoft/i.test(x.name))) || en.find(x=>x.lang===langPref) || en.find(x=>/^en/i.test(x.lang)) || en[0]; const u = new SpeechSynthesisUtterance(text); if(v) u.voice = v; u.lang = langPref; u.rate = rate; u.pitch = this.gender==='male' ? 0.85 : 1.1; let started = false; u.onstart = () => { started = true; }; u.onend = () => { if(done) done(); }; u.onerror = () => { this._systemFailed = true; if(done) done(); }; // 华为等浏览器:需在下一轮事件循环再调用 speak setTimeout(function(){ try{ // 部分华为浏览器需要再次获取 voices if(!VOICE.voices.length && typeof speechSynthesis!=='undefined'){ try{ VOICE.voices = speechSynthesis.getVoices() || []; }catch(e){} } speechSynthesis.speak(u); }catch(e){} }, isHuawei ? 16 : 0); // 如果 1.8 秒内未开始朗读,判定系统语音不可用 setTimeout(function(){ if(!started){ VOICE._systemFailed = true; } }, 1800); return true; }catch(e){ return false; } } }; safe(function(){ VOICE.loadSystemVoices(); }); /* 华为等浏览器需要首次用户手势解锁音频(自动播放策略) */ (function(){ let unlocked=false; function unlock(){ if(unlocked) return; unlocked=true; try{ const a=new Audio(); a.src='data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAIA+AAACABAAZGF0YQAAAAA='; a.volume=0; const p=a.play(); if(p&&p.catch)p.catch(function(){}); }catch(e){} // 华为解锁系统语音 try{ if(typeof speechSynthesis!=='undefined' && typeof SpeechSynthesisUtterance!=='undefined'){ speechSynthesis.cancel(); const u2=new SpeechSynthesisUtterance(' '); u2.volume=0; u2.rate=1; speechSynthesis.speak(u2); setTimeout(function(){ try{ speechSynthesis.cancel(); }catch(e){} }, 10); } }catch(e){} ['touchstart','click'].forEach(ev=>document.removeEventListener(ev, unlock, true)); } ['touchstart','click'].forEach(ev=>document.addEventListener(ev, unlock, true)); })(); /* 播放失败/提示浮层:让用户知道发生了什么,而不是"点了没反应" */ const VoiceUI = { _t:null, toast(msg){ let el = document.getElementById('voiceToast'); if(!el){ el = document.createElement('div'); el.id = 'voiceToast'; el.style.cssText = 'position:fixed;left:50%;bottom:96px;transform:translateX(-50%);z-index:9999;'+ 'max-width:86vw;padding:11px 18px;border-radius:14px;font-size:14px;font-weight:700;'+ 'color:#fff;background:rgba(60,50,80,.94);box-shadow:0 8px 24px rgba(0,0,0,.25);'+ 'opacity:0;transition:opacity .25s;text-align:center;line-height:1.5;pointer-events:none'; document.body.appendChild(el); } el.textContent = msg; el.style.opacity = '1'; if(this._t) clearTimeout(this._t); this._t = setTimeout(()=>{ el.style.opacity='0'; }, 6000); }, fail(){ const online = (typeof navigator!=='undefined' && navigator.onLine===false); this.toast(online ? '📵 网络未连接,无法发音。请连接网络后重试' : '🔇 无法播放发音:请检查①手机未静音 ②已连网 ③点「🎧 发声设置」切换口音后重试'); } }; /* 播放按钮通用:点击播放 + 高亮状态 */ function playText(text, btn, opts={}){ document.querySelectorAll('.speaking').forEach(b=>b.classList.remove('speaking')); if(btn) btn.classList.add('speaking'); VOICE.speak(text, { slow: opts.slow, onend: () => { if(btn) btn.classList.remove('speaking'); } }); } /* ================================================================== 学习进度 ================================================================== */ const STORE_KEY = 'kids_english_progress_v1'; /* 安全存储:部分浏览器(华为自带/隐私模式)访问 localStorage 会抛异常 */ const SafeStore = { get(k){ try{ return localStorage.getItem(k); }catch(e){ return null; } }, set(k,v){ try{ localStorage.setItem(k,v); }catch(e){} }, del(k){ try{ localStorage.removeItem(k); }catch(e){} } }; function safeParse(s, fallback){ try{ return s? JSON.parse(s): fallback; }catch(e){ return fallback; } } let progress = safeParse(SafeStore.get(STORE_KEY), {}); function markLearned(id){ progress[id] = 1; SafeStore.set(STORE_KEY, JSON.stringify(progress)); safe(function(){ updateProgress(); }); } function updateProgress(){ const done = Object.keys(progress).filter(k=>progress[k]).length; const total = TOTAL_UNITS; const pct = total? Math.round(done/total*100):0; const fill = document.getElementById('progressFill'); if(fill) fill.style.width = pct + '%'; const txt = document.getElementById('progressText'); if(txt){ if(plan && plan.name){ txt.textContent = `${plan.emoji} ${plan.name} · 已掌握 ${done} / ${total} 个知识点(${pct}%)`; }else{ const cheer = pct>=100?'🎉 全部通关!':pct>=50?'👏 已经过半啦!':'👍 选个计划开始吧~'; txt.textContent = `已完成 ${done} / ${total} 项(${pct}%)· ` + cheer; } } if(typeof renderDashboard==='function') safe(function(){ renderDashboard(); }); } /* ================================================================== 数据:元音 ================================================================== */ const shortVowels = [ {id:'sv1', ipa:'/æ/', sym:'a', cn:'大嘴"哎",像被吓一跳', ex:'apple', exCn:'苹果', tip:'嘴巴张大,下巴往下'}, {id:'sv2', ipa:'/e/', sym:'e', cn:'小嘴"诶",嘴角往两边', ex:'bed', exCn:'床', tip:'嘴巴半开,像微笑'}, {id:'sv3', ipa:'/ɪ/', sym:'i', cn:'短"衣",比中文短促', ex:'sit', exCn:'坐', tip:'嘴角咧开,声音短'}, {id:'sv4', ipa:'/ɒ/', sym:'o', cn:'圆嘴"奥",嘴型圆', ex:'dog', exCn:'狗', tip:'嘴巴圆圆的,像公鸡'}, {id:'sv5', ipa:'/ʌ/', sym:'u', cn:'短"啊",像被扎一下', ex:'cup', exCn:'杯子', tip:'嘴巴自然张开,短促'}, {id:'sv6', ipa:'/ʊ/', sym:'u', cn:'短"乌",像小声"呜"', ex:'book', exCn:'书', tip:'嘴唇微微撅起'}, ]; const longVowels = [ {id:'lv1', ipa:'/iː/', sym:'ee', cn:'长"衣",嘴角咧到耳朵', ex:'sheep', exCn:'绵羊', tip:'像微笑一样咧嘴'}, {id:'lv2', ipa:'/ɑː/', sym:'ar', cn:'长"啊",像医生检查喉咙', ex:'car', exCn:'小汽车', tip:'嘴巴张大,声音拉长'}, {id:'lv3', ipa:'/ɔː/', sym:'aw', cn:'长"奥",嘴巴圆圆', ex:'door', exCn:'门', tip:'嘴唇收圆向前'}, {id:'lv4', ipa:'/uː/', sym:'oo', cn:'长"乌",嘴唇撅很高', ex:'moon', exCn:'月亮', tip:'嘴唇撅成小圆'}, {id:'lv5', ipa:'/ɜː/', sym:'er', cn:'长"额",像生气的哼', ex:'bird', exCn:'小鸟', tip:'嘴型放松,舌头中平'}, ]; const diphthongs = [ {id:'dt1', ipa:'/eɪ/', sym:'ay', cn:'"诶—衣"滑动', ex:'day', exCn:'白天', tip:'从诶滑到衣'}, {id:'dt2', ipa:'/aɪ/', sym:'eye', cn:'"啊—衣"滑动', ex:'my', exCn:'我的', tip:'从大啊滑到衣'}, {id:'dt3', ipa:'/ɔɪ/', sym:'oy', cn:'"奥—衣"滑动', ex:'boy', exCn:'男孩', tip:'圆嘴滑到咧嘴'}, {id:'dt4', ipa:'/aʊ/', sym:'ow', cn:'"啊—乌"滑动', ex:'how', exCn:'怎样', tip:'像惊讶的"嗷"'}, {id:'dt5', ipa:'/əʊ/', sym:'oh', cn:'"额—乌"滑动', ex:'go', exCn:'去', tip:'从放松滑到圆嘴'}, ]; /* 辅音 */ const voiceless = [ {id:'v1', ipa:'/p/', sym:'p', cn:'轻"泼"', ex:'pen', exCn:'钢笔', tip:'双唇紧闭再送气'}, {id:'v2', ipa:'/t/', sym:'t', cn:'轻"特"', ex:'tea', exCn:'茶', tip:'舌尖顶上齿龈'}, {id:'v3', ipa:'/k/', sym:'k', cn:'轻"科"', ex:'cat', exCn:'猫', tip:'舌后顶软腭送气'}, {id:'v4', ipa:'/f/', sym:'f', cn:'咬唇"夫"', ex:'fish', exCn:'鱼', tip:'上齿咬住下唇吹气'}, {id:'v5', ipa:'/s/', sym:'s', cn:'咬舌"斯"', ex:'sun', exCn:'太阳', tip:'舌尖靠近上齿,漏气'}, {id:'v6', ipa:'/θ/', sym:'th', cn:'咬舌尖"斯"', ex:'think', exCn:'想', tip:'舌尖轻轻咬在齿间'}, {id:'v7', ipa:'/ʃ/', sym:'sh', cn:'嘘声"嘘"', ex:'ship', exCn:'轮船', tip:'像让人安静的"嘘"'}, {id:'v8', ipa:'/h/', sym:'h', cn:'轻"呵"', ex:'hat', exCn:'帽子', tip:'像哈气'}, {id:'v9', ipa:'/tʃ/', sym:'ch', cn:'"切"', ex:'chair', exCn:'椅子', tip:'先顶后送气'}, {id:'v10', ipa:'/ts/', sym:'ts', cn:'"茨"', ex:'cats', exCn:'猫(复数)', tip:'舌尖顶住再送气'}, ]; const voiced = [ {id:'w1', ipa:'/b/', sym:'b', cn:'浊"波"', ex:'bus', exCn:'公交车', tip:'声带振动的p'}, {id:'w2', ipa:'/d/', sym:'d', cn:'浊"得"', ex:'dog', exCn:'狗', tip:'声带振动的t'}, {id:'w3', ipa:'/g/', sym:'g', cn:'浊"哥"', ex:'go', exCn:'去', tip:'声带振动的k'}, {id:'w4', ipa:'/v/', sym:'v', cn:'浊"务"', ex:'van', exCn:'货车', tip:'咬唇+振动'}, {id:'w5', ipa:'/z/', sym:'z', cn:'浊"滋"', ex:'zoo', exCn:'动物园', tip:'声带振动的s'}, {id:'w6', ipa:'/ð/', sym:'th', cn:'咬舌浊音', ex:'this', exCn:'这个', tip:'咬舌尖+振动'}, {id:'w7', ipa:'/ʒ/', sym:'zh', cn:'浊"日"', ex:'measure', exCn:'测量', tip:'像"日"但更靠后'}, {id:'w8', ipa:'/r/', sym:'r', cn:'卷舌"若"', ex:'red', exCn:'红色', tip:'舌尖卷起不碰上颚'}, {id:'w9', ipa:'/l/', sym:'l', cn:'"乐"', ex:'leg', exCn:'腿', tip:'舌尖顶上齿龈'}, {id:'w10', ipa:'/m/', sym:'m', cn:'闭嘴"姆"', ex:'mom', exCn:'妈妈', tip:'双唇闭合,鼻子出气'}, {id:'w11', ipa:'/n/', sym:'n', cn:'"嗯"', ex:'no', exCn:'不', tip:'舌尖顶齿龈,鼻子出气'}, {id:'w12', ipa:'/ŋ/', sym:'ng', cn:'"嗯"后鼻', ex:'sing', exCn:'唱歌', tip:'舌后顶软腭,鼻子出气'}, {id:'w13', ipa:'/w/', sym:'w', cn:'"乌"', ex:'water', exCn:'水', tip:'嘴唇撅圆'}, {id:'w14', ipa:'/j/', sym:'y', cn:'"耶"', ex:'yes', exCn:'是的', tip:'像中文"耶"'}, ]; /* 自然拼读 */ const letterSounds = [ {id:'ls-a', letter:'A a', sound:'/æ/', cn:'a 短音', word:'ant', tip:'像小蚂蚁 ant'}, {id:'ls-b', letter:'B b', sound:'/b/', cn:'b 音', word:'bee', tip:'像小蜜蜂 bee'}, {id:'ls-c', letter:'C c', sound:'/k/', cn:'c 音', word:'cat', tip:'像小猫 cat'}, {id:'ls-d', letter:'D d', sound:'/d/', cn:'d 音', word:'dog', tip:'像小狗 dog'}, {id:'ls-e', letter:'E e', sound:'/e/', cn:'e 短音', word:'egg', tip:'像鸡蛋 egg'}, {id:'ls-f', letter:'F f', sound:'/f/', cn:'f 音', word:'fan', tip:'像风扇 fan'}, {id:'ls-g', letter:'G g', sound:'/g/', cn:'g 音', word:'go', tip:'go 去'}, {id:'ls-h', letter:'H h', sound:'/h/', cn:'h 音', word:'hat', tip:'像帽子 hat'}, {id:'ls-i', letter:'I i', sound:'/ɪ/', cn:'i 短音', word:'ink', tip:'像墨水 ink'}, {id:'ls-j', letter:'J j', sound:'/dʒ/', cn:'j 音', word:'jam', tip:'像果酱 jam'}, {id:'ls-k', letter:'K k', sound:'/k/', cn:'k 音', word:'kite', tip:'像风筝 kite'}, {id:'ls-l', letter:'L l', sound:'/l/', cn:'l 音', word:'leg', tip:'像腿 leg'}, {id:'ls-m', letter:'M m', sound:'/m/', cn:'m 音', word:'moon', tip:'像月亮 moon'}, {id:'ls-n', letter:'N n', sound:'/n/', cn:'n 音', word:'nut', tip:'像坚果 nut'}, {id:'ls-o', letter:'O o', sound:'/ɒ/', cn:'o 短音', word:'ox', tip:'像公牛 ox'}, {id:'ls-p', letter:'P p', sound:'/p/', cn:'p 音', word:'pig', tip:'像小猪 pig'}, {id:'ls-q', letter:'Q q', sound:'/kw/', cn:'kw 音', word:'queen', tip:'像女王 queen'}, {id:'ls-r', letter:'R r', sound:'/r/', cn:'r 音', word:'run', tip:'像跑步 run'}, {id:'ls-s', letter:'S s', sound:'/s/', cn:'s 音', word:'sun', tip:'像太阳 sun'}, {id:'ls-t', letter:'T t', sound:'/t/', cn:'t 音', word:'top', tip:'像顶端 top'}, {id:'ls-u', letter:'U u', sound:'/ʌ/', cn:'u 短音', word:'up', tip:'像向上 up'}, {id:'ls-v', letter:'V v', sound:'/v/', cn:'v 音', word:'van', tip:'像货车 van'}, {id:'ls-w', letter:'W w', sound:'/w/', cn:'w 音', word:'win', tip:'像赢 win'}, {id:'ls-x', letter:'X x', sound:'/ks/', cn:'ks 音', word:'box', tip:'像盒子 box'}, {id:'ls-y', letter:'Y y', sound:'/j/', cn:'y 音', word:'yes', tip:'像 yes'}, {id:'ls-z', letter:'Z z', sound:'/z/', cn:'z 音', word:'zoo', tip:'像动物园 zoo'}, ]; const blends = [ {id:'bl1', parts:['c','a','t'], word:'cat', cn:'猫', tip:'c-a-t,慢慢连起来'}, {id:'bl2', parts:['d','o','g'], word:'dog', cn:'狗', tip:'d-o-g'}, {id:'bl3', parts:['b','us'], word:'bus', cn:'公交车', tip:'b-us'}, {id:'bl4', parts:['p','en'], word:'pen', cn:'钢笔', tip:'p-en'}, {id:'bl5', parts:['s','un'], word:'sun', cn:'太阳', tip:'s-un'}, {id:'bl6', parts:['m','o','m'], word:'mom', cn:'妈妈', tip:'m-o-m'}, {id:'bl7', parts:['h','a','t'], word:'hat', cn:'帽子', tip:'h-a-t'}, {id:'bl8', parts:['b','i','g'], word:'big', cn:'大的', tip:'b-i-g'}, {id:'bl9', parts:['f','i','sh'], word:'fish', cn:'鱼', tip:'f-i-sh'}, {id:'bl10', parts:['st','ar'], word:'star', cn:'星星', tip:'st-ar 连读'}, {id:'bl11', parts:['tr','ee'], word:'tree', cn:'树', tip:'tr-ee'}, {id:'bl12', parts:['pl','ay'], word:'play', cn:'玩', tip:'pl-ay'}, ]; const combos = [ {id:'cb1', combo:'ee', sound:'/iː/', words:['see 看见','tree 树','bee 蜜蜂'], tip:'ee 常发长"衣"音'}, {id:'cb2', combo:'oo', sound:'/uː/', words:['moon 月亮','food 食物','zoo 动物园'], tip:'oo 常发长"乌"音'}, {id:'cb3', combo:'sh', sound:'/ʃ/', words:['ship 轮船','shop 商店','fish 鱼'], tip:'sh 就是"嘘"'}, {id:'cb4', combo:'ch', sound:'/tʃ/', words:['chair 椅子','chat 聊天','lunch 午餐'], tip:'ch 像"切"'}, {id:'cb5', combo:'th', sound:'/θ/', words:['think 想','three 三','thank 感谢'], tip:'咬舌尖送气'}, {id:'cb6', combo:'ck', sound:'/k/', words:['duck 鸭子','back 后面','clock 时钟'], tip:'ck 结尾发 k'}, {id:'cb7', combo:'ng', sound:'/ŋ/', words:['sing 唱歌','ring 戒指','king 国王'], tip:'后鼻音'}, {id:'cb8', combo:'igh', sound:'/aɪ/', words:['night 夜晚','light 灯','high 高的'], tip:'igh 发长"爱"'}, ]; /* 词汇主题 */ const vocabGroups = [ {id:'v-color', name:'🎨 颜色', words:[ {en:'red', ipa:'/red/', cn:'红色', emoji:'🔴', note:'I like red. 我喜欢红色。'}, {en:'blue', ipa:'/bluː/', cn:'蓝色', emoji:'🔵', note:'The sky is blue. 天空是蓝色的。'}, {en:'yellow', ipa:'/ˈjeləʊ/', cn:'黄色', emoji:'🟡', note:'A yellow banana. 一根黄香蕉。'}, {en:'green', ipa:'/ɡriːn/', cn:'绿色', emoji:'🟢', note:'Green leaves. 绿色的叶子。'}, {en:'orange', ipa:'/ˈɒrɪndʒ/', cn:'橙色', emoji:'🟠', note:'My bag is orange. 我的包是橙色的。'}, {en:'purple', ipa:'/ˈpɜːpl/', cn:'紫色', emoji:'🟣', note:'A purple flower. 一朵紫花。'}, {en:'black', ipa:'/blæk/', cn:'黑色', emoji:'⚫', note:'A black cat. 一只黑猫。'}, {en:'white', ipa:'/waɪt/', cn:'白色', emoji:'⚪', note:'White snow. 白雪。'}, {en:'pink', ipa:'/pɪŋk/', cn:'粉色', emoji:'🌸', note:'A pink dress. 一条粉色裙子。'}, {en:'brown', ipa:'/braʊn/', cn:'棕色', emoji:'🟤', note:'A brown bear. 一只棕熊。'}, ]}, {id:'v-animal', name:'🐾 动物', words:[ {en:'cat', ipa:'/kæt/', cn:'猫', emoji:'🐱', note:'The cat is cute. 这只猫很可爱。'}, {en:'dog', ipa:'/dɒɡ/', cn:'狗', emoji:'🐶', note:'A dog can run fast. 狗跑得快。'}, {en:'bird', ipa:'/bɜːd/', cn:'小鸟', emoji:'🐦', note:'Birds can fly. 鸟会飞。'}, {en:'fish', ipa:'/fɪʃ/', cn:'鱼', emoji:'🐟', note:'Fish live in water. 鱼生活在水里。'}, {en:'rabbit', ipa:'/ˈræbɪt/', cn:'兔子', emoji:'🐰', note:'A rabbit has long ears. 兔子有长耳朵。'}, {en:'bear', ipa:'/beə/', cn:'熊', emoji:'🐻', note:'The bear is big. 熊很大。'}, {en:'panda', ipa:'/ˈpændə/', cn:'熊猫', emoji:'🐼', note:'Pandas are from China. 熊猫来自中国。'}, {en:'duck', ipa:'/dʌk/', cn:'鸭子', emoji:'🦆', note:'A duck can swim. 鸭子会游泳。'}, {en:'elephant', ipa:'/ˈelɪfənt/', cn:'大象', emoji:'🐘', note:'An elephant is very big. 大象非常大。'}, {en:'monkey', ipa:'/ˈmʌŋki/', cn:'猴子', emoji:'🐵', note:'Monkeys like bananas. 猴子喜欢香蕉。'}, ]}, {id:'v-food', name:'🍎 食物', words:[ {en:'apple', ipa:'/ˈæpl/', cn:'苹果', emoji:'🍎', note:'An apple a day. 一天一个苹果。'}, {en:'banana', ipa:'/bəˈnɑːnə/', cn:'香蕉', emoji:'🍌', note:'I eat a banana. 我吃一根香蕉。'}, {en:'egg', ipa:'/eɡ/', cn:'鸡蛋', emoji:'🥚', note:'I have an egg for breakfast. 我早餐吃鸡蛋。'}, {en:'milk', ipa:'/mɪlk/', cn:'牛奶', emoji:'🥛', note:'Drink your milk. 把牛奶喝掉。'}, {en:'bread', ipa:'/bred/', cn:'面包', emoji:'🍞', note:'I like bread. 我喜欢面包。'}, {en:'water', ipa:'/ˈwɔːtə/', cn:'水', emoji:'💧', note:'I want some water. 我想要点水。'}, {en:'juice', ipa:'/dʒuːs/', cn:'果汁', emoji:'🧃', note:'Orange juice, please. 请给我橙汁。'}, {en:'rice', ipa:'/raɪs/', cn:'米饭', emoji:'🍚', note:'We eat rice. 我们吃米饭。'}, {en:'cake', ipa:'/keɪk/', cn:'蛋糕', emoji:'🍰', note:'A birthday cake. 一个生日蛋糕。'}, {en:'candy', ipa:'/ˈkændi/', cn:'糖果', emoji:'🍬', note:'Too much candy is bad. 糖吃多了不好。'}, ]}, {id:'v-family', name:'👨‍👩‍👧‍👦 家庭', words:[ {en:'mom', ipa:'/mɒm/', cn:'妈妈', emoji:'👩', note:'My mom is kind. 我妈妈很温柔。'}, {en:'dad', ipa:'/dæd/', cn:'爸爸', emoji:'👨', note:'My dad is tall. 我爸爸很高。'}, {en:'sister', ipa:'/ˈsɪstə/', cn:'姐妹', emoji:'👧', note:'I have one sister. 我有一个姐妹。'}, {en:'brother', ipa:'/ˈbrʌðə/', cn:'兄弟', emoji:'👦', note:'My brother is ten. 我哥哥十岁。'}, {en:'grandma', ipa:'/ˈɡrɑːnmɑː/', cn:'奶奶/外婆', emoji:'👵', note:'Grandma makes good food. 奶奶做的饭好吃。'}, {en:'grandpa', ipa:'/ˈɡrænpɑː/', cn:'爷爷/外公', emoji:'👴', note:'Grandpa tells stories. 爷爷讲故事。'}, {en:'baby', ipa:'/ˈbeɪbi/', cn:'宝宝', emoji:'👶', note:'The baby is sleeping. 宝宝在睡觉。'}, {en:'family', ipa:'/ˈfæməli/', cn:'家庭', emoji:'🏠', note:'I love my family. 我爱我的家。'}, ]}, {id:'v-number', name:'🔢 数字', words:[ {en:'one', ipa:'/wʌn/', cn:'一', emoji:'1️⃣', note:'one apple 一个苹果'}, {en:'two', ipa:'/tuː/', cn:'二', emoji:'2️⃣', note:'two cats 两只猫'}, {en:'three', ipa:'/θriː/', cn:'三', emoji:'3️⃣', note:'three books 三本书'}, {en:'four', ipa:'/fɔː/', cn:'四', emoji:'4️⃣', note:'four legs 四条腿'}, {en:'five', ipa:'/faɪv/', cn:'五', emoji:'5️⃣', note:'five fingers 五根手指'}, {en:'six', ipa:'/sɪks/', cn:'六', emoji:'6️⃣', note:'six eggs 六个鸡蛋'}, {en:'seven', ipa:'/ˈsevn/', cn:'七', emoji:'7️⃣', note:'I am seven. 我七岁。'}, {en:'eight', ipa:'/eɪt/', cn:'八', emoji:'8️⃣', note:'eight o clock 八点'}, {en:'nine', ipa:'/naɪn/', cn:'九', emoji:'9️⃣', note:'nine stars 九颗星星'}, {en:'ten', ipa:'/ten/', cn:'十', emoji:'🔟', note:'ten toes 十个脚趾'}, ]}, {id:'v-body', name:'🤸 身体', words:[ {en:'head', ipa:'/hed/', cn:'头', emoji:'🙂', note:'Touch your head. 摸摸你的头。'}, {en:'eye', ipa:'/aɪ/', cn:'眼睛', emoji:'👁', note:'Close your eyes. 闭上眼睛。'}, {en:'ear', ipa:'/ɪə/', cn:'耳朵', emoji:'👂', note:'I have two ears. 我有两只耳朵。'}, {en:'nose', ipa:'/nəʊz/', cn:'鼻子', emoji:'👃', note:'A small nose. 一个小鼻子。'}, {en:'mouth', ipa:'/maʊθ/', cn:'嘴巴', emoji:'👄', note:'Open your mouth. 张开嘴巴。'}, {en:'hand', ipa:'/hænd/', cn:'手', emoji:'🤚', note:'Raise your hand. 举起手。'}, {en:'foot', ipa:'/fʊt/', cn:'脚', emoji:'🦶', note:'My foot hurts. 我的脚疼。'}, {en:'arm', ipa:'/ɑːm/', cn:'手臂', emoji:'💪', note:'Move your arms. 活动手臂。'}, ]}, {id:'v-school', name:'🎒 学校', words:[ {en:'book', ipa:'/bʊk/', cn:'书', emoji:'📖', note:'Open your book. 打开你的书。'}, {en:'pen', ipa:'/pen/', cn:'钢笔', emoji:'🖊', note:'I have a blue pen. 我有一支蓝钢笔。'}, {en:'pencil', ipa:'/ˈpensl/', cn:'铅笔', emoji:'✏️', note:'Use a pencil to write. 用铅笔写字。'}, {en:'ruler', ipa:'/ˈruːlə/', cn:'尺子', emoji:'📏', note:'A ruler is long. 尺子很长。'}, {en:'eraser', ipa:'/ɪˈreɪzə/', cn:'橡皮', emoji:'🧹', note:'May I use your eraser? 我能用你的橡皮吗?'}, {en:'bag', ipa:'/bæɡ/', cn:'书包', emoji:'🎒', note:'My bag is heavy. 我的书包很重。'}, {en:'teacher', ipa:'/ˈtiːtʃə/', cn:'老师', emoji:'👩‍🏫', note:'The teacher is nice. 老师很好。'}, {en:'student', ipa:'/ˈstjuːdnt/', cn:'学生', emoji:'🧑‍🎓', note:'I am a student. 我是学生。'}, {en:'desk', ipa:'/desk/', cn:'课桌', emoji:'🪑', note:'Sit at your desk. 坐好在课桌前。'}, {en:'chair', ipa:'/tʃeə/', cn:'椅子', emoji:'💺', note:'Sit on the chair. 坐在椅子上。'}, ]}, {id:'v-weather', name:'☀️ 天气', words:[ {en:'sunny', ipa:'/ˈsʌni/', cn:'晴朗的', emoji:'☀️', note:'It is sunny today. 今天晴天。'}, {en:'rainy', ipa:'/ˈreɪni/', cn:'下雨的', emoji:'🌧', note:'A rainy day. 一个雨天。'}, {en:'windy', ipa:'/ˈwɪndi/', cn:'有风的', emoji:'🌬', note:'It is windy outside. 外面有风。'}, {en:'cloudy', ipa:'/ˈklaʊdi/', cn:'多云的', emoji:'☁️', note:'It is cloudy. 是多云天气。'}, {en:'snowy', ipa:'/ˈsnəʊi/', cn:'下雪的', emoji:'❄️', note:'A snowy night. 一个雪夜。'}, {en:'hot', ipa:'/hɒt/', cn:'热的', emoji:'🥵', note:'It is hot in summer. 夏天很热。'}, {en:'cold', ipa:'/kəʊld/', cn:'冷的', emoji:'🥶', note:'It is cold in winter. 冬天很冷。'}, {en:'warm', ipa:'/wɔːm/', cn:'温暖的', emoji:'🌤', note:'Spring is warm. 春天很暖和。'}, ]}, {id:'v-motion', name:'🏃 动作', words:[ {en:'run', ipa:'/rʌn/', cn:'跑', emoji:'🏃', note:'I can run fast. 我能跑很快。'}, {en:'jump', ipa:'/dʒʌmp/', cn:'跳', emoji:'🤸', note:'Jump up high! 跳高一点!'}, {en:'walk', ipa:'/wɔːk/', cn:'走', emoji:'🚶', note:'We walk to school. 我们走去学校。'}, {en:'sleep', ipa:'/sliːp/', cn:'睡觉', emoji:'😴', note:'I sleep at nine. 我九点睡觉。'}, {en:'eat', ipa:'/iːt/', cn:'吃', emoji:'🍽', note:'We eat lunch at noon. 我们中午吃午饭。'}, {en:'drink', ipa:'/drɪŋk/', cn:'喝', emoji:'🥤', note:'Drink more water. 多喝水。'}, {en:'sing', ipa:'/sɪŋ/', cn:'唱歌', emoji:'🎤', note:'Let us sing a song. 我们唱首歌。'}, {en:'dance', ipa:'/dɑːns/', cn:'跳舞', emoji:'💃', note:'She likes to dance. 她喜欢跳舞。'}, {en:'read', ipa:'/riːd/', cn:'阅读', emoji:'📚', note:'I read every day. 我每天读书。'}, {en:'draw', ipa:'/drɔː/', cn:'画画', emoji:'🎨', note:'Draw a cat. 画一只猫。'}, ]}, ]; /* 句子 */ const sentenceGroups = [ {id:'s-intro', name:'🙋 自我介绍', tip:'介绍自己时,先说名字,再说年龄、来自哪里,最后加一句"很高兴认识你",礼貌又完整。', lines:[ {en:'Hello! My name is Tom.', cn:'你好!我叫汤姆。', tip:'重读 name 和 Tom', why:'My name is... 是最标准的自我介绍句型,也可以简说 I am Tom.'}, {en:'I am seven years old.', cn:'我七岁了。', tip:'重读 seven', why:'说年龄固定用"数字 + years old",不能说 I am seven years。'}, {en:'I am from China.', cn:'我来自中国。', tip:'重读 China', why:'be from + 国家/城市,表示"来自某地"。'}, {en:'Nice to meet you!', cn:'很高兴认识你!', tip:'语调上扬,表示热情', why:'初次见面专用。对方要回 Nice to meet you, too.'}, {en:'This is my friend, Lily.', cn:'这是我的朋友莉莉。', tip:'重读 friend', why:'This is... 用来把身边的朋友介绍给别人。'}, ]}, {id:'s-greet', name:'👋 问候招呼', tip:'问候语分时间段:早上好、下午好、晚上好。回答 How are you? 时用固定答句即可。', lines:[ {en:'Good morning!', cn:'早上好!', tip:'morning 语调下降', why:'中午前用 morning,下午用 afternoon,晚上用 evening。'}, {en:'How are you?', cn:'你好吗?', tip:'you 语调上扬', why:'最常用的问候。熟人之间也可以说 How are you doing?'}, {en:'I am fine, thank you.', cn:'我很好,谢谢。', tip:'thank you 连读', why:'标准答句。也可以说 I am good / I am great.'}, {en:'See you tomorrow!', cn:'明天见!', tip:'tomorrow 重读', why:'See you + 时间,如 See you later(待会见)。'}, {en:'Have a nice day!', cn:'祝你有美好的一天!', tip:'nice day 重读', why:'道别时的祝福语,对方回 You too(你也是)。'}, ]}, {id:'s-school', name:'🏫 学校用语', tip:'课堂上最常说的几句话,掌握这几句就能和老师顺畅交流。', lines:[ {en:'What is this?', cn:'这是什么?', tip:'this 稍拉长', why:'问近处的东西用 this;远处用 that(What is that?)。'}, {en:'It is a book.', cn:'这是一本书。', tip:'book 重读', why:'回答用 It is a/an + 名词。元音开头用 an,如 an apple。'}, {en:'Open your book, please.', cn:'请打开你的书。', tip:'Open 起头重读', why:'祈使句(命令句)直接以动词开头,加 please 更礼貌。'}, {en:'I like English.', cn:'我喜欢英语。', tip:'like 和 English 重读', why:'表达喜好用 I like + 名词。不喜欢说 I do not like。'}, {en:'Can you help me?', cn:'你能帮我吗?', tip:'help 重读,句尾上扬', why:'Can you...? 是请求帮助的礼貌句型。'}, ]}, {id:'s-daily', name:'🏠 日常表达', tip:'表达感觉和需求,是每天都要用到的口语。', lines:[ {en:'I am hungry.', cn:'我饿了。', tip:'hungry 重读', why:'I am + 形容词,表达身体和情绪状态(tired 累、happy 开心)。'}, {en:'I want some water.', cn:'我想要些水。', tip:'water 重读', why:'I want + 名词。想更礼貌可以说 I would like some water.'}, {en:'Let us play together!', cn:'我们一起玩吧!', tip:'play 重读', why:'Let us... 表示建议一起做某事,口语常缩写成 Lets。'}, {en:'I am tired.', cn:'我累了。', tip:'tired 拉长', why:'状态形容词,前面必须有 be 动词(am/is/are)。'}, {en:'It is time for bed.', cn:'该睡觉了。', tip:'time 和 bed 重读', why:'It is time for + 名词,表示"该做某事了"。'}, ]}, ]; /* 对话 */ const talkGroups = [ {id:'t-morning', name:'🌅 早上上学', tip:'对话礼仪:见面先问候,被问候时要回应,再说自己的情况。', lines:[ {who:'A', en:'Good morning, teacher!', cn:'老师,早上好!', why:'对老师称呼 teacher 或在姓后加 Mr./Ms.,如 Mr. Smith。'}, {who:'B', en:'Good morning, Lily! How are you today?', cn:'早上好,莉莉!今天怎么样?', why:'How are you today? 比 How are you? 更亲切,关注对方今天的状态。'}, {who:'A', en:'I am great, thank you! And you?', cn:'我很好,谢谢!您呢?', why:'回答后加 And you? 表示关心对方,是礼貌的对话习惯。'}, {who:'B', en:'I am good, too. Let us go to class.', cn:'我也很好。我们去上课吧。', why:'too 表示"也",放在肯定句末。Let us + 动词表示一起做某事。'}, ]}, {id:'t-friend', name:'👫 交朋友', tip:'交朋友的关键句型:问名字 → 答名字 → 回问 → 说"很高兴认识你"。', lines:[ {who:'A', en:'Hi! What is your name?', cn:'嗨!你叫什么名字?', why:'问名字用 What is your name?,也可以说 What is your name?'}, {who:'B', en:'My name is Ben. What about you?', cn:'我叫本。你呢?', why:'What about you? = And you?,把问题抛回给对方。'}, {who:'A', en:'I am Amy. Nice to meet you!', cn:'我是艾米。很高兴认识你!', why:'介绍自己可以简化成 I am + 名字,更自然。'}, {who:'B', en:'Nice to meet you, too! Let us play!', cn:'我也很高兴!我们一起玩吧!', why:'回应 Nice to meet you 一定要加 too。'}, ]}, {id:'t-food', name:'🍽 吃东西', tip:'点餐、要东西的礼貌句型和回应感谢的话。', lines:[ {who:'A', en:'I am hungry. I want an apple.', cn:'我饿了。我想要一个苹果。', why:'apple 元音开头,用 an 而不是 a(an apple, a banana)。'}, {who:'B', en:'Here you are. Do you like bananas?', cn:'给你。你喜欢香蕉吗?', why:'递东西时说 Here you are。问喜好用 Do you like...?'}, {who:'A', en:'Yes, I do. Thank you very much!', cn:'是的,我喜欢。非常感谢!', why:'回答 Do you like...? 用 Yes, I do / No, I do not。'}, {who:'B', en:'You are welcome!', cn:'不客气!', why:'回应 Thank you 用 You are welcome,也可以说 No problem。'}, ]}, {id:'t-ask', name:'❓ 问问题', tip:'问颜色、问数量是小学最常考的问句,注意 How many 后面接复数。', lines:[ {who:'A', en:'What color is it?', cn:'它是什么颜色?', why:'问颜色固定句型 What color is it? 回答 It is + 颜色。'}, {who:'B', en:'It is red.', cn:'它是红色的。', why:'颜色作形容词放在 be 动词后面作表语。'}, {who:'A', en:'How many books do you have?', cn:'你有几本书?', why:'How many + 复数名词,问数量。'}, {who:'B', en:'I have three books.', cn:'我有三本书。', why:'have 表示"有",数量词后名词要用复数(three books)。'}, ]}, {id:'t-help', name:'🆘 求助', tip:'遇到困难时怎么说:先说 Excuse me 引起注意,再礼貌求助。', lines:[ {who:'A', en:'Excuse me, can you help me?', cn:'打扰一下,你能帮我吗?', why:'Excuse me 用在打扰别人、提问之前,很有礼貌。'}, {who:'B', en:'Sure! What is wrong?', cn:'当然!怎么了?', why:'What is wrong? = Whats the matter?,问"出什么事了"。'}, {who:'A', en:'I lost my bag.', cn:'我的包丢了。', why:'lost 是 lose 的过去式,说已经发生的事用过去式。'}, {who:'B', en:'Do not worry. Let us find it.', cn:'别担心。我们一起找。', why:'Do not worry 是安慰别人的常用语。'}, ]}, ]; /* ================================================================== 语音进阶:音节 → 重音 → 连读 → 弱读 → 语调(阶梯加深) ================================================================== */ const advData = [ {title:'① 数音节 & 音节的秘密', lv:1, intro:'英语单词由"音节"组成。一个音节里通常有一个元音。数清楚音节,才能读得准、拼得对。', rules:[ '每个音节至少有一个元音字母(a e i o u)。', '读单词时在音节之间轻轻断开,别一口气连成一片。', '元音字母有"本音"(长音)和"短音"两种读法,靠音节结构决定。' ], ex:[ {en:'cat (1 音节)', ipa:'/kæt/', cn:'猫 — 短元音,一口气读完', why:'只有一个元音 a,读短音 /æ/。'}, {en:'rabbit (2 音节)', ipa:'/ˈræb.ɪt/', cn:'兔子 — rab-bit', why:'两个元音 a、i,两个音节,重音在前。'}, {en:'banana (3 音节)', ipa:'/bə.ˈnɑː.nə/', cn:'香蕉 — ba-na-na', why:'三个元音,重音在中间 na。'}, {en:'elephant (3 音节)', ipa:'/ˈel.ɪ.fənt/', cn:'大象 — el-e-phant', why:'重音在最前面的 el。'} ]}, {title:'② 开音节 · 闭音节 · 魔法 e', lv:2, intro:'这是自然拼读的核心规则!掌握它,见到新单词就能猜出发音。', rules:[ '闭音节 = 元音后面被辅音"关住",元音读短音:cat /æ/、pet /e/、sit /ɪ/、hot /ɒ/、cut /ʌ/。', '开音节 = 元音结尾或"元音+辅音+e",元音读字母本音(长音):cake /eɪ/、bike /aɪ/、note /əʊ/。', '魔法 e 规则:词尾不发音的 e 会让前面的元音"变长"——cap → cape,bit → bite,hop → hope。' ], ex:[ {en:'cap → cape', ipa:'/kæp/ → /keɪp/', cn:'帽子 → 披风', why:'加了 e,a 从短音 /æ/ 变长音 /eɪ/。'}, {en:'bit → bite', ipa:'/bɪt/ → /baɪt/', cn:'一点 → 咬', why:'魔法 e 让 i 读字母本音 /aɪ/。'}, {en:'hop → hope', ipa:'/hɒp/ → /həʊp/', cn:'单脚跳 → 希望', why:'o 从 /ɒ/ 变成 /əʊ/。'}, {en:'not → note', ipa:'/nɒt/ → /nəʊt/', cn:'不 → 笔记', why:'同样的魔法 e 规则。'} ]}, {title:'③ 单词重音', lv:3, intro:'每个多音节单词都有一个"重音音节",读得又响又长。重音读错,美国人就听不懂了。', rules:[ '两个音节的词,重音大多在第一个:TA-ble、MON-key、TEACHer。', '名词/形容词重音常在前,动词重音常在后:REcord(名词) / reCORD(动词)。', '重音音节的元音要清楚饱满,非重读音节的元音常弱化成 /ə/(轻声"呃")。' ], ex:[ {en:'TA-ble', ipa:'/ˈteɪbl/', cn:'桌子', why:'重音在第一音节,读得响亮。'}, {en:'ba-NA-na', ipa:'/bəˈnɑːnə/', cn:'香蕉', why:'重音在中间,前后弱读。'}, {en:'com-PU-ter', ipa:'/kəmˈpjuːtə/', cn:'电脑', why:'重音在第二音节。'}, {en:'UM-bre-lla', ipa:'/ʌmˈbrelə/', cn:'雨伞', why:'重音在中间 bre。'} ]}, {title:'④ 连读 Linking', lv:3, intro:'美国人说话像"连珠炮",因为相邻单词的音会连在一起。学会连读,听力立刻提升一大截!', rules:[ '辅音 + 元音连读:前一个词以辅音结尾,后一个词以元音开头,就连起来读。', 'Turn it off 听起来像 "tur-ni-toff"。', '同一个音相遇只读一次:bus stop → "bu-stop"。' ], ex:[ {en:'Take it easy.', ipa:'/teɪ-ki-tiːzi/', cn:'放轻松。', why:'take 的 k 与 it 连读,it 的 t 与 easy 连读。'}, {en:'Turn it off.', ipa:'/tɜːr-nɪ-tɒf/', cn:'把它关掉。', why:'三个词连成一串,几乎分不开。'}, {en:'an apple', ipa:'/ə-ˈnæpl/', cn:'一个苹果', why:'n 和后面的元音连读。'}, {en:'Not at all.', ipa:'/nɒ-tə-tɔːl/', cn:'一点也不。', why:'t 在元音间变成轻快的闪音。'} ]}, {title:'⑤ 弱读 & 缩读', lv:4, intro:'英语里很多小词(a, the, and, to, for, of)在句子里会"轻读",甚至缩成一个音。这就是为什么听不懂他们说话。', rules:[ '弱读:and → /ən/,to → /tə/,for → /fə/,of → /əv/,a → /ə/。', '缩读(口语常用):I am → Im,do not → dont,cannot → cant,want to → wanna,going to → gonna。', '缩读多用于口语,正式写作还是要写完整形式。' ], ex:[ {en:'I want to go.', ipa:'/aɪ wɒnə ɡəʊ/', cn:'我想去。', why:'want to 口语连成 wanna。'}, {en:'I am going to play.', ipa:'/aɪm ɡənə pleɪ/', cn:'我要去玩。', why:'going to 口语常说 gonna。'}, {en:'Do not worry.', ipa:'/dəʊnt ˈwʌri/', cn:'别担心。', why:'Do not 缩成 dont。'}, {en:'bread and butter', ipa:'/bred ən ˈbʌtə/', cn:'面包黄油', why:'and 弱读成 /ən/。'} ]}, {title:'⑥ 句子语调', lv:4, intro:'同样一句话,语调不同意思就不同。这是"说得地道"的最后一块拼图。', rules:[ '陈述句:语调下降 ↘,句尾落下来。', '一般疑问句(Yes/No 问句):语调上扬 ↗。', '特殊疑问句(What/Where 开头):语调下降 ↘。', '列举、选择疑问句:前面几项上扬,最后一项下降。' ], ex:[ {en:'I like apples. ↘', ipa:'', cn:'我喜欢苹果。', why:'陈述句,末尾降调。'}, {en:'Do you like apples? ↗', ipa:'', cn:'你喜欢苹果吗?', why:'一般疑问句,末尾升调。'}, {en:'What is your name? ↘', ipa:'', cn:'你叫什么名字?', why:'特殊疑问句,末尾降调。'}, {en:'Do you want tea ↗ or coffee? ↘', ipa:'', cn:'你要茶还是咖啡?', why:'选择疑问句,前升后降。'} ]} ]; /* ================================================================== 教材同步:核心语法(美国小学 Grammer) ================================================================== */ const grammarData = [ {point:'be 动词 am / is / are', lv:1, rule:'我用 am,你用 are,is 连着 he / she / it;复数名词全用 are。', ex:[ {en:'I am a student.', cn:'我是学生。', why:'主语 I 用 am。'}, {en:'She is my sister.', cn:'她是我姐姐。', why:'she 用 is。'}, {en:'They are happy.', cn:'他们很开心。', why:'复数用 are。'} ]}, {point:'a / an / the', lv:1, rule:'a 用在辅音音素开头的词前,an 用在元音音素开头的词前;the 表示特指。', ex:[ {en:'a book / an apple', cn:'一本书 / 一个苹果', why:'元音音素前用 an。'}, {en:'an hour', cn:'一小时', why:'hour 的 h 不发音,音素是元音,用 an。'}, {en:'The sun is big.', cn:'太阳很大。', why:'the 指独一无二的事物。'} ]}, {point:'指示代词 this / that / these / those', lv:1, rule:'this/these 指近处,that/those 指远处;单数用 this/that,复数用 these/those。', ex:[ {en:'This is my pen.', cn:'这是我的笔。', why:'近处单数。'}, {en:'Those are birds.', cn:'那些是鸟。', why:'远处复数。'} ]}, {point:'可数与不可数名词', lv:2, rule:'可数名词有单复数,不可数名词(水、米饭、牛奶等)没有复数、不加 a/an。', ex:[ {en:'two apples', cn:'两个苹果', why:'可数名词加 s。'}, {en:'some water', cn:'一些水', why:'不可数用 some,不加 s。'} ]}, {point:'名词复数变化', lv:2, rule:'一般加 -s;以 s/x/ch/sh 结尾加 -es;辅音 letter+y 变 y 为 i 加 -es。', ex:[ {en:'book → books', cn:'书 → 书(复数)', why:'一般加 s。'}, {en:'bus → buses', cn:'公交车 → 复数', why:'s 结尾加 es。'}, {en:'box → boxes', cn:'盒子 → 复数', why:'x 结尾加 es。'}, {en:'baby → babies', cn:'宝宝 → 复数', why:'辅音+y 变 ies。'} ]}, {point:'一般现在时(第三人称单数)', lv:2, rule:'主语是 he / she / it 时,动词要加 -s 或 -es。', ex:[ {en:'He plays football.', cn:'他踢足球。', why:'he 后面 play 加 s。'}, {en:'She goes to school.', cn:'她去上学。', why:'go 加 es。'} ]}, {point:'现在进行时 be + doing', lv:3, rule:'表示"正在做某事":主语 + am/is/are + 动词-ing。', ex:[ {en:'I am reading a book.', cn:'我正在读书。', why:'am + reading。'}, {en:'They are playing.', cn:'他们正在玩。', why:'are + playing。'} ]}, {point:'一般过去时', lv:3, rule:'表示过去发生的事,规则动词加 -ed,不规则动词要单独记(go→went, see→saw)。', ex:[ {en:'I played yesterday.', cn:'我昨天玩了。', why:'规则动词加 ed。'}, {en:'She went home.', cn:'她回家了。', why:'go 的过去式是 went。'} ]}, {point:'情态动词 can / must / should', lv:3, rule:'情态动词后面直接跟动词原形,没有人称变化。', ex:[ {en:'I can swim.', cn:'我会游泳。', why:'can + 动词原形。'}, {en:'You should sleep early.', cn:'你应该早点睡。', why:'should + 动词原形。'} ]}, {point:'人称代词与物主代词', lv:2, rule:'主格作主语(I/you/he),宾格作宾语(me/you/him),形容词性物主代词放名词前(my/your/his)。', ex:[ {en:'I like her.', cn:'我喜欢她。', why:'her 作宾语。'}, {en:'This is my bag.', cn:'这是我的包。', why:'my 放在名词前。'} ]}, {point:'介词 in / on / under / behind', lv:2, rule:'表示位置关系的介词:in 在里面,on 在上面,under 在下面,behind 在后面。', ex:[ {en:'The cat is under the table.', cn:'猫在桌子下面。', why:'under 表示下方。'}, {en:'The book is on the desk.', cn:'书在桌上。', why:'on 表示接触表面。'} ]}, {point:'基本句型:主谓宾 / 主系表', lv:3, rule:'英语句子按"主语 + 谓语 + 其他"的顺序排列,语序和中文不同要注意。', ex:[ {en:'I love English.', cn:'我爱英语。', why:'主 + 谓 + 宾。'}, {en:'She is happy.', cn:'她很高兴。', why:'主 + 系 + 表。'} ]}, ]; /* ================================================================== 教材同步:阅读策略 ================================================================== */ const readingData = [ {name:'🔍 找主旨 Main Idea', lv:1, tip:'读完后问自己:这段话主要讲了什么?通常答案在第一句或最后一句。', ex:[{en:'The sun gives us light and heat. It helps plants grow.', cn:'太阳给我们光和热,帮助植物生长。', why:'第一句就是主旨句:太阳给我们光和热。'}]}, {name:'📋 找细节 Details', lv:1, tip:'细节是支持主旨的小信息:谁、什么时候、在哪里、怎么样。用 5W1H 来提问。', ex:[{en:'Tom has a red bike. He rides it to school every day.', cn:'汤姆有一辆红色自行车,他每天骑车上学。', why:'细节:红色、自行车、每天、上学。'}]}, {name:'🔮 预测 Predicting', lv:2, tip:'读到一半先猜猜接下来会发生什么,用图片和标题帮忙猜。', ex:[{en:'Tom forgot his umbrella...', cn:'汤姆忘了带伞……', why:'看到 forget umbrella,可以预测"他要被雨淋了"。'}]}, {name:'🧩 联系上下文猜词', lv:2, tip:'遇到不认识的词,看前后句子帮忙猜,不用每个词都查字典。', ex:[{en:'The puppy was famished. It had not eaten all day.', cn:'小狗 famished,它一整天没吃东西。', why:'从"一整天没吃东西"猜出 famished = 非常饿。'}]}, {name:'🖼 想象画面 Visualizing', lv:3, tip:'边读边在脑子里"放电影",把文字变成画面,理解更牢。', ex:[{en:'The big yellow sun slowly set behind the green hills.', cn:'大大的黄太阳慢慢落到青山后面。', why:'读到就在脑中画出日落青山的画面。'}]}, {name:'🔁 复述 Retelling', lv:3, tip:'读完用自己的话讲一遍:开头、中间、结尾。能复述就是真读懂了。', ex:[{en:'First..., Then..., Finally...', cn:'首先……然后……最后……', why:'用这三个词把故事串起来复述。'}]}, ]; /* ================================================================== 教材同步:高频词 Sight Words ================================================================== */ const sightWords = [ {w:'the', cn:'这/那(特指)', t:'最常见,读 /ðə/ 或 /ðiː/'}, {w:'and', cn:'和', t:'口语弱读成 /ən/'}, {w:'is', cn:'是', t:'读 /ɪz/'}, {w:'you', cn:'你/你们', t:'读 /juː/'}, {w:'that', cn:'那个', t:'读 /ðæt/'}, {w:'it', cn:'它', t:'读 /ɪt/'}, {w:'he', cn:'他', t:'读 /hiː/'}, {w:'she', cn:'她', t:'读 /ʃiː/'}, {w:'was', cn:'是(is的过去式)', t:'读 /wɒz/'}, {w:'for', cn:'为了/给', t:'弱读成 /fə/'}, {w:'on', cn:'在……上面', t:'读 /ɒn/'}, {w:'are', cn:'是', t:'读 /ɑː/'}, {w:'as', cn:'像/作为', t:'读 /æz/'}, {w:'with', cn:'和……一起', t:'读 /wɪð/'}, {w:'his', cn:'他的', t:'读 /hɪz/'}, {w:'they', cn:'他们', t:'读 /ðeɪ/'}, {w:'I', cn:'我', t:'永远大写'}, {w:'at', cn:'在……', t:'读 /æt/'}, {w:'be', cn:'是/成为', t:'读 /biː/'}, {w:'this', cn:'这个', t:'读 /ðɪs/'}, {w:'have', cn:'有', t:'读 /hæv/'}, {w:'from', cn:'从……来', t:'读 /frɒm/'}, {w:'or', cn:'或者', t:'读 /ɔː/'}, {w:'one', cn:'一', t:'读 /wʌn/'}, {w:'had', cn:'有(have过去式)', t:'读 /hæd/'}, {w:'by', cn:'被/通过', t:'读 /baɪ/'}, {w:'word', cn:'单词', t:'读 /wɜːd/'}, {w:'but', cn:'但是', t:'读 /bʌt/'}, {w:'not', cn:'不', t:'读 /nɒt/'}, {w:'what', cn:'什么', t:'读 /wɒt/'}, {w:'all', cn:'全部', t:'读 /ɔːl/'}, {w:'were', cn:'是(are过去式)', t:'读 /wɜː/'}, {w:'we', cn:'我们', t:'读 /wiː/'}, {w:'when', cn:'什么时候', t:'读 /wen/'}, {w:'your', cn:'你的', t:'读 /jɔː/'}, {w:'can', cn:'能/可以', t:'读 /kæn/'}, {w:'said', cn:'说(say过去式)', t:'读 /sed/'}, {w:'there', cn:'那里', t:'读 /ðeə/'}, {w:'use', cn:'使用', t:'读 /juːz/'}, {w:'an', cn:'一个', t:'元音前用'}, {w:'each', cn:'每一个', t:'读 /iːtʃ/'}, {w:'which', cn:'哪一个', t:'读 /wɪtʃ/'}, {w:'do', cn:'做', t:'读 /duː/'}, {w:'how', cn:'怎样', t:'读 /haʊ/'}, {w:'their', cn:'他们的', t:'读 /ðeə/'}, {w:'if', cn:'如果', t:'读 /ɪf/'}, {w:'will', cn:'将要', t:'读 /wɪl/'}, {w:'up', cn:'向上', t:'读 /ʌp/'}, {w:'other', cn:'其他的', t:'读 /ˈʌðə/'}, {w:'about', cn:'关于', t:'读 /əˈbaʊt/'}, {w:'out', cn:'外面', t:'读 /aʊt/'}, {w:'many', cn:'许多', t:'读 /ˈmeni/'}, {w:'then', cn:'然后', t:'读 /ðen/'}, {w:'them', cn:'他们(宾格)', t:'读 /ðem/'}, {w:'these', cn:'这些', t:'读 /ðiːz/'}, {w:'so', cn:'所以/如此', t:'读 /səʊ/'}, {w:'some', cn:'一些', t:'读 /sʌm/'}, {w:'her', cn:'她的/她(宾格)', t:'读 /hɜː/'}, {w:'would', cn:'会/愿意', t:'读 /wʊd/'}, {w:'make', cn:'制作', t:'读 /meɪk/'}, {w:'like', cn:'喜欢/像', t:'读 /laɪk/'}, {w:'him', cn:'他(宾格)', t:'读 /hɪm/'}, {w:'into', cn:'进入', t:'读 /ˈɪntə/'}, {w:'time', cn:'时间', t:'读 /taɪm/'}, {w:'has', cn:'有(have三单)', t:'读 /hæz/'}, ]; /* ================================================================== 生活用语:8 大真实场景 ================================================================== */ const lifeGroups = [ {id:'l-morning', name:'⏰ 起床与早晨', tip:'早上和家人的日常对话,简短又高频。', lines:[ {en:'Wake up! It is time to get up.', cn:'醒醒!该起床了。', why:'叫孩子起床的固定说法,get up = 起床。'}, {en:'Good morning, Mom.', cn:'早上好,妈妈。', why:'见家人先问候,很有礼貌。'}, {en:'I am still sleepy.', cn:'我还是很困。', why:'sleepy 表示"困倦的",feel sleepy 更常用。'}, {en:'Hurry up, or we will be late.', cn:'快点,不然我们要迟到了。', why:'or 表示"否则",后面接结果。'}, {en:'I am brushing my teeth.', cn:'我正在刷牙。', why:'现在进行时,表示正在做的动作。'}, ]}, {id:'l-classroom', name:'🏫 教室内', tip:'课堂上向老师提问、请假的常用语。', lines:[ {en:'May I go to the bathroom?', cn:'我可以去洗手间吗?', why:'May I...? 是课堂请求最礼貌的表达。'}, {en:'I do not understand. Could you repeat that?', cn:'我没听懂,你能再说一遍吗?', why:'没听懂时大胆说出来,老师会帮助你。'}, {en:'How do you spell it?', cn:'它怎么拼写?', why:'spell 表示"拼写",学新词时常用。'}, {en:'Can I borrow your eraser?', cn:'我能借你的橡皮吗?', why:'borrow 表示"借入",借出用 lend。'}, {en:'Here, let me help you.', cn:'来,我来帮你。', why:'Let me... 表示主动帮忙。'}, ]}, {id:'l-lunch', name:'🍱 食堂与零食', tip:'在学校吃饭时和同学、阿姨的对话。', lines:[ {en:'It is lunch time! I am starving.', cn:'到午饭时间了!我饿死了。', why:'starving 比 hungry 程度更深,口语很常用。'}, {en:'What is for lunch today?', cn:'今天午饭吃什么?', why:'What is for lunch? 问午餐内容。'}, {en:'Can I have more rice, please?', cn:'我能再要一些米饭吗?', why:'Can I have..., please? 是加餐的礼貌说法。'}, {en:'Yuck! I do not like carrots.', cn:'咦!我不喜欢胡萝卜。', why:'Yuck 表示"好恶心",表达厌恶。'}, {en:'It tastes so good!', cn:'太好吃了!', why:'taste + 形容词,表示"尝起来……"。'}, ]}, {id:'l-afterschool', name:'🎒 放学与玩耍', tip:'放学后和小伙伴约玩、告别的话。', lines:[ {en:'See you tomorrow!', cn:'明天见!', why:'最常用的道别语。'}, {en:'Do you want to play with me?', cn:'你想和我一起玩吗?', why:'Want to 口语常缩成 wanna。'}, {en:'Let us go to the playground.', cn:'我们去操场吧。', why:'Let us 后接动词原形,提建议。'}, {en:'It is my turn!', cn:'轮到我了!', why:'take turns 表示"轮流",玩游戏常用。'}, {en:'That is not fair!', cn:'那不公平!', why:'fair 表示"公平的",小朋友常挂在嘴边。'}, ]}, {id:'l-chores', name:'🧹 家务与帮忙', tip:'在家帮父母做事时的对话,学会能显懂事。', lines:[ {en:'Can you help me set the table?', cn:'你能帮我摆餐具吗?', why:'set the table 是固定搭配,摆好餐具。'}, {en:'Sure, I will do it right away.', cn:'当然,我马上做。', why:'right away 表示"立刻、马上"。'}, {en:'Please put your toys away.', cn:'请把你的玩具收起来。', why:'put away 表示"收拾好"。'}, {en:'I am cleaning my room.', cn:'我在打扫我的房间。', why:'clean the room 打扫房间。'}, {en:'Good job! Thank you for helping.', cn:'做得好!谢谢你帮忙。', why:'Good job 是夸奖别人做得好。'}, ]}, {id:'l-feelings', name:'😊 情绪与感受', tip:'表达开心、难过、害怕、生气的英语说法。', lines:[ {en:'I am so happy today!', cn:'我今天好开心!', why:'so + 形容词,加强语气。'}, {en:'I feel sad.', cn:'我觉得难过。', why:'feel + 情绪形容词,I feel... 很常用。'}, {en:'I am a little scared.', cn:'我有点害怕。', why:'a little 表示"一点点",缓和语气。'}, {en:'I am angry with you.', cn:'我生你的气了。', why:'be angry with sb 对某人生气。'}, {en:'Do not be afraid. I am here.', cn:'别怕,我在这儿。', why:'Do not be + 形容词,安慰别人。'}, ]}, {id:'l-restaurant', name:'🍽 餐厅点餐', tip:'和家长去餐厅时可以用上的点餐英语。', lines:[ {en:'A table for two, please.', cn:'两位,谢谢。', why:'进餐厅第一句,说明人数。'}, {en:'May I have the menu?', cn:'请给我菜单好吗?', why:'May I have...? 点餐、要东西的礼貌句型。'}, {en:'I would like a hamburger.', cn:'我想要一个汉堡。', why:'I would like 比 I want 更礼貌,口语常缩读 Id like。'}, {en:'Can I have some juice?', cn:'我能要些果汁吗?', why:'Can I have...? 请求句型。'}, {en:'Check, please.', cn:'买单,谢谢。', why:'结账时说 Check, please,简洁正式。'}, ]}, {id:'l-weekend', name:'🎡 周末与爱好', tip:'聊周末计划和爱好的英语,交朋友必备。', lines:[ {en:'What do you do on weekends?', cn:'你周末做什么?', why:'问对方周末活动,聊天好开头。'}, {en:'I like playing soccer.', cn:'我喜欢踢足球。', why:'like + doing,表示喜欢长期爱好。'}, {en:'Let us go to the park!', cn:'我们去公园吧!', why:'Let us 提建议,语气轻松。'}, {en:'I watch cartoons on Saturday.', cn:'我周六看动画片。', why:'on + 星期几,表示在周几。'}, {en:'That sounds fun!', cn:'听起来很有趣!', why:'That sounds + 形容词,回应别人的提议。'}, ]}, ]; /* ================================================================== 儿歌:15 首美国 7-10 岁经典传统儿歌(公版) ================================================================== */ const songData = [ {id:'sg-abcd', title:'The Alphabet Song', cn:'字母歌', tip:'几乎所有美国孩子学会的第一首歌,用来记 26 个字母。', lines:[ {en:'A B C D E F G,', cn:'A B C D E F G,', note:'跟着字母本身读音唱。'}, {en:'H I J K L M N O P,', cn:'H I J K L M N O P,', note:'一口气连唱 9 个字母。'}, {en:'Q R S, T U V,', cn:'Q R S,T U V,', note:'Q R S 连在一起唱更快。'}, {en:'W X, Y and Z.', cn:'W X,Y 和 Z。', note:'W 读 "double-u"。'}, {en:'Now I know my ABC,', cn:'现在我会我的 ABC 了,', note:'这是歌曲的固定收尾句。'}, {en:'Next time will you sing with me?', cn:'下次你要和我一起唱吗?', note:'以疑问收尾,邀请一起唱。'} ], vocab:[ {w:'alphabet', t:'字母表 /ˈælfəbet/'}, {w:'letter', t:'字母 /ˈletə/'}, {w:'next time', t:'下次 /nekst taɪm/'}, {w:'sing', t:'唱歌 /sɪŋ/'} ], grammar:'Now I know... 用一般现在时表示"现在会了";Next time will you...? 是邀请句型。'}, {id:'sg-baabaa', title:'Baa Baa Black Sheep', cn:'咩咩黑绵羊', tip:'经典童谣,重复的 "Baa Baa" 模仿羊叫,非常适合练发音。', lines:[ {en:'Baa, baa, black sheep,', cn:'咩,咩,黑绵羊,', note:'Baa 模仿羊的叫声。'}, {en:'Have you any wool?', cn:'你有羊毛吗?', note:'Have you any...? 是英式问"你有……吗"。'}, {en:'Yes, sir. Yes, sir,', cn:'有的,先生。有的,先生,', note:'重复表示肯定,很押韵。'}, {en:'Three bags full.', cn:'满满三袋。', note:'three bags full 押韵、好记。'}, {en:'One for my master,', cn:'一袋给我的主人,', note:'master 指主人。'}, {en:'One for my dame,', cn:'一袋给我的女主人,', note:'dame 是古英语的"女主人"。'}, {en:'And one for the little boy', cn:'还有一袋给那个小男孩,', note:'little 表示"小的"。'}, {en:'Who lives down the lane.', cn:'他住在小巷那头。', note:'lane 小巷,押韵词。'} ], vocab:[ {w:'sheep', t:'绵羊 /ʃiːp/'}, {w:'wool', t:'羊毛 /wʊl/'}, {w:'bag', t:'袋子 /bæɡ/'}, {w:'lane', t:'小巷 /leɪn/'} ], grammar:'Have you any wool? 是疑问句;One for... 用 for 表示"给……"。'}, {id:'sg-twinkle', title:'Twinkle, Twinkle, Little Star', cn:'一闪一闪小星星', tip:'旋律最熟悉的英文儿歌,注意 twinkle 和 star 的重复。', lines:[ {en:'Twinkle, twinkle, little star,', cn:'一闪一闪小星星,', note:'twinkle 表示"闪烁"。'}, {en:'How I wonder what you are.', cn:'我多想知道你是什么。', note:'How I wonder 表示"我多么好奇"。'}, {en:'Up above the world so high,', cn:'高高挂在世界之上,', note:'up above 表示"在……上方"。'}, {en:'Like a diamond in the sky.', cn:'像天空中的钻石。', note:'like 表示"像",是比喻。'}, {en:'Twinkle, twinkle, little star,', cn:'一闪一闪小星星,', note:'重复第一句,形成呼应。'}, {en:'How I wonder what you are.', cn:'我多想知道你是什么。', note:'整首歌首尾重复。'} ], vocab:[ {w:'twinkle', t:'闪烁 /ˈtwɪŋkl/'}, {w:'wonder', t:'想知道 /ˈwʌndə/'}, {w:'above', t:'在……上方 /əˈbʌv/'}, {w:'diamond', t:'钻石 /ˈdaɪəmənd/'} ], grammar:'How I wonder... 是感叹句;Like a diamond 用 like 作比喻,表示"像"。'}, {id:'sg-happy', title:'If You are Happy and You Know It', cn:'如果感到幸福你就拍拍手', tip:'动作儿歌,边唱边做动作,学身体和动作词。', lines:[ {en:'If you are happy and you know it, clap your hands!', cn:'如果感到幸福你就拍拍手!', note:'If 引导条件句,clap 拍手。'}, {en:'If you are happy and you know it, stomp your feet!', cn:'如果感到幸福你就跺跺脚!', note:'stomp your feet 跺脚。'}, {en:'If you are happy and you know it, shout "Hooray!"', cn:'如果感到幸福你就欢呼!', note:'shout 喊叫,Hooray 万岁。'}, {en:'If you are happy and you know it, do all three!', cn:'如果感到幸福三个一起做!', note:'all three 指前面三个动作。'} ], vocab:[ {w:'happy', t:'开心的 /ˈhæpi/'}, {w:'clap', t:'拍手 /klæp/'}, {w:'stomp', t:'跺脚 /stɒmp/'}, {w:'shout', t:'喊叫 /ʃaʊt/'} ], grammar:'If you..., do... 是"如果……就……"的条件句型,是英语最基础的句型之一。'}, {id:'sg-head', title:'Head, Shoulders, Knees and Toes', cn:'头、肩、膝、脚趾', tip:'学身体部位的超快口诀,越唱越快很好玩。', lines:[ {en:'Head, shoulders, knees and toes, knees and toes.', cn:'头、肩、膝、脚趾,膝、脚趾。', note:'依次指身体部位。'}, {en:'Head, shoulders, knees and toes, knees and toes.', cn:'头、肩、膝、脚趾,膝、脚趾。', note:'重复,速度加快。'}, {en:'And eyes and ears and mouth and nose.', cn:'还有眼睛、耳朵、嘴巴和鼻子。', note:'继续补充五官。'}, {en:'Head, shoulders, knees and toes, knees and toes.', cn:'头、肩、膝、脚趾,膝、脚趾。', note:'首尾呼应。'} ], vocab:[ {w:'head', t:'头 /hed/'}, {w:'shoulder', t:'肩膀 /ˈʃəʊldə/'}, {w:'knee', t:'膝盖 /niː/(k不发音)'}, {w:'toe', t:'脚趾 /təʊ/'} ], grammar:'用 and 连接一串名词,是列举的基本用法。'}, {id:'sg-wheel', title:'The Wheels on the Bus', cn:'公共汽车上的轮子', tip:'学交通工具和动作声音,唱起来像真的坐车。', lines:[ {en:'The wheels on the bus go round and round,', cn:'公共汽车上的轮子转呀转,', note:'wheels 轮子,round and round 转圈。'}, {en:'Round and round, round and round.', cn:'转呀转,转呀转。', note:'重复增强节奏感。'}, {en:'The wheels on the bus go round and round,', cn:'公共汽车上的轮子转呀转,', note:'重复主句。'}, {en:'All through the town.', cn:'穿过整个小镇。', note:'all through 表示"遍及全程"。'}, {en:'The horn on the bus goes beep, beep, beep.', cn:'公共汽车上的喇叭哔哔哔,', note:'horn 喇叭,beep 嘟嘟声。'}, {en:'The babies on the bus go wah, wah, wah.', cn:'车上的宝宝哇哇哇,', note:'wah 模仿哭声。'} ], vocab:[ {w:'wheel', t:'轮子 /wiːl/'}, {w:'bus', t:'公共汽车 /bʌs/'}, {w:'horn', t:'喇叭 /hɔːn/'}, {w:'town', t:'城镇 /taʊn/'} ], grammar:'The + 名词 + on the bus + go...,用一般现在时描述常见现象。'}, {id:'sg-oldmac', title:'Old MacDonald Had a Farm', cn:'老麦克唐纳有个农场', tip:'学动物叫声的经典歌,每种动物换一种叫声。', lines:[ {en:'Old MacDonald had a farm, E-I-E-I-O!', cn:'老麦克唐纳有个农场,咿呀咿呀哟!', note:'E-I-E-I-O 是拟声词。'}, {en:'And on his farm he had a cow, E-I-E-I-O!', cn:'他的农场里有头牛,咿呀咿呀哟!', note:'he had 表示"他有",过去式。'}, {en:'With a moo moo here and a moo moo there,', cn:'这里哞哞,那里哞哞,', note:'moo 是牛的叫声。'}, {en:'Here a moo, there a moo, everywhere a moo moo.', cn:'这里哞,那里哞,到处都哞哞。', note:'here/there/everywhere 方位词。'}, {en:'Old MacDonald had a farm, E-I-E-I-O!', cn:'老麦克唐纳有个农场,咿呀咿呀哟!', note:'副歌重复。'} ], vocab:[ {w:'farm', t:'农场 /fɑːm/'}, {w:'cow', t:'奶牛 /kaʊ/'}, {w:'everywhere', t:'到处 /ˈevriweə/'}, {w:'moo', t:'哞(牛叫)/muː/'} ], grammar:'had 是 have 的过去式;on his farm / on the farm 用介词 on。'}, {id:'sg-mary', title:'Mary Had a Little Lamb', cn:'玛丽有只小羊羔', tip:'简单押韵,学会 lamb 和 snow 的地道读法(b 不发音)。', lines:[ {en:'Mary had a little lamb,', cn:'玛丽有只小羊羔,', note:'lamb 中的 b 不发音,读 /læm/。'}, {en:'Its fleece was white as snow.', cn:'它的毛像雪一样白。', note:'as...as 表示"和……一样"。'}, {en:'And everywhere that Mary went,', cn:'不管玛丽走到哪里,', note:'everywhere that 表示"无论到哪里"。'}, {en:'The lamb was sure to go.', cn:'小羊都一定会跟去。', note:'be sure to 表示"一定"。'}, {en:'It followed her to school one day,', cn:'有一天它跟着她去了学校,', note:'followed 跟随,过去式。'}, {en:'Which was against the rule.', cn:'这是违反规定的。', note:'against the rule 违反规定。'} ], vocab:[ {w:'lamb', t:'小羊 /læm/(b不发音)'}, {w:'fleece', t:'羊毛 /fliːs/'}, {w:'snow', t:'雪 /snəʊ/'}, {w:'rule', t:'规则 /ruːl/'} ], grammar:'white as snow 是 as...as 的同级比较;had 是过去式,整首歌讲过去发生的事。'}, {id:'sg-london', title:'London Bridge Is Falling Down', cn:'伦敦桥要倒了', tip:'节奏感强的传统歌,配合游戏边唱边钻拱桥。', lines:[ {en:'London Bridge is falling down,', cn:'伦敦桥要倒了,', note:'fall down 表示"倒塌"。'}, {en:'Falling down, falling down.', cn:'要倒了,要倒了。', note:'重复,营造节奏。'}, {en:'London Bridge is falling down,', cn:'伦敦桥要倒了,', note:'重复主句。'}, {en:'My fair lady.', cn:'我美丽的女士。', note:'fair lady 美丽的女士。'}, {en:'Build it up with wood and clay,', cn:'用木头和泥土把它建起来,', note:'build up 建造,wood/clay 材料。'} ], vocab:[ {w:'bridge', t:'桥 /brɪdʒ/'}, {w:'fall', t:'倒塌 /fɔːl/'}, {w:'wood', t:'木头 /wʊd/'}, {w:'clay', t:'黏土 /kleɪ/'} ], grammar:'is falling 是现在进行时,表示"正在倒塌"。'}, {id:'sg-hokey', title:'The Hokey Pokey', cn:'霍基波基舞', tip:'经典律动歌,学 in/out、left/right 等方位和身体词。', lines:[ {en:'You put your right hand in,', cn:'把你的右手放进去,', note:'put...in 放进去。'}, {en:'You put your right hand out.', cn:'把你的右手放出来。', note:'out 与 in 相对。'}, {en:'You put your right hand in,', cn:'把你的右手放进去,', note:'再次重复。'}, {en:'And you shake it all about.', cn:'然后把它摇来摇去。', note:'shake 摇动,all about 到处。'}, {en:'You do the hokey pokey', cn:'你做霍基波基,', note:'hokey pokey 舞蹈名。'}, {en:'And you turn yourself around.', cn:'然后自己转个圈。', note:'turn around 转身。'}, {en:'That is what it is all about!', cn:'这就是全部的意义!', note:'收尾固定句。'} ], vocab:[ {w:'right', t:'右 /raɪt/'}, {w:'shake', t:'摇动 /ʃeɪk/'}, {w:'turn around', t:'转身 /tɜːn əˈraʊnd/'}, {w:'about', t:'到处 /əˈbaʊt/'} ], grammar:'You put... 是祈使句,表示指令;in/out 是相反方向的介词。'}, {id:'sg-rain', title:'Rain, Rain, Go Away', cn:'雨啊雨啊快走开', tip:'超短的一首,练 /eɪ/ 韵脚(rain, away, play, day)。', lines:[ {en:'Rain, rain, go away,', cn:'雨啊,雨啊,快走开,', note:'go away 走开。'}, {en:'Come again another day.', cn:'改天再来。', note:'another day 改天,押 /eɪ/ 韵。'}, {en:'Little children want to play.', cn:'小孩子们想去玩。', note:'want to 口语常读 wanna。'}, {en:'Rain, rain, go away.', cn:'雨啊,雨啊,快走开。', note:'首尾重复。'} ], vocab:[ {w:'rain', t:'雨 /reɪn/'}, {w:'away', t:'离开 /əˈweɪ/'}, {w:'another', t:'另一个 /əˈnʌðə/'}, {w:'children', t:'孩子们 /ˈtʃɪldrən/'} ], grammar:'Go away 是祈使句;want to play 中 want 后接不定式 to play。'}, {id:'sg-spider', title:'Itsy Bitsy Spider', cn:'小小蜘蛛', tip:'练 /ɪ/ 和动作词,讲蜘蛛爬水管的故事。', lines:[ {en:'The itsy bitsy spider went up the water spout.', cn:'小小蜘蛛爬上了水管。', note:'itsy bitsy 表示"小小的",went up 爬上去。'}, {en:'Down came the rain and washed the spider out.', cn:'雨下下来了,把蜘蛛冲了出来。', note:'倒装句:Down came the rain。'}, {en:'Out came the sun and dried up all the rain.', cn:'太阳出来了,晒干了所有的雨。', note:'Out came the sun 也是倒装。'}, {en:'And the itsy bitsy spider went up the spout again.', cn:'小小蜘蛛又爬上了水管。', note:'again 再次。'} ], vocab:[ {w:'spider', t:'蜘蛛 /ˈspaɪdə/'}, {w:'spout', t:'水管 /spaʊt/'}, {w:'wash', t:'冲洗 /wɒʃ/'}, {w:'dry', t:'弄干 /draɪ/'} ], grammar:'Down came the rain = The rain came down,这是强调方位的倒装用法。'}, {id:'sg-jingle', title:'Jingle Bells', cn:'铃儿响叮当', tip:'最著名的冬季节日歌,学 sleigh、bell、snow 等词。', lines:[ {en:'Jingle bells, jingle bells,', cn:'叮叮当,叮叮当,', note:'jingle 叮当响。'}, {en:'Jingle all the way.', cn:'一路叮当响。', note:'all the way 一路。'}, {en:'Oh what fun it is to ride', cn:'哦,坐着多有趣啊,', note:'What fun it is to... 感叹句型。'}, {en:'In a one-horse open sleigh, hey!', cn:'坐在单马敞篷雪橇上,嗨!', note:'sleigh 雪橇,one-horse 单匹马的。'}, {en:'Dashing through the snow,', cn:'冲过雪地,', note:'dash 冲、飞驰。'}, {en:'In a one-horse open sleigh.', cn:'坐在单马敞篷雪橇上。', note:'in a + 交通工具,表示乘坐。'} ], vocab:[ {w:'jingle', t:'叮当响 /ˈdʒɪŋɡl/'}, {w:'sleigh', t:'雪橇 /sleɪ/'}, {w:'dash', t:'飞驰 /dæʃ/'}, {w:'snow', t:'雪 /snəʊ/'} ], grammar:'How fun it is to + 动词,是感叹句型;in a sleigh 用 in 表示乘坐。'}, {id:'sg-birthday', title:'Happy Birthday to You', cn:'生日快乐歌', tip:'全世界唱得最多的英文歌,句式非常简单。', lines:[ {en:'Happy birthday to you,', cn:'祝你生日快乐,', note:'to you 表示"给你/对你"。'}, {en:'Happy birthday to you,', cn:'祝你生日快乐,', note:'重复第一句。'}, {en:'Happy birthday, dear friend,', cn:'生日快乐,亲爱的朋友,', note:'dear friend 亲爱的朋友。'}, {en:'Happy birthday to you!', cn:'祝你生日快乐!', note:'以同一句收尾。'} ], vocab:[ {w:'birthday', t:'生日 /ˈbɜːθdeɪ/'}, {w:'happy', t:'快乐的 /ˈhæpi/'}, {w:'dear', t:'亲爱的 /dɪə/'}, {w:'friend', t:'朋友 /frend/'} ], grammar:'Happy birthday to you 是省略句,完整是 I wish you a happy birthday。'}, {id:'sg-row', title:'Row, Row, Row Your Boat', cn:'划呀划呀划小船', tip:'旋律优美的经典歌,学 row、stream、merrily 等词。', lines:[ {en:'Row, row, row your boat,', cn:'划呀划呀划小船,', note:'row 划船,repeat 三遍。'}, {en:'Gently down the stream.', cn:'轻轻顺流而下。', note:'gently 轻轻地,stream 小溪。'}, {en:'Merrily, merrily, merrily, merrily,', cn:'快乐地,快乐地,快乐地,快乐地,', note:'merrily 快乐地,连说四遍。'}, {en:'Life is but a dream.', cn:'人生不过是一场梦。', note:'but 在这里是"只是",古诗歌用法。'} ], vocab:[ {w:'row', t:'划船 /rəʊ/'}, {w:'stream', t:'小溪 /striːm/'}, {w:'merrily', t:'快乐地 /ˈmerəli/'}, {w:'dream', t:'梦 /driːm/'} ], grammar:'Life is but a dream 中 but = only(只是),是古典诗歌用法。'} ]; /* 音标总数量(用于进度条) */ const TOTAL_UNITS = shortVowels.length + longVowels.length + diphthongs.length + voiceless.length + voiced.length + letterSounds.length + blends.length + combos.length + vocabGroups.reduce((a,g)=>a+g.words.length,0) + sentenceGroups.reduce((a,g)=>a+g.lines.length,0) + talkGroups.reduce((a,g)=>a+g.lines.length,0) + advData.reduce((a,x)=>a+x.ex.length,0) + grammarData.reduce((a,x)=>a+x.ex.length,0) + readingData.length + sightWords.length + lifeGroups.reduce((a,g)=>a+g.lines.length,0) + songData.reduce((a,s)=>a+s.lines.length,0); /* ================================================================== 渲染工具 ================================================================== */ function unitCard(item, playText, idKey='id'){ const el = document.createElement('div'); el.className = 'unit' + (progress[item[idKey]]?' learned':''); el.innerHTML = `
✅
${item.sym || item.letter || ''}
${item.ipa || item.sound || ''}
${item.cn}
${item.ex?`
${item.ex}${item.exCn}
`:''} ${item.parts?`
${item.parts.join(' · ')} → ${item.word}
`:''} ${item.combo?`
${item.combo} ${item.sound}
`:''} ${item.tip?`
💡 ${item.tip}${item.words?'
'+item.words.join(' · '):''}
`:''} `; const btn = el.querySelector('.play'); btn.addEventListener('click', e=>{ e.stopPropagation(); playText(); markLearned(item[idKey]); el.classList.add('learned'); }); el.addEventListener('click', ()=>{ playText(); markLearned(item[idKey]); el.classList.add('learned'); }); return el; } function renderUnits(containerId, items, textFn, extraRender){ const box = document.getElementById(containerId); items.forEach(item=>{ box.appendChild(unitCard(item, ()=> textFn(item))); }); if(extraRender) extraRender(box); } /* ================================================================== 各区渲染 ================================================================== */ safe(function(){ renderUnits('shortVowels', shortVowels, it=>it.ex); }); safe(function(){ renderUnits('longVowels', longVowels, it=>it.ex); }); safe(function(){ renderUnits('diphthongs', diphthongs, it=>it.ex); }); safe(function(){ renderUnits('voiceless', voiceless, it=>it.ex); }); safe(function(){ renderUnits('voiced', voiced, it=>it.ex); }); safe(function(){ renderUnits('letterSounds', letterSounds, it=>it.word); }); safe(function(){ renderUnits('blendCards', blends, it=>it.word); }); safe(function(){ renderUnits('comboCards', combos, it=>it.words.join('. ')); }); /* 词汇主题 */ function renderVocab(groupId){ const g = vocabGroups.find(x=>x.id===groupId) || vocabGroups[0]; const body = document.getElementById('vocabBody'); body.innerHTML = ''; const card = document.createElement('div'); card.className = 'card'; card.innerHTML = `

${g.name}

点整行可播放
`; g.words.forEach(w=>{ const row = document.createElement('div'); row.className = 'word-row' + (progress['v_'+g.id+'_'+w.en]?' word-learned':''); row.innerHTML = `
${w.emoji}
${w.en}${w.ipa}
${w.cn}
${w.note?`📝 ${w.note}`:''}
`; const playIt = ()=>{ playText(w.en, row.querySelector('.play-round')); progress['v_'+g.id+'_'+w.en]=1; SafeStore.set(STORE_KEY, JSON.stringify(progress)); row.classList.add('word-learned'); updateProgress(); }; row.querySelector('.play-round').addEventListener('click', e=>{e.stopPropagation();playIt();}); row.addEventListener('click', playIt); card.appendChild(row); }); body.appendChild(card); } function buildVocabNav(){ const nav = document.getElementById('vocabNav'); vocabGroups.forEach((g,i)=>{ const b = document.createElement('button'); b.className='tool-btn'+(i===0?' on':''); b.textContent = g.name; b.onclick = ()=>{ nav.querySelectorAll('.tool-btn').forEach(x=>x.classList.remove('on')); b.classList.add('on'); renderVocab(g.id); }; nav.appendChild(b); }); renderVocab(vocabGroups[0].id); } safe(function(){ buildVocabNav(); }); /* 句子 */ function renderSent(groupId){ const g = sentenceGroups.find(x=>x.id===groupId) || sentenceGroups[0]; const body = document.getElementById('sentBody'); body.innerHTML=''; const card = document.createElement('div'); card.className='card'; card.innerHTML = `

${g.name}

点整句跟读
${g.tip?`
${g.tip}
`:''}`; g.lines.forEach((l,i)=>{ const id = 's_'+g.id+'_'+i; const row = document.createElement('div'); row.className='line'; row.innerHTML = `
${l.en} ${l.cn} ${l.why?`📝 ${l.why}`:''}
`; const playIt = ()=>{ playText(l.en, row.querySelector('.play-round')); progress[id]=1; SafeStore.set(STORE_KEY, JSON.stringify(progress)); updateProgress(); }; row.querySelector('.play-round').addEventListener('click', e=>{e.stopPropagation();playIt();}); row.addEventListener('click', playIt); card.appendChild(row); }); const allBtn = document.createElement('button'); allBtn.className='big-play'; allBtn.textContent='▶ 连续播放整段'; allBtn.onclick = ()=>{ playText(g.lines.map(x=>x.en).join('. '), allBtn); g.lines.forEach((l,i)=>progress['s_'+g.id+'_'+i]=1); SafeStore.set(STORE_KEY, JSON.stringify(progress)); updateProgress(); }; card.appendChild(allBtn); body.appendChild(card); } function buildSentNav(){ const nav = document.getElementById('sentNav'); sentenceGroups.forEach((g,i)=>{ const b=document.createElement('button'); b.className='tool-btn'+(i===0?' on':''); b.textContent=g.name; b.onclick=()=>{ nav.querySelectorAll('.tool-btn').forEach(x=>x.classList.remove('on')); b.classList.add('on'); renderSent(g.id); }; nav.appendChild(b); }); renderSent(sentenceGroups[0].id); } safe(function(){ buildSentNav(); }); /* 对话 */ function renderTalk(groupId){ const g = talkGroups.find(x=>x.id===groupId) || talkGroups[0]; const body = document.getElementById('talkBody'); body.innerHTML=''; const card = document.createElement('div'); card.className='card'; card.innerHTML = `

${g.name}

点每句跟读
${g.tip?`
${g.tip}
`:''}`; g.lines.forEach((l,i)=>{ const id = 't_'+g.id+'_'+i; const row = document.createElement('div'); row.className = 'line' + (l.who==='B'?' right':''); row.innerHTML = `
${l.who}
${l.en} ${l.cn} ${l.why?`📝 ${l.why}`:''}
`; const playIt = ()=>{ playText(l.en, row.querySelector('.play-round')); progress[id]=1; SafeStore.set(STORE_KEY, JSON.stringify(progress)); updateProgress(); }; row.querySelector('.play-round').addEventListener('click', e=>{e.stopPropagation();playIt();}); row.addEventListener('click', playIt); card.appendChild(row); }); const allBtn=document.createElement('button'); allBtn.className='big-play'; allBtn.textContent='▶ 连续播放整段对话'; allBtn.onclick=()=>{ playText(g.lines.map(x=>x.en).join('. '), allBtn); g.lines.forEach((l,i)=>progress['t_'+g.id+'_'+i]=1); SafeStore.set(STORE_KEY, JSON.stringify(progress)); updateProgress(); }; card.appendChild(allBtn); body.appendChild(card); } function buildTalkNav(){ const nav=document.getElementById('talkNav'); talkGroups.forEach((g,i)=>{ const b=document.createElement('button'); b.className='tool-btn'+(i===0?' on':''); b.textContent=g.name; b.onclick=()=>{ nav.querySelectorAll('.tool-btn').forEach(x=>x.classList.remove('on')); b.classList.add('on'); renderTalk(g.id); }; nav.appendChild(b); }); renderTalk(talkGroups[0].id); } safe(function(){ buildTalkNav(); }); /* ================================================================== 语音进阶 渲染 ================================================================== */ function renderAdv(){ const body = document.getElementById('advBody'); body.innerHTML=''; advData.forEach((sec, si)=>{ const card = document.createElement('div'); card.className='card'; const lvClass = sec.lv>=4?'lv4':sec.lv>=3?'lv3':sec.lv>=2?'lv2':''; card.innerHTML = `

${sec.title}难度 ${sec.lv}/4

💡 一句话讲清:${sec.intro}
${sec.rules.map(r=>'• '+r).join('
')}

🎧 例句示范

点 🔊 听
`; sec.ex.forEach(e=>{ const row = document.createElement('div'); row.className='ex-row'; row.innerHTML = `
${e.en}${e.ipa?` ${e.ipa}`:''}
${e.cn}
📝 ${e.why}
`; const id = 'adv_'+si+'_'+e.en; const playIt = ()=>{ playText(e.en, row.querySelector('.play-round'), {slow:true}); progress[id]=1; SafeStore.set(STORE_KEY, JSON.stringify(progress)); updateProgress(); }; row.querySelector('.play-round').addEventListener('click', ev=>{ev.stopPropagation();playIt();}); row.addEventListener('click', playIt); card.appendChild(row); }); body.appendChild(card); }); } safe(function(){ renderAdv(); }); /* ================================================================== 教材同步 渲染(高频词 / 语法 / 阅读) ================================================================== */ function renderText(tabIdx){ const body = document.getElementById('textBody'); body.innerHTML=''; if(tabIdx===0){ const card=document.createElement('div'); card.className='card'; card.innerHTML=`

⭐ 高频词 Sight Words(${sightWords.length} 个)

点一点听发音
高频词是英语里出现最多的词,很多不能靠拼读猜出来,需要"看一眼就认识"。美国孩子每天练,你也试试!
`; const chipWrap=document.createElement('div'); chipWrap.className='chip-grid'; chipWrap.style.marginTop='12px'; sightWords.forEach(sw=>{ const b=document.createElement('button'); b.className='chip'+(progress['sw_'+sw.w]?' learned':''); b.innerHTML=`${sw.w}${sw.cn}${sw.t}`; const playIt=()=>{ playText(sw.w, b); progress['sw_'+sw.w]=1; SafeStore.set(STORE_KEY, JSON.stringify(progress)); b.classList.add('learned'); updateProgress(); }; b.addEventListener('click', playIt); chipWrap.appendChild(b); }); card.appendChild(chipWrap); body.appendChild(card); } else if(tabIdx===1){ grammarData.forEach((g,gi)=>{ const card=document.createElement('div'); card.className='card'; const lvClass = g.lv>=3?'lv3':g.lv>=2?'lv2':''; card.innerHTML=`

${g.point}难度 ${g.lv}/4

${g.rule}
`; g.ex.forEach(e=>{ const row=document.createElement('div'); row.className='ex-row'; row.innerHTML=`
${e.en}
${e.cn}
📝 ${e.why}
`; const id='gr_'+gi+'_'+e.en; const playIt=()=>{ playText(e.en, row.querySelector('.play-round')); progress[id]=1; SafeStore.set(STORE_KEY, JSON.stringify(progress)); updateProgress(); }; row.querySelector('.play-round').addEventListener('click',ev=>{ev.stopPropagation();playIt();}); row.addEventListener('click', playIt); card.appendChild(row); }); body.appendChild(card); }); } else { readingData.forEach((r,ri)=>{ const card=document.createElement('div'); card.className='card'; const lvClass = r.lv>=3?'lv3':r.lv>=2?'lv2':''; card.innerHTML=`

${r.name}难度 ${r.lv}/4

${r.tip}
`; r.ex.forEach(e=>{ const row=document.createElement('div'); row.className='ex-row'; row.innerHTML=`
${e.en}
${e.cn}
📝 ${e.why}
`; const id='rd_'+ri+'_'+e.en; const playIt=()=>{ playText(e.en, row.querySelector('.play-round')); progress[id]=1; SafeStore.set(STORE_KEY, JSON.stringify(progress)); updateProgress(); }; row.querySelector('.play-round').addEventListener('click',ev=>{ev.stopPropagation();playIt();}); row.addEventListener('click', playIt); card.appendChild(row); }); body.appendChild(card); }); } } function buildTextNav(){ const nav=document.getElementById('textNav'); ['⭐ 高频词','🧮 核心语法','🔑 阅读策略'].forEach((name,i)=>{ const b=document.createElement('button'); b.className='tool-btn'+(i===0?' on':''); b.textContent=name; b.onclick=()=>{ nav.querySelectorAll('.tool-btn').forEach(x=>x.classList.remove('on')); b.classList.add('on'); renderText(i); }; nav.appendChild(b); }); renderText(0); } safe(function(){ buildTextNav(); }); /* ================================================================== 生活用语 渲染 ================================================================== */ function renderLife(groupId){ const g = lifeGroups.find(x=>x.id===groupId) || lifeGroups[0]; const body = document.getElementById('lifeBody'); body.innerHTML=''; const card=document.createElement('div'); card.className='card'; card.innerHTML=`

${g.name}

点整句跟读
${g.tip?`
${g.tip}
`:''}`; g.lines.forEach((l,i)=>{ const row=document.createElement('div'); row.className='line'; row.innerHTML=`
${l.en} ${l.cn} 📝 ${l.why}
`; const id='lf_'+g.id+'_'+i; const playIt=()=>{ playText(l.en, row.querySelector('.play-round')); progress[id]=1; SafeStore.set(STORE_KEY, JSON.stringify(progress)); updateProgress(); }; row.querySelector('.play-round').addEventListener('click',ev=>{ev.stopPropagation();playIt();}); row.addEventListener('click', playIt); card.appendChild(row); }); const allBtn=document.createElement('button'); allBtn.className='big-play'; allBtn.textContent='▶ 连续播放整段'; allBtn.onclick=()=>{ playText(g.lines.map(x=>x.en).join('. '), allBtn); g.lines.forEach((l,i)=>progress['lf_'+g.id+'_'+i]=1); SafeStore.set(STORE_KEY, JSON.stringify(progress)); updateProgress(); }; card.appendChild(allBtn); body.appendChild(card); } function buildLifeNav(){ const nav=document.getElementById('lifeNav'); lifeGroups.forEach((g,i)=>{ const b=document.createElement('button'); b.className='tool-btn'+(i===0?' on':''); b.textContent=g.name; b.onclick=()=>{ nav.querySelectorAll('.tool-btn').forEach(x=>x.classList.remove('on')); b.classList.add('on'); renderLife(g.id); }; nav.appendChild(b); }); renderLife(lifeGroups[0].id); } safe(function(){ buildLifeNav(); }); /* ================================================================== 儿歌跟唱 渲染 ================================================================== */ function renderSongs(){ const body=document.getElementById('songBody'); body.innerHTML=''; songData.forEach((song,si)=>{ const card=document.createElement('div'); card.className='card'; card.innerHTML=`

🎵 ${song.title} 《${song.cn}》

${song.tip}

`; const listWrap=document.createElement('div'); song.lines.forEach((l,li)=>{ const row=document.createElement('div'); row.className='sline'; row.innerHTML=`
${l.en}
${l.cn}
${l.note?`
📝 ${l.note}
`:''}
`; const id='sg_'+song.id+'_'+li; const playIt=()=>{ playText(l.en, row.querySelector('.play-round'), {slow:true}); progress[id]=1; SafeStore.set(STORE_KEY, JSON.stringify(progress)); updateProgress(); }; row.querySelector('.play-round').addEventListener('click',ev=>{ev.stopPropagation();playIt();}); row.addEventListener('click', playIt); listWrap.appendChild(row); }); card.appendChild(listWrap); const allBtn=document.createElement('button'); allBtn.className='big-play'; allBtn.textContent='▶ 整首连唱'; allBtn.onclick=()=>{ playText(song.lines.map(x=>x.en).join(' '), allBtn); song.lines.forEach((l,li)=>progress['sg_'+song.id+'_'+li]=1); SafeStore.set(STORE_KEY, JSON.stringify(progress)); updateProgress(); }; card.appendChild(allBtn); const vocabTitle=document.createElement('div'); vocabTitle.className='card-head'; vocabTitle.style.marginTop='14px'; vocabTitle.innerHTML=`

📚 关键词汇

点词听发音`; card.appendChild(vocabTitle); const vg=document.createElement('div'); vg.className='song-vocab'; song.vocab.forEach(v=>{ const item=document.createElement('div'); item.className='sv-item'; item.innerHTML=`
${v.w}
${v.t}
`; item.addEventListener('click', ()=> playText(v.w, null)); vg.appendChild(item); }); card.appendChild(vg); const gr=document.createElement('div'); gr.className='rule'; gr.style.marginTop='12px'; gr.innerHTML=`🔤 句型解析:${song.grammar}`; card.appendChild(gr); body.appendChild(card); }); } safe(function(){ renderSongs(); }); /* ================================================================== 小测验 ================================================================== */ const quizPool = vocabGroups.reduce((a,g)=>a.concat(g.words),[]) ; let quiz = { cur:null, opts:[], score:0, total:0, locked:false }; function newQuestion(){ quiz.locked = false; const word = quizPool[Math.floor(Math.random()*quizPool.length)]; const distractors = quizPool.filter(w=>w.en!==word.en) .sort(()=>Math.random()-0.5).slice(0,3); const opts = [word, ...distractors].sort(()=>Math.random()-0.5); quiz.cur = word; quiz.opts = opts; document.getElementById('quizWord').textContent = '❓ ???'; document.getElementById('quizCn').textContent = '点击 "🔊 播放单词" 听发音'; const optsBox = document.getElementById('quizOpts'); optsBox.innerHTML=''; opts.forEach(o=>{ const b=document.createElement('button'); b.className='opt'; b.textContent=`${o.emoji} ${o.cn}`; b.onclick=()=>{ if(quiz.locked) return; quiz.locked=true; quiz.total++; if(o.en===word.en){ b.classList.add('right'); quiz.score++; progress['quiz_'+word.en]=1; SafeStore.set(STORE_KEY, JSON.stringify(progress)); updateProgress(); setTimeout(newQuestion, 800); }else{ b.classList.add('wrong'); // 高亮正确答案 optsBox.querySelectorAll('.opt').forEach((el,idx)=>{ if(opts[idx].en===word.en) el.classList.add('right'); }); document.getElementById('quizWord').textContent = word.en; setTimeout(()=>{ quiz.locked=false; }, 1200); } document.getElementById('quizScore').textContent = `得分:${quiz.score} / ${quiz.total}`; }; optsBox.appendChild(b); }); document.getElementById('quizRound').textContent = `第 ${quiz.total+1} 题`; } document.getElementById('quizPlay').onclick = function(){ if(quiz.cur) playText(quiz.cur.en, this); }; document.getElementById('quizNext').onclick = newQuestion; safe(function(){ newQuestion(); }); /* ================================================================== Tabs 切换 + 上一步/下一步 ================================================================== */ const tabOrder = ['pplan','p1','p2','p3','padv','p4','ptext','p5','plife','p6','psong','p7']; function switchTab(idx){ idx = Math.max(0, Math.min(tabOrder.length-1, idx)); const id = tabOrder[idx]; document.querySelectorAll('section').forEach(s=>s.classList.remove('show')); document.getElementById(id).classList.add('show'); document.querySelectorAll('.tab').forEach(t=>t.classList.toggle('active', t.dataset.t===id)); window.scrollTo({top:0,behavior:'smooth'}); } document.getElementById('tabs').addEventListener('click', e=>{ const btn = e.target.closest('.tab'); if(!btn) return; switchTab(tabOrder.indexOf(btn.dataset.t)); }); document.getElementById('btnNext').onclick = ()=>{ const cur = tabOrder.findIndex(id=>document.getElementById(id).classList.contains('show')); switchTab(cur+1); }; document.getElementById('btnPrev').onclick = ()=>{ const cur = tabOrder.findIndex(id=>document.getElementById(id).classList.contains('show')); switchTab(cur-1); }; document.getElementById('btnStop').onclick = ()=>VOICE.stop(); /* ================================================================== 发声设置面板 ================================================================== */ document.getElementById('segGender').addEventListener('click', e=>{ const b = e.target.closest('button'); if(!b) return; document.querySelectorAll('#segGender button').forEach(x=>x.classList.remove('on')); b.classList.add('on'); VOICE.gender = b.dataset.g; }); document.getElementById('segAccent').addEventListener('click', e=>{ const b = e.target.closest('button'); if(!b) return; document.querySelectorAll('#segAccent button').forEach(x=>x.classList.remove('on')); b.classList.add('on'); VOICE.accent = b.dataset.a; playText('Hello, I can speak English!', null); }); const rangeSpeed = document.getElementById('rangeSpeed'); rangeSpeed.addEventListener('input', ()=>{ VOICE.rate = parseFloat(rangeSpeed.value); document.getElementById('speedVal').textContent = VOICE.rate.toFixed(2)+'x'; }); document.getElementById('btnVoiceCfg').onclick = ()=>{ const p = document.getElementById('voicePanel'); p.style.display = p.style.display==='none' ? 'block' : 'none'; p.scrollIntoView({behavior:'smooth', block:'nearest'}); }; document.getElementById('btnTestVoice').onclick = ()=>{ VOICE.speak('Hello! This is a voice test. 你好,这是发音测试。', {}); }; /* ================================================================== 学习计划系统(30 / 90 / 180 天) ================================================================== */ const PLAN_KEY = 'kids_english_plan_v1'; let plan = safeParse(SafeStore.get(PLAN_KEY), null); // 课程大纲:按学习顺序排列的模块 const curriculum = [ {id:'p1', name:'元音发音', icon:'🔤', tab:'p1', count:()=>shortVowels.length+longVowels.length+diphthongs.length}, {id:'p3', name:'自然拼读', icon:'🧩', tab:'p3', count:()=>letterSounds.length+blends.length+combos.length}, {id:'padv',name:'语音进阶', icon:'📈', tab:'padv',count:()=>advData.reduce((a,x)=>a+x.ex.length,0)}, {id:'p4', name:'分类词汇', icon:'📚', tab:'p4', count:()=>vocabGroups.reduce((a,g)=>a+g.words.length,0)}, {id:'p5', name:'句型句子', icon:'💬', tab:'p5', count:()=>sentenceGroups.reduce((a,g)=>a+g.lines.length,0)}, {id:'plife',name:'生活用语', icon:'🏡', tab:'plife',count:()=>lifeGroups.reduce((a,g)=>a+g.lines.length,0)}, {id:'p6', name:'日常对话', icon:'👫', tab:'p6', count:()=>talkGroups.reduce((a,g)=>a+g.lines.length,0)}, {id:'psong',name:'儿歌跟唱', icon:'🎵', tab:'psong',count:()=>songData.reduce((a,s)=>a+s.lines.length,0)}, {id:'ptext',name:'教材同步·语法', icon:'🧮', tab:'ptext',count:()=>grammarData.reduce((a,x)=>a+x.ex.length,0)}, {id:'ptext2',name:'教材同步·阅读', icon:'🔑', tab:'ptext',count:()=>readingData.length}, {id:'ptext3',name:'教材同步·高频词',icon:'⭐', tab:'ptext',count:()=>sightWords.length}, ]; const PLANS = { 30:{name:'30 天速成', emoji:'🚀', days:30, modules:['p1','p3','p4','p5'], desc:'每天 20–30 分钟。只学最核心的:音标 → 拼读 → 高频词汇 → 基本句型。适合想快速入门、立刻开口的小朋友。'}, 90:{name:'90 天标准', emoji:'🌟', days:90, modules:['p1','p3','padv','p4','p5','plife','p6'], desc:'每天 15–20 分钟。完整覆盖音标、拼读、语音进阶、词汇、句型、生活用语和对话。节奏舒适,稳步过关。', popular:true}, 180:{name:'180 天精学', emoji:'🐢', days:180, modules:['p1','p3','padv','p4','p5','plife','p6','psong','ptext','ptext2','ptext3'], desc:'每天 10–15 分钟。学完全部内容,还包括语法、阅读策略、高频词和 15 首儿歌。学得扎实,尤其适合打基础。'}, }; function buildDailyPlan(days, moduleIds){ const mods = curriculum.filter(m=>moduleIds.includes(m.id)); const tasks = []; mods.forEach(m=>{ const c = m.count(); for(let i=0;i= days){ // 任务比天数多:尽可能均匀,且保证正好 days 天 const base = Math.floor(tasks.length/days); const extra = tasks.length % days; // 前 extra 天各多 1 个 let pos = 0; for(let d=0; d{ daily.push({day:td, items:[t], review:(i%2===1)}); td += gap || 1; }); // 补齐剩余天数,作为"复习日" while(daily.length < days){ const t = tasks[daily.length % tasks.length]; daily.push({day:daily.length+1, items:[t], review:true}); } // 重新编号 + 合并同一天 const merged = []; daily.forEach(d=>{ const last = merged[merged.length-1]; if(last && last.day===d.day) last.items.push(...d.items); else merged.push({day:d.day, items:d.items.slice(), review:d.review}); }); return {daily:merged.map((d,i)=>({day:i+1, items:d.items})), total:tasks.length, perDay:1}; } return {daily, total:tasks.length, perDay:Math.ceil(tasks.length/days)}; } function dailyLoad(p){ const mods = curriculum.filter(m=>p.modules.includes(m.id)); const total = mods.reduce((a,m)=>a+m.count(),0); return Math.max(1, Math.round(total/p.days)); } function renderPlanGrid(){ const grid = document.getElementById('planGrid'); if(!grid) return; grid.innerHTML=''; Object.entries(PLANS).forEach(([k,p])=>{ const el = document.createElement('div'); el.className = 'plan-card' + (plan && plan.days==p.days ? ' active':''); el.innerHTML = ` ${p.popular?'
最受欢迎
':''} ${p.emoji}
${p.name}
${p.days} 天 · 每天约 ${dailyLoad(p)} 个知识点
${p.desc}
`; el.onclick = ()=> choosePlan(parseInt(k)); grid.appendChild(el); }); } function choosePlan(days){ const cfg = PLANS[days]; const built = buildDailyPlan(cfg.days, cfg.modules); plan = { days, name:cfg.name, emoji:cfg.emoji, startDate: new Date().toISOString().slice(0,10), daily: built.daily.map(d=>({day:d.day, modules:[...new Set(d.items.map(it=>it.mod.id))], count:d.items.length})), total: built.total, perDay: built.perDay, lastVisit: new Date().toISOString().slice(0,10) }; SafeStore.set(PLAN_KEY, JSON.stringify(plan)); safe(function(){ renderPlanGrid(); }); renderDashboard(); } function todayPlan(){ if(!plan) return null; const idx = Math.min(plan.daily.length-1, daysSince(plan.startDate)); return idx >= 0 ? plan.daily[idx] : plan.daily[0]; } function daysSince(dateStr){ const d0 = new Date(dateStr+'T00:00:00'); const now = new Date(); now.setHours(0,0,0,0); return Math.round((now - d0)/86400000); } function renderDashboard(){ const dash = document.getElementById('planDash'); const intro = document.getElementById('planIntro'); if(!plan){ dash.style.display='none'; if(intro)intro.style.display='block'; return; } dash.style.display='block'; if(intro)intro.style.display='none'; const tp = todayPlan(); const dayNum = tp ? tp.day : plan.days; document.getElementById('todayDay').textContent = dayNum; const mods = tp ? curriculum.filter(m=>tp.modules.includes(m.id)) : []; document.getElementById('todayDesc').textContent = mods.length ? '今天专注:' + mods.map(m=>m.icon+' '+m.name).join('、') + `(约 ${tp.count} 个知识点)` : '今天复习一下学过的内容吧!'; const ul = document.getElementById('todayList'); ul.innerHTML = mods.map(m=>`
  • ${m.icon} ${m.name} — 点开练习几遍
  • `).join(''); document.getElementById('startToday').onclick = ()=>{ const first = mods[0]; if(first) switchTab(tabOrder.indexOf(first.tab)); else switchTab(tabOrder.indexOf('p7')); }; // 统计 const done = Object.keys(progress).filter(k=>progress[k]).length; const elapsed = daysSince(plan.startDate)+1; const left = Math.max(0, plan.days - elapsed); document.getElementById('statDone').textContent = done; document.getElementById('statDays').textContent = Math.min(elapsed, plan.days); document.getElementById('statStreak').textContent = Math.min(elapsed, plan.days); document.getElementById('statLeft').textContent = left; const pct = plan.total ? Math.min(100, Math.round(done/plan.total*100)) : 0; document.getElementById('planFill').style.width = pct+'%'; document.getElementById('planPctText').textContent = `${done}/${plan.total} 知识点 · ${pct}%`; // 每周概览 const wk = document.getElementById('planWeeks'); const weeks = Math.ceil(plan.daily.length/7); let html=''; for(let w=0; wa.concat(d.modules),[]))).map(mid=>{ const m = curriculum.find(x=>x.id===mid); return m? m.icon+m.name : mid; }).join('、'); const isNow = (w === Math.floor((daysSince(plan.startDate))/7)); html += `
    第 ${start+1}–${end} 天${isNow?' · 当前':''}:${names}
    `; } wk.innerHTML = html; } document.getElementById('resetPlan').onclick = ()=>{ if(!confirm('确定要重新选择学习计划吗?(已学进度会保留)')) return; plan = null; SafeStore.del(PLAN_KEY); renderPlanGrid(); renderDashboard(); }; document.getElementById('btnPlan').onclick = ()=>{ switchTab(0); document.getElementById('planGrid').scrollIntoView({behavior:'smooth'}); }; renderPlanGrid(); renderDashboard(); updateProgress();