You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 21:53:25