如何实现Canvas画布四象限划分及随机绘制点所属象限识别
实现Canvas四象限划分与点归属识别
核心判定逻辑
Canvas默认坐标系原点在画布左上角,x轴向右数值递增,y轴向下数值递增,不需要做坐标转换,直接用画布中点做分割线就能划分四个象限:
- 计算画布中点坐标:水平中点
centerX = canvas.width / 2,垂直中点centerY = canvas.height / 2 - 对任意点(x,y)的归属判定规则:
- 垂直方向:
y < centerY为上半区(top),y > centerY为下半区(bottom) - 水平方向:
x < centerX为左半区(left),x > centerX为右半区(right) - 点刚好落在分割线上时,可以按需标记为中线位置即可
- 垂直方向:
修正后的完整可运行代码
原有代码存在几个小问题:画点前未调用beginPath()导致路径重复绘制、label重复使用相同id、硬编码画布尺寸做随机数范围、存在无用的余数计算变量,修正后代码如下:
HTML部分
<canvas id="showCanvas" width="600" height="350"></canvas> <h3>The starting point of the line is: <label id="startPoint">e.g. top, right</label></h3> <h3>The end point of the line is: <label id="endPoint">e.g. bottom, left</label></h3>
JavaScript部分
const myCanvas = document.getElementById("showCanvas"); const myContext = myCanvas.getContext("2d"); const xAxis = []; const yAxis = []; // 计算画布中点,即象限分割线位置 const centerX = myCanvas.width / 2; const centerY = myCanvas.height / 2; // 可选:绘制灰色分割线,直观展示四个象限边界 myContext.strokeStyle = "#cccccc"; // 垂直分割线 myContext.beginPath(); myContext.moveTo(centerX, 0); myContext.lineTo(centerX, myCanvas.height); myContext.stroke(); // 水平分割线 myContext.beginPath(); myContext.moveTo(0, centerY); myContext.lineTo(myCanvas.width, centerY); myContext.stroke(); // 生成并绘制随机点 myContext.fillStyle = "#000000"; for (let i = 0; i < 4; i++) { // 随机数范围直接取画布宽高,后续修改画布尺寸无需调整这里的逻辑 const x = Math.floor(Math.random() * myCanvas.width); const y = Math.floor(Math.random() * myCanvas.height); const r = 5; xAxis.push(x); yAxis.push(y); // 每次画点前必须开启新路径,否则会重复绘制之前的所有路径 myContext.beginPath(); myContext.arc(x, y, r, 0, 2 * Math.PI, true); myContext.closePath(); myContext.fill(); } // 象限判定工具函数 function getPointQuadrant(x, y) { let verticalPos = y < centerY ? "top" : "bottom"; let horizontalPos = x < centerX ? "left" : "right"; // 处理点刚好落在分割线上的边界情况 if (y === centerY) verticalPos = "on horizontal split line"; if (x === centerX) horizontalPos = "on vertical split line"; return `${verticalPos}, ${horizontalPos}`; } // 计算起点、终点的象限结果并写入页面 const startPointResult = getPointQuadrant(xAxis[0], yAxis[0]); const endPointResult = getPointQuadrant(xAxis[3], yAxis[3]); document.getElementById("startPoint").textContent = startPointResult; document.getElementById("endPoint").textContent = endPointResult;
原有代码问题说明
- 绘制圆弧前没有调用
beginPath(),会把之前所有绘制的路径重复填充,导致点渲染异常 - 两个结果label使用了相同的id
sumPoints,不符合HTML规范,JS获取DOM时会出现匹配错误 - 随机生成点坐标时硬编码了600、350的范围,和画布尺寸解绑,后续修改画布大小时容易出现点画到画布外的问题
- 定义的
remainder变量和象限判定逻辑完全无关,属于冗余代码,可以直接删除
内容的提问来源于stack exchange,提问作者MotseMo
相关产品推荐
相关产品推荐

