javascript "未捕获的类型错误:运行画布动画时无法读取未定义(读取'310')"的属性

bwitn5fc  于 2023-02-11  发布在  Java
关注(0)|答案(1)|浏览(75)

我正在做另一个隧道效果演示。这次我试着让隧道在图像中移动。
然而,处理隧道渲染的函数总是抛出一个错误,我不完全确定为什么:

function draw(time) {
  let animation = time / 1000.0;
  
  let shiftX = ~~(texWidth * animation);
  let shiftY = ~~(texHeight * 0.25 * animation);
  let shiftLookX = (screenWidth / 2) + ~~(screenWidth / 2 * Math.sin(animation))
  let shiftLookY = (screenHeight / 2) + ~~(screenHeight / 2 * Math.sin(animation))

  for (y = 0; y < buffer.height; y++) {
    for (x = 0; x < buffer.width; x++) {
      let id = (y * buffer.width + x) * 4;
      let d = ~~(distanceTable[y + shiftLookY][x + shiftLookX] + shiftX) % texWidth;
      let a = ~~(angleTable[y + shiftLookY][x + shiftLookX] + shiftY) % texHeight;
      let tex = (a * texture.width + d) * 4;

      buffer.data[id] = texture.data[tex];
      buffer.data[id+1] = texture.data[tex+1];
      buffer.data[id+2] = texture.data[tex+2];
      buffer.data[id+3] = texture.data[tex+3];
    }
  }

  ctx.putImageData(buffer, 0, 0);
  window.requestAnimationFrame(draw);
}

代码的其余部分可以在here中查看,以防问题发生在其他地方。
我已经确定了一个可能的原因--如果用于从distanceTableangleTable读取的第一个索引不是y,则会出现错误,即使只是将一个值添加到y。不幸的是,我还没有找出导致此错误的原因,或者为什么第二个索引不受此影响。
我也搜索过类似的问题,但似乎问这些问题的人都因为不同的原因得到了这个错误,所以我有点卡住了。

dsekswqp

dsekswqp1#

似乎将for循环设置为使用画布的高度和宽度作为上限,而不是像素缓冲区的宽度和高度,就足以解决这个问题。
我完全不知道为什么,是因为缓冲区是画布的两倍大吗?

var texWidth = 256;
var texHeight = 256;
var screenWidth = 640;
var screenHeight = 480;

var canvas = document.createElement('canvas');
canvas.width = screenWidth;
canvas.height = screenHeight;

var ctx = canvas.getContext("2d");

var texture = new ImageData(texWidth, texHeight);
var distanceTable = [];
var angleTable = [];
var buffer = new ImageData(canvas.width * 2, canvas.height * 2);

for (let y = 0; y < texture.height; y++) {
  for (let x = 0; x < texture.width; x++) {
    let id = (y * texture.width + x) * 4;
    let c = x ^ y;

    texture.data[id] = c;
    texture.data[id+1] = c;
    texture.data[id+2] = c;
    texture.data[id+3] = 255;
  }
}

for (let y = 0; y < buffer.height; y++) {
  distanceTable[y] = [];
  angleTable[y] = [];

  let sqy = Math.pow(y - canvas.height, 2);
  for (let x = 0; x < buffer.width; x++) {
    let sqx = Math.pow(x - canvas.width, 2);
    let ratio = 32.0;

    let distance = ~~(ratio * texHeight / Math.sqrt(sqx + sqy)) % texHeight;
    let angle = Math.abs(~~(0.5 * texWidth * Math.atan2(y - canvas.height, x - canvas.width)) / Math.PI);

    distanceTable[y][x] = distance;
    angleTable[y][x] = angle;
  }
}

function draw(time) {
  let animation = time / 1000.0;
  
  let shiftX = ~~(texWidth * animation);
  let shiftY = ~~(texHeight * 0.25 * animation);
  let shiftLookX = (screenWidth / 2) + ~~(screenWidth / 2 * Math.sin(animation))
  let shiftLookY = (screenHeight / 2) + ~~(screenHeight / 2 * Math.sin(animation * 2.0))

  for (y = 0; y < canvas.height; y++) {
    for (x = 0; x < canvas.width; x++) {
      let id = (y * buffer.width + x) * 4;
      let d = ~~(distanceTable[y + shiftLookY][x + shiftLookX] + shiftX) % texWidth;
      let a = ~~(angleTable[y + shiftLookY][x + shiftLookX] + shiftY) % texHeight;
      let tex = (a * texture.width + d) * 4;

      buffer.data[id] = texture.data[tex];
      buffer.data[id+1] = texture.data[tex+1];
      buffer.data[id+2] = texture.data[tex+2];
      buffer.data[id+3] = texture.data[tex+3];
    }
  }

  ctx.putImageData(buffer, 0, 0);
  window.requestAnimationFrame(draw);
}

document.body.appendChild(canvas);

window.requestAnimationFrame(draw);

相关问题