如何缩放.txt文件加载的坐标适配canvas 避免绘制图形超出边界
解决方案
问题根因
你当前使用的原始坐标范围超出了750x750的canvas尺寸(比如示例数据中存在x=945的坐标点),且绘制的圆形直径为20px,未预留内边距的情况下边缘元素会被裁切。
实现步骤
- 第一步:加载完所有坐标后,先统计原始坐标的x、y的最大、最小值,确定原始坐标的整体边界
- 第二步:给canvas设置内边距(避免边缘圆形被裁切),计算canvas实际可用的绘制区域尺寸
- 第三步:通过归一化映射把每个原始坐标转换到canvas的可用区域内,可选择保持原始宽高比避免图形拉伸
修改后的完整代码
let dots = []; let dotsData; let orderData; // 预留内边距,避免边缘的圆形被裁切 const padding = 20; function preload() { dotsData = loadStrings('./dots.txt'); orderData = loadStrings('./orderFile.txt'); } function setup() { createCanvas(750, 750); createDots(dotsData); // 坐标适配处理 adaptDotsCoordinate(); } function draw() { background(220); fill(255, 100, 200); for (let i = 0; i < dots.length; i++) { circle(dots[i].x, dots[i].y, 20); let goalDot = dots.find(e => e.id == orderData[i]); if (goalDot) { line(dots[i].x, dots[i].y, goalDot.x, goalDot.y); } } } function createDots(filename) { for (let i = 0; i < filename.length; i++) { let temp = splitTokens(filename[i]); dots.push({ id: temp[0], // 转成数字类型避免字符串运算错误 x: Number(temp[1]), y: Number(temp[2]) }) } } function adaptDotsCoordinate() { // 计算原始坐标的边界 let minX = Infinity, maxX = -Infinity; let minY = Infinity, maxY = -Infinity; dots.forEach(dot => { minX = Math.min(minX, dot.x); maxX = Math.max(maxX, dot.x); minY = Math.min(minY, dot.y); maxY = Math.max(maxY, dot.y); }) // 计算可用绘制区域尺寸 const validWidth = width - 2 * padding; const validHeight = height - 2 * padding; // 取宽高缩放比例的最小值,保持原始比例不拉伸 const scaleX = validWidth / (maxX - minX); const scaleY = validHeight / (maxY - minY); const scale = Math.min(scaleX, scaleY); // 映射每个点的坐标到canvas区域 dots.forEach(dot => { dot.x = padding + (dot.x - minX) * scale; dot.y = padding + (dot.y - minY) * scale; }) }
补充说明
如果不需要保持原始坐标的宽高比,直接分别用scaleX和scaleY计算x、y的映射值即可,不需要统一取scale最小值。
内容的提问来源于stack exchange,提问作者KodyJH
相关产品推荐
相关产品推荐

