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

二维矩阵中Cannot Read Properties of undefined错误排查(HTML&JavaScript)

像素黑暗光效模拟项目错误排查:Cannot read properties of undefined

问题背景

我正在用JavaScript开发一个基于像素的黑暗光效模拟项目,目标是实现光标移动时周围生成光泡效果,仅渲染光标附近区域保证实时性,代码支持光强、像素分辨率等定制。运行代码时出现以下错误:

Uncaught TypeError: Cannot read properties of undefined

确认已定义Canvas.Matrix,作为编程新手需要问题排查及解决帮助。

错误原因分析

  1. 边界判断逻辑错误:循环中的if (x || y <= 0)完全不符合需求,该条件会允许x或y为负数的情况(比如x=-1时,x为true,条件成立),同时排除x=0但y合法的情况。当x或y超出Canvas.Matrix的索引范围(负数或大于等于矩阵长度)时,访问Canvas.Matrix[x][y]就会得到undefined,触发错误。
  2. 距离计算逻辑错误:计算CellDistance时两次使用Mouse.X,应该分别对应x和y方向的偏移,且应该基于矩阵的单元格坐标,而非原始鼠标像素坐标。
  3. 未声明局部变量:CellDistance未用let/const声明,会成为全局变量,不符合编码规范。
  4. 矩阵访问顺序错误:矩阵是按行(高度方向)初始化的,应该用Canvas.Matrix[y][x]访问,原代码用Canvas.Matrix[x][y]会在x超过矩阵列数时触发undefined。

修复方案

  • 修正边界判断:确保x和y落在矩阵的合法索引范围内(x >= 0 && x < Canvas.Matrix[0].length、y >= 0 && y < Canvas.Matrix.length)
  • 修复距离计算:基于鼠标所在的单元格坐标,计算当前单元格到鼠标单元格的距离
  • 声明局部变量CellDistance
  • 调整矩阵访问顺序:使用Canvas.Matrix[y][x]匹配初始化逻辑
  • 优化光效逻辑:让光强随距离衰减,符合真实光效(可选)

完整修复代码

var Canvas = {
  Element: document.createElement("canvas"),
  Width: 500,
  Height: 500,
  Style: "border: 1px solid black;",
  Resolution: 10,
  Matrix: [],
  Context: null,
};

var Light = {
  Intensity: 20,
};

document.body.appendChild(Canvas.Element);
Canvas.Element.style = Canvas.Style;
Canvas.Element.width = Canvas.Width;
Canvas.Element.height = Canvas.Height;

// 初始化矩阵,每个单元格用独立对象避免引用共享
Canvas.Matrix = new Array(Math.floor(Canvas.Height / Canvas.Resolution)).fill().map(() =>
  new Array(Math.floor(Canvas.Width / Canvas.Resolution)).fill().map(() => ({
    Intensity: 0,
  }))
);

Canvas.Context = Canvas.Element.getContext("2d");

Canvas.Element.addEventListener("mousemove", function (event) {
  var Rect = Canvas.Element.getBoundingClientRect();

  var Mouse = {
    X: event.clientX - Rect.left,
    Y: event.clientY - Rect.top,
  };

  // 绘制黑色背景
  Canvas.Context.fillStyle = "#000";
  Canvas.Context.fillRect(0, 0, Canvas.Width, Canvas.Height);

  // 计算鼠标对应的矩阵单元格坐标
  const mouseCellX = Math.floor(Mouse.X / Canvas.Resolution);
  const mouseCellY = Math.floor(Mouse.Y / Canvas.Resolution);

  // 遍历光标附近的单元格
  for (
    let x = mouseCellX - Math.floor(Light.Intensity / 2);
    x < mouseCellX + Math.floor(Light.Intensity / 2);
    x++
  ) {
    for (
      let y = mouseCellY - Math.floor(Light.Intensity / 2);
      y < mouseCellY + Math.floor(Light.Intensity / 2);
      y++
    ) {
      // 检查x和y是否在矩阵合法范围内
      if (x >= 0 && x < Canvas.Matrix[0].length && y >= 0 && y < Canvas.Matrix.length) {
        // 计算当前单元格到鼠标单元格的距离
        const CellDistance = Math.sqrt(
          Math.pow(x - mouseCellX, 2) +
          Math.pow(y - mouseCellY, 2)
        );
        // 光强随距离衰减,最小为0
        Canvas.Matrix[y][x].Intensity = Math.max(0, Light.Intensity - CellDistance);
        
        // 根据光强绘制单元格
        const brightness = Math.floor(Canvas.Matrix[y][x].Intensity / Light.Intensity * 255);
        Canvas.Context.fillStyle = `rgb(${brightness}, ${brightness}, ${brightness})`;
        Canvas.Context.fillRect(
          x * Canvas.Resolution,
          y * Canvas.Resolution,
          Canvas.Resolution,
          Canvas.Resolution
        );
      }
    }
  }
});

额外说明

  • 初始化矩阵时改用双层map,避免fill({Intensity:0})导致所有单元格共享同一个对象的问题
  • 增加了光强衰减逻辑,让光效更自然
  • 补充了单元格绘制逻辑,实现完整的光泡可视化效果

内容的提问来源于stack exchange,提问作者Evan Bair

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 06:25:15