自缩放交互式网页课件的框架
从 20 年前的 flash,10 年前的 JavaScript,到 5 年前的 Geogebra,一直对开发交互式教学课件念念不忘,限于当时资料匮乏、遇到问题很难找到解答等原因,最后半途而废。现在有了AI的辅助编程,再次激起了制作的热情,目标是把高中物理课本中的插图改编成可互动的形式,加深学生对物理图景的理解、提高教师授课的效率。
编程 IDE 用的是字节跳动的 Trea,大模型选用的是 DeepSeek。第一次用 AI 生成的代码的确惊艳了我,比如生成一个“演示力的平行四边形定则”的互动课件,科学性、互动性、标注、网页布局、配色方面等方面几乎都无需修改拿来就能用了。不由打开多年前用 flash 制作的版本,那时花了好几天时间才制作出来个半成品,对比之下差距明显。
当年学习编程通常是买本书,在实际编程过程中,很多东西在书上找不到解答,需要上网搜索,即“面向谷歌编程”或“面向百度编程”,但往往搜出一大堆东西,却找不到想要的答案,一来二去,热情被磨灭,最后就放弃了。
早在 2006 年,Google 推出 Gmail、Google Docs 等在线办公套件,展示了基于浏览器的应用潜力。2008 年 Chrome 浏览器的诞生,初衷不仅是“浏览网页”,更是支持复杂的 Web 应用。当时的宣言是:“浏览器应该成为现代操作系统的平台”。现在看来,这个技术理念是成功的,我现在用的 Word、PPT 等常用软件都能通过浏览器在云端实现。PhET(Physics Education Technology)互动模拟项目亦是如此,2002 年建立以来,它的互动程序从 java 转变为 flash,目前已经几乎都转成了可以在浏览器上直接使用的 HTML 5 程序,而且将脚本、图像都打包到一个 html 文件中,大小 1、2 MB,可以放在优盘中,离线也能使用,十分方便。phET 是我制作课件时的主要参考对象,我要做的就是改编成适合对应课本的形式,且功能做到小而精,虽然 PhET 也开放了源代码,但是较为复杂,我的水平很难对它进行二次开发。
几年前曾想用 Geogebra(源代码也是公开的)制作课件,也做了几个作品(初始化较慢,因为要加载 10 MB 左右的库文件,之后就快了),但后来放弃了。主要原因是难以满足单文件离线使用的要求。ggb 程序本身并不大,几十 K 到几百 K 左右,离线在优盘上使用是可以的,但需要在优盘放置一个包含主程序的文件夹,大约 2、30 MB,不是很方便。总的来说,Geogebra 比较适合制作数学课件,做物理课件用得有点不顺手。
有了AI,直接提问就能直奔主题,甚至还会补充更多的细节,问题得到即时反馈,效率非常高,并不像下图的右边所示——AI生成5分钟,人工调试除错 24 小时,我觉得 AI 的代码质量比我高多了,它5分钟生成主要结构,我只需要花 24 小时看懂代码,在细节处进行调整就可以了,如此算来,大概一个星期能完成一个课件。

自动缩放框架
对于像我这种从 flash 时代走来的人来说,习惯的模式就是先设定一个固定分辨率(flash 时代主流分辨率好像 800×600、640×480),在这个分辨率下放置元件的位置,编程设置它们的坐标、旋转实现动画。由于 flash 绘制的是矢量图,所以即使屏幕放大图也不会模糊。
做 h5 课件还是使用类似的思路:设置一个大小为 1920×1080 的分辨率(这是目前主流的 1080p 分辨率)的 div,若你在 1080p 的显示器下工作,由于浏览器上方还有菜单,因此 <html> 元素的可视区域高度小于 1080,比例大于 16∶9,此时将高度设置为可视区域高度,宽度减小,但比例保持 16∶9 不变;若是手机竖屏,则比例小于 16∶9,需要将宽度设置为可视区域宽度,高度也随之减小,比例仍保持 16∶9 不变。
上面的文字可以作为 DeepSeek 的提示词,让它帮你生成符合要求的代码。效果不错,第一次就生成了符合我要求的代码。
首先是网页的三大核心之一的表现层——层叠样式表(CSS),代码如下:
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 可自定义尺寸的容器 */
.app-container {
position: relative;
width: 100vw; /* 可以按需修改尺寸 */
height: 100vh; /* 可以按需修改尺寸 */
overflow: hidden;
min-width: 400px;
min-height: 300px;
}
#app {
position: absolute;
top: 0;
left: 0;
width: 1920px;
height: 1080px;
transform-origin: 0 0;
overflow: hidden;
/* 初始居中 */
transform: translate(calc(50% - 960px), calc(50% - 540px));
}
</style>
然后是关键的行为层——JavaScript:
<script>
document.addEventListener('DOMContentLoaded', function () {
const app = document.getElementById('app');
const appContainer = document.getElementById('app-container');
// 初始缩放
updateScale();
// 监听容器大小变化
const resizeObserver = new ResizeObserver(updateScale);
resizeObserver.observe(appContainer);
// 更新缩放比例和位置
function updateScale() {
const containerWidth = appContainer.clientWidth;
const containerHeight = appContainer.clientHeight;
// 计算缩放比例
const scaleX = containerWidth / 1920;
const scaleY = containerHeight / 1080;
const scale = Math.min(scaleX, scaleY);
// 计算居中偏移
const scaledWidth = 1920 * scale;
const scaledHeight = 1080 * scale;
const offsetX = (containerWidth - scaledWidth) / 2;
const offsetY = (containerHeight - scaledHeight) / 2;
// 应用变换
app.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`;
}
});
</script>
使用浏览器的 API——ResizeObserver 监听 app-container 的尺寸变化,当变化时则调用 updateScale 方法,调整 app 的位置和缩放。
最后的 html 代码很简单,代码如下:
<div class="app-container" id="app-container">
<div id="app">
</div>
</div>
以后设计课件界面时,将 html 代码都放在 <div id="app"></div> 标签内,其中的内容就会自动缩放了。
测试
有了框架后,做了一个简单的测试,你可以拖动程序的右下角改变它的大小。在页面左侧放置主内容,分别用 canvas 和 svg 绘制了两个圆,右侧为控制区,放置了滚动条控制圆的半径。有些 AI 编出的程序会将控制区放置在左边,这样做不好,因为大部分人都是右手拿鼠标,教师在教室大屏演示时也会站在右方,控制区放在右边更顺手、不会遮挡内容。
控制面板
• 当前缩放比例: 1.00
• container 容器尺寸: 0×0
• 虚拟分辨率: 1920×1080
canvas 绘制的是像素,相当于一张图像,它绘制圆的代码如下:
ctx.beginPath();
ctx.arc(150, 150, radius, 0, Math.PI * 2);
ctx.strokeStyle = 'blue';
ctx.lineWidth = 3;
ctx.stroke();
// 绘制红色填充
ctx.beginPath();
ctx.arc(150, 150, radius, 0, Math.PI * 2);
ctx.fillStyle = 'red';
ctx.fill();
svg 绘制的是矢量图形,放大不变形,还可以用其他矢量绘图软件制作好后插入网页中,绘制圆的代码如下:
<svg id="blueCircleSvg" width="300" height="300" viewBox="0 0 300 300">
<circle id="blueCircle" cx="150" cy="150" r="50" fill="blue" stroke="red" stroke-width="3"/>
</svg>
两者的语法非常像。对于简单的、对象比较少的程序,我更倾向于使用svg。
完整的源代码
发布时间:2025/12/13 下午4:13:30 阅读次数:40
