AI 协作日志
学生 Web 实验作品平台
学号:202412211402018 · 来源:ai-log.md
# 实验三 AI协作记录(请学生在实际完成实验后填写)
## AI协作1:矩阵和变换次序
- 我自己的预测:
我需要补全transforms.js里面S缩放、R旋转矩阵,完成bItem里面两种旋转模式world/self的矩阵拼接。
我手写写的时候担心multiply(A,B)顺序搞反,打算先写代码,再看页面矩阵测试项是否打勾。我主观猜测:world模式应该把R放前面,self模式T放前面,但不确定,需要跑页面验证。
- AI工具与原始提示词:
gl‑matrix mat4 multiply(A,B)代表A乘以B,列向量模式,补全WebGL实验transforms.js S缩放矩阵 R旋转矩阵,task‑b bItem函数world和self两种旋转模式矩阵怎么拼接,角度需要转弧度。
- AI的建议:
给出S()、R()函数代码;bItem中world模式 mat = multiply(rotM, transM);self模式 mat = multiply(transM, rotM)。同时提醒我角度要deg2rad转弧度。
- 本人计算、运行与证据:
将AI给出的S、R函数粘贴到transforms.js对应TODO位置,复制bItem内矩阵拼接代码。打开task‑b测试页面,设置cx=0.5,cy=0.25,角度45度。切换pivot为world,正方形围绕画布原点做公转运动;切换pivot为self,正方形固定在(0.5,0.25)位置原地旋转。页面下方矩阵探针5组测试用例,全部显示✓。刚开始粘贴完代码我忘记使用X.deg2rad转换角度,拖动角度滑块图形完全没有旋转效果,控制台没有报错,观察代码后补上角度转换才恢复正常。
- 采纳或修正结论:
整体采纳S、R矩阵函数代码,但是没有直接照搬就结束。我通过页面可视化图形、矩阵探针两套手段双向校验结果。自行排查修复了角度忘记转弧度的bug,确认矩阵乘法顺序符合预期,理解multiply(A,B)代表A*B,列向量右侧矩阵先执行。
## AI协作2:实际故障排查
- 错误现象与重现步骤:
完成task‑D的代码编写后,打开task‑d.html页面。界面可以正常显示控件,动画循环正常运行。选择任意图形类型,调整运动参数之后点击canvas画布,不会生成新对象;页面上的对象计数数字保持不变,画布没有新增图形。每点击一次画布,浏览器F12控制台就输出一条红色报错:Uncaught ReferenceError: dirSel is not defined。只要点击画布就复现,切换图形类型现象不变。
- 我先检查了什么:
1. 看addFromMouse鼠标点击事件有没有绑定;
2. 断点看点击会不会进到addFromMouse函数;
3. 定位报错行指向selectOptions函数,回头看自己写的代码。
我发现我定义变量名字叫`direction`,但是if判断写的是`dirSel`,变量名字敲错。
- AI工具与原始提示词:
豆包 JS函数报ReferenceError变量未定义,点击画布不执行创建对象,怎么解决。
- AI建议的候选原因与测试:
AI给出4条可能故障点:
1. 函数内部使用了未声明、名字拼写错误的局部变量,代码抛出异常导致函数终止;
2. 鼠标坐标换算完成后u、v超出0‑1范围,触发return直接退出函数;
3. selectOptions函数内部报错,create对象创建逻辑不会被执行;
4. 对象实际已经创建成功,但是transforms.js的modelFor返回错误矩阵,对象存在但是渲染不可见。
- 实测结果、修复与复测:
测试1:在浏览器控制台手动调用cg3.create('circle',0,0,{}),画布成功渲染圆形,说明对象创建、渲染绘制整套管线是正常的,问题锁定在鼠标点击调用链路上。
测试2:定位selectOptions函数内拼写错误,把所有`dirSel`修改为代码中实际定义的变量名`direction`。
保存代码刷新页面,控制台红色报错消失。点击画布可以正常生成图形,对象计数跟随点击上涨;不同形状、不同运动参数都可以正常创建,每个新对象按照自己保存的参数独立运动,原有全部D任务功能恢复正常。
## AI协作3:设计方案比较
- 我考虑的两种实现:
方案1:直接调用canvas.toBlob()生成截图,截图之前不手动调用draw()重绘,仅仅依靠WebGL上下文preserveDrawingBuffer配置保留画面缓冲。
方案2:调用toBlob之前,先手动执行this.draw()强制完整重绘一帧画面,再导出PNG图片;下载完成后调用revokeObjectURL释放blob临时资源。
- AI工具与原始提示词:
豆包 WebGL2 canvas.toBlob截图空白,preserveDrawingBuffer,两种截图实现方案对比。
- 对比、取舍与原因:
方案1代码行数少,不需要额外调用绘制函数。虽然Graphics初始化已经设置preserveDrawingBuffer:true,但是浏览器规范并不强制保证缓冲区永久保留;当页面切后台、窗口最小化、动画持续运行一段时间后,浏览器有可能回收WebGL绘图缓冲区,此时导出的PNG就会变成全黑空白图片。虽然代码简短,但是功能稳定性不可控,在实验验收时很容易出现截图失效。
方案2会额外执行一次完整draw绘制,带来极其微小的性能开销,对于本实验场景完全可以忽略不计。手动重绘可以主动生成最新一帧画面,不依赖浏览器对绘图缓冲区的保留策略。同时在下载完成之后释放blob的url,避免页面内存持续占用。综合考虑实验验收稳定性,我选择方案2。
- 实际实现及核验:
在app.js savePNG函数最开头添加`this.draw();`,保证导出前渲染最新画面;之后调用canvas.toBlob,创建临时a标签设置download属性触发浏览器下载;下载回调完成后移除临时DOM节点并且执行URL.revokeObjectURL释放资源。
多组测试核验:
1. 画布同时放置多种运动对象,动画正常运行状态点击保存截图,下载PNG图片,图形内容、自定义背景颜色全部和画布显示一致;
2. 动画运行数秒之后,立刻点击截图,图片内容同步;
3. 切换浏览器其他标签页,切回本页面马上点击截图,图片不会变黑;
4. 临时注释掉this.draw(),可以稳定复现截图变黑的bug,加回代码截图恢复正常。