news 2026/5/8 16:51:38

用 400 行 HTML 给小学生做汉字学习工具

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用 400 行 HTML 给小学生做汉字学习工具

起因

女儿上小学二年级,语文作业里有两类题目让她很头疼:

  1. 笔顺练习:老师要求按正确顺序书写,但家里没有专门的点读笔,她总是记错"先横后竖"还是"先撇后捺"。
  2. 字帖临摹:学校发的纸质字帖字太小,印刷模糊,她趴在桌上看得很费力。

市面上倒是有不少 App,但要么需要注册账号,要么广告满屏,要么需要付费解锁。我想要的很简单:打开浏览器,输入今天要学的字,立刻开始练习。于是花了几个晚上,做了两个纯 HTML 页面。


两个工具

工具一:汉字笔顺演示(hanzi.html

核心功能:

  • 输入任意汉字或带标点的句子
  • 每个汉字自动显示田字格 / 米字格辅助线
  • 动画逐笔演示笔顺,支持三种播放模式:顺序播放循环播放只播一次
  • 点击单个汉字可单独对其循环播放,方便重点攻克难字
  • 支持显示拼音(声调符号,如 nǐ hǎo)

工具二:汉字字帖(hanzi2.html

核心功能:

  • 将课文段落渲染成米字格字帖
  • 每个格子内用 HanziWriter 显示汉字轮廓,供孩子描红
  • 支持可调格子大小,适配不同打印纸张
  • 支持拼音模式,在汉字上方标注拼音
  • 浏览器打印友好(@media print隐藏 UI 控件)

技术选型

HanziWriter

HanziWriter 是这两个工具的核心依赖,一个开源的 JavaScript 库,提供:

  • 完整的汉字 SVG 笔画数据(基于 Make Me a Hanzi 数据集)
  • animateCharacter()API 按正确笔顺播放动画
  • showOutline()显示灰色轮廓供描红
  • 偏旁部首可单独染色(radicalColor

引入方式极简,一个 CDN script 标签即可:

<scriptsrc="https://cdn.jsdelivr.net/npm/hanzi-writer@3.5/dist/hanzi-writer.min.js"></script>

pinyin-pro

拼音功能使用 pinyin-pro,支持带声调符号的标准拼音(ā á ǎ à),多音字根据上下文取最常用读音:

pinyinPro.pinyin("重",{toneType:"symbol",type:"array"});// => ["zhòng"]

同样是一个 CDN script 标签搞定,无需 Node.js / 构建工具。


关键实现细节

1. 并发动画控制(笔顺演示)

字帖有时需要同时展示几十个汉字,如果全部同时播放动画,浏览器会卡顿。解决方案是维护一个异步工作池:

constMAX_CONCURRENT_ANIMATIONS=32;constloopState={cursor:0};// 启动 N 个并发 worker,每个 worker 循环取下一个可见字播放for(leti=0;i<workerCount;i++){playVisibleLoop(writerEntries,runId,loopState);}

每个 worker 通过共享的loopState.cursor原子性地认领下一个待播字符,避免重复播放。

2. IntersectionObserver 懒执行

页面很长时,只对当前视口内的汉字播放动画,滚出屏幕的字暂停,滚回来再继续:

constobserver=newIntersectionObserver((entries)=>{entries.forEach((entry)=>{entry.target.__writerEntry.visible=entry.isIntersecting;});},{rootMargin:"120px 0px"});writerEntries.forEach((entry)=>observer.observe(entry.element));

rootMargin: "120px 0px"让字进入视口前 120px 就提前标记为可见,动画能无缝衔接。

3. 拼音与字格的对齐

拼音模式下每个字符需要上下两层结构(拼音 + 格子),用 flex column 实现:

.char-cell{display:inline-flex;flex-direction:column;align-items:center;gap:4px;}.pinyin-label{font-size:13px;font-weight:600;color:var(--primary);min-height:15px;/* 非汉字字符也占位,保持行底对齐 */white-space:nowrap;}

关键是给非汉字字符(标点、空格)的拼音位置也保留min-height,这样整行元素能整齐地底部对齐,不会因为有无拼音而高低错落。

4. 田字格 / 米字格用纯 CSS 实现

没有用<canvas>或额外的 DOM 节点,格子辅助线完全用多层linear-gradient叠加:

/* 田字格:竖中线 + 横中线 */.writer-target.grid-tian{background-image:linear-gradient(to right,transparentcalc(50% - 0.5px),rgba(23,88,200,0.22)calc(50% - 0.5px),rgba(23,88,200,0.22)calc(50% + 0.5px),transparentcalc(50% + 0.5px)),linear-gradient(to bottom,transparentcalc(50% - 0.5px),rgba(23,88,200,0.22)calc(50% - 0.5px),rgba(23,88,200,0.22)calc(50% + 0.5px),transparentcalc(50% + 0.5px));}

米字格再加两条 45° 对角线即可。线宽精确到 1px(calc(50% - 0.5px)calc(50% + 0.5px)),在 Retina 屏上也锐利清晰。

5. 状态持久化

设置项(格子大小、字格类型、是否显示拼音)和输入文本都存入localStorage,刷新页面后自动恢复,不需要每次重新输入:

constSTORAGE_KEYS={text:"hanzi-demo:text",cellSize:"hanzi-demo:cellSize",gridType:"hanzi-demo:gridType",playbackMode:"hanzi-demo:playbackMode",showPinyin:"hanzi-demo:showPinyin",};

6. 防抖动画竞态(runId 机制)

用户快速修改文字、点击"开始演示"时,旧的异步动画循环需要立刻失效,否则新旧动画会混在一起:

letactiveRunId=0;asyncfunctionstartAnimation(){activeRunId+=1;// 每次启动递增 IDconstrunId=activeRunId;// 所有异步操作前都检查:if(!isRunActive(runId))return;}functionisRunActive(runId){returnrunId===activeRunId;}

这是一种轻量级的"取消令牌"模式,无需引入AbortController


零依赖构建

两个页面都是单文件 HTML,没有npm install,没有打包步骤,没有服务端。直接双击用浏览器打开,或者扔到任意静态托管(GitHub Pages、Nginx、OSS)就能用。

对家长来说最重要的是:不需要注册,不需要 App,不收集任何数据

可以在 “四楼没电梯” 的公众号里面获取地址


源码

两个文件加起来不到 1500 行,全部是原生 HTML / CSS / JS,没有框架依赖。

  • hanzi.html— 笔顺动画演示
  • hanzi2.html— 字帖生成与打印
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/8 16:51:11

明日方舟游戏资源库:解决素材获取难题的完整教程

明日方舟游戏资源库&#xff1a;解决素材获取难题的完整教程 【免费下载链接】ArknightsGameResource 明日方舟客户端素材 项目地址: https://gitcode.com/gh_mirrors/ar/ArknightsGameResource 还在为寻找明日方舟高清游戏素材而烦恼吗&#xff1f;这个开源资源库正是你…

作者头像 李华
网站建设 2026/5/8 16:51:09

未来展会画面数量有望增多

未来展会画面数量有望增多&#xff0c;且将朝着更智能、更具沉浸感的方向发展。随着科技进步&#xff0c;大屏显示技术在会展场景中的渗透率不断提升&#xff0c;如MiniLED、MicroLED等技术的应用&#xff0c;让展会画面以更清晰、更震撼的方式呈现&#xff0c;吸引观众注意力。…

作者头像 李华
网站建设 2026/5/8 16:51:08

从Blender到3D打印机:3MF插件如何简化你的工作流程

从Blender到3D打印机&#xff1a;3MF插件如何简化你的工作流程 【免费下载链接】Blender3mfFormat Blender add-on to import/export 3MF files 项目地址: https://gitcode.com/gh_mirrors/bl/Blender3mfFormat 如果你使用Blender进行3D建模&#xff0c;并且需要将模型发…

作者头像 李华
网站建设 2026/5/8 16:51:04

比肩Z-Image!手机上实时图像生成、编辑模型!字节

真没想到&#xff0c;图像生成进化到这种程度了&#xff01;参数仅有 0.39B&#xff0c;不需要云&#xff0c;不需要电脑 GPU&#xff0c;手机上就能实时生成的顶级图像生成、编辑模型来了。这么好的效果&#xff0c;0.39B&#xff0c;时时生成&#xff0c;还能编辑&#xff0c…

作者头像 李华
网站建设 2026/5/8 16:51:00

如何在Hermes Agent中自定义Provider并接入Taotoken模型

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 如何在Hermes Agent中自定义Provider并接入Taotoken模型 Hermes Agent 是一个流行的开源智能体框架&#xff0c;它支持通过配置自定…

作者头像 李华
网站建设 2026/5/8 16:51:00

全周期陪伴,Captain AI适配OZON商家每一个成长阶段

OZON商家的成长是一个循序渐进的过程&#xff0c;从新手入驻到中小卖家&#xff0c;再到资深大卖&#xff0c;不同阶段的核心需求和痛点完全不同。很多商家在新手期用着某款工具&#xff0c;到了成长期却发现功能不够用&#xff0c;只能重新换工具&#xff0c;不仅浪费钱&#…

作者头像 李华