用代码作画:竞赛任务9 | 课型:实习课 | 建议课时:2节
800×600画布,红绿蓝三色切换,鼠标拖动画线——2026纯JS版。
新窗口运行 下载源码<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Task 9 - 画板</title>
<style>
* { margin: 0; padding: 0; }
body { background: #f2f6f8; padding: 24px; font-family: Arial, sans-serif; }
#canvas { border: 2px solid black; background: #fff; cursor: crosshair; }
.color > div { width: 40px; height: 40px; cursor: pointer; float: left; margin: 20px 20px 20px 0; border-radius: 6px; }
.red { background: red; } .green { background: green; } .blue { background: blue; }
.color > div.active { outline: 3px solid #123a52; }
</style>
</head>
<body>
<canvas id="canvas" width="800" height="600"></canvas>
<div class="color">
<div class="red active" data-color="red"></div>
<div class="green" data-color="green"></div>
<div class="blue" data-color="blue"></div>
</div>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let drawing = false, lastX = 0, lastY = 0;
ctx.lineWidth = 4; ctx.lineCap = 'round'; ctx.lineJoin = 'round'; ctx.strokeStyle = 'red';
function getPos(e) {
const rect = canvas.getBoundingClientRect();
return [e.clientX - rect.left, e.clientY - rect.top];
}
canvas.addEventListener('mousedown', e => { drawing = true; [lastX, lastY] = getPos(e); });
canvas.addEventListener('mousemove', e => {
if (!drawing) return;
const [x, y] = getPos(e);
ctx.beginPath(); ctx.moveTo(lastX, lastY); ctx.lineTo(x, y); ctx.stroke();
[lastX, lastY] = [x, y];
});
['mouseup', 'mouseleave'].forEach(ev => canvas.addEventListener(ev, () => drawing = false));
document.querySelectorAll('.color > div').forEach(sw => {
sw.addEventListener('click', () => {
document.querySelector('.color .active').classList.remove('active');
sw.classList.add('active');
ctx.strokeStyle = sw.dataset.color;
});
});
</script>
</body>
</html>任务目标:独立完成竞赛任务9画板并理解绘图模型
| 任务内容与评分 |
|---|
| 任务1:创建800×600带边框画布(15分) |
| 任务2:实现按下-移动-抬起画线模型(35分) |
| 任务3:三色色块切换画笔颜色(20分) |
| 任务4:线条圆角平滑无锯齿(15分) |
| 任务5:画出canvas属性宽高与CSS宽高的区别(15分) |