如何用for循环简化代码并实现矩形独立悬停变色功能?
问题描述
我用代码创建了两个同心矩形,现在想通过for循环简化代码,以便创建更多更大的矩形并保留原有功能。但用for循环实现时,鼠标悬停小矩形时大矩形也会跟着变色,没法让当前悬停的矩形独立变色,该怎么解决?
原代码如下:
let rectX = 200; let rectY = 200; let rect1Width = 80; let rect1Height = 80; let rect2Width = 40; let rect2Height = 40; let isMouseOverRect1 = false; let isMouseOverRect2 = false; let rect1 = false; let rect2 = false; function setup() { createCanvas(400, 400); rectMode(CENTER); } function draw() { background(200); if ( mouseX > rectX - rect1Width / 2 && mouseX < rectX + rect1Width / 2 && mouseY > rectY - rect1Height / 2 && mouseY < rectY + rect1Height / 2 ) { isMouseOverRect1 = true; rect1 = true; } else { isMouseOverRect1 = false; rect1 = false; } if ( mouseX > rectX - rect2Width / 2 && mouseX < rectX + rect2Width / 2 && mouseY > rectY - rect2Height / 2 && mouseY < rectY + rect2Height / 2 ) { isMouseOverRect2 = true; rect2 = true; } else { isMouseOverRect2 = false; rect2 = false; } if (isMouseOverRect1 && !rect2) { fill(0); } else { fill(255); } rect(rectX, rectY, rect1Width, rect1Height); if (isMouseOverRect2 && rect1) { fill(0); } else { fill(255); } rect(rectX, rectY, rect2Width, rect2Height); }
解决思路
问题核心是同心矩形的包含关系:鼠标悬停在小矩形内时,同时也处于所有外层大矩形的范围内,导致多个矩形的hover状态被触发。要实现仅当前悬停的矩形(即鼠标所在的最内层矩形)变色,需要:
- 用数组存储所有矩形的尺寸,方便批量处理
- 从最小的(最内层)矩形开始判断hover状态,找到目标后立即停止,确保只标记最内层的hover矩形
- 绘制时仅给标记的目标矩形填充深色,其他保持白色
优化后的代码
let rectX = 200; let rectY = 200; // 按从小到大排序存储矩形尺寸(最内层到最外层) let rects = [ { width: 40, height: 40 }, { width: 80, height: 80 }, { width: 120, height: 120 }, { width: 160, height: 160 } ]; let hoveredIndex = -1; // 记录当前hover的矩形索引,-1表示无hover function setup() { createCanvas(400, 400); rectMode(CENTER); } function draw() { background(200); hoveredIndex = -1; // 从最内层开始判断hover,找到后立即跳出循环 for (let i = 0; i < rects.length; i++) { let r = rects[i]; let halfW = r.width / 2; let halfH = r.height / 2; if (mouseX > rectX - halfW && mouseX < rectX + halfW && mouseY > rectY - halfH && mouseY < rectY + halfH) { hoveredIndex = i; break; } } // 从最外层到最内层绘制,保证内层矩形在上方 for (let i = rects.length - 1; i >= 0; i--) { let r = rects[i]; fill(i === hoveredIndex ? 0 : 255); rect(rectX, rectY, r.width, r.height); } }
关键说明
- 矩形数组按从小到大排序,判断hover时优先检测最内层,确保
hoveredIndex只记录鼠标所在的最小矩形 - 绘制时从大到小遍历,避免内层矩形被外层遮挡
- 仅对
hoveredIndex对应的矩形填充黑色,其他保持白色,实现单个矩形独立变色
内容的提问来源于stack exchange,提问作者Soren RJ
相关产品推荐
相关产品推荐

