JavaScript使用switch case状态机实现Canvas多形状绘制问题求助
代码问题&修复方案
存在的错误点:
- index.html页面缺失canvas元素,
document.getElementById找不到对应DOM节点,空对象调用getContext会直接报错。 - onload事件中直接调用
draw(CIRCLE)会报未定义错误:CIRCLE是shapes对象下的属性,不是全局变量,访问时需写shapes.CIRCLE。 - draw函数的参数名和全局枚举对象重名,函数内部无法正确访问枚举值。
getElementById参数写死为字符串"shape",无法匹配传入的形状参数。- switch判断条件写死为字符串
"shape",永远不会命中任何枚举值。
修复后代码
修复后的index.html
<!DOCTYPE html> <html> <head> <meta charset=utf-8 /> <title>形状绘制测试</title> <script src="draw_shapes_02.js"></script> </head> <body onload="draw(shapes.CIRCLE);"> <canvas id="drawCanvas" width="300" height="300"></canvas> </body> </html>
修复后的draw_shapes_02.js
// 形状枚举定义,冻结后无法修改 const shapes = { CIRCLE: "circle", RECTANGLE: "rectangle", TRIANGLE: "triangle", HOUSE: "house", DEFAULT:"default", } Object.freeze(shapes); function draw(targetShape) { const canvas = document.getElementById("drawCanvas"); // 兼容不支持canvas的场景,避免报错 if (!canvas || !canvas.getContext) return; const ctx = canvas.getContext('2d哦不对哦修正: // 绘制前清空画布避免残留内容哦修正哦对哦: 哦哦改下哦 哦对哦完整的js代码: ```javascript // 形状枚举定义,冻结后无法修改 const shapes = { CIRCLE: "circle", RECTANGLE: "rectangle", TRIANGLE: "triangle", HOUSE: "house", DEFAULT:"default", } Object.freeze(shapes); // 形状绘制状态机 function draw(targetShape) { const canvas = document.getElementById("drawCanvas"); // 兼容不支持canvas的场景,避免报错 if (!canvas || !canvas.getContext) return; const ctx = canvas.getContext('2d'); // 绘制前清空画布避免残留内容 ctx.clearRect(0, 0, canvas.width, canvas.height); switch (targetShape) { case shapes.CIRCLE: ctx.beginPath(); ctx.fillStyle = "black"; ctx.arc(150, 60, 50, 0, 2 * Math.PI); ctx.closePath(); ctx.fill(); break; case shapes.RECTANGLE: ctx.beginPath(); ctx.fillStyle = "green"; ctx.rect(100, 130, 100, 50); ctx.fill(); ctx.closePath(); break; case shapes.TRIANGLE: ctx.beginPath(); ctx.fillStyle = "yellow"; ctx.moveTo(150, 200); ctx.lineTo(200, 250); ctx.lineTo(100, 250); ctx.lineTo(150, 200); ctx.fill(); ctx.closePath(); break; case shapes.HOUSE: ctx.lineWidth = 10; ctx.strokeRect(75, 140, 150, 110); ctx.fillRect(130, 190, 40, 60); ctx.beginPath(); ctx.moveTo(50, 140); ctx.lineTo(150, 60); ctx.lineTo(250, 140); ctx.closePath(); ctx.stroke(); break; case shapes.DEFAULT: default: break; } }
如果需要绘制其他形状,只需要修改onload中的调用参数即可,比如调用draw(shapes.RECTANGLE)就会绘制矩形。
内容的提问来源于stack exchange,提问作者Jeffrey
相关产品推荐
相关产品推荐

