1

I was working with imageData, and for some reason, it is only drawing half of the image!

Here is my code. (There is a canvas element with an ID of canvas)

function getWidth() {
  return Math.max(
    document.body.scrollWidth,
    document.documentElement.scrollWidth,
    document.body.offsetWidth,
    document.documentElement.offsetWidth,
    document.documentElement.clientWidth
  );
}
function getHeight() {
  return Math.max(
    document.body.scrollHeight,
    document.documentElement.scrollHeight,
    document.body.offsetHeight,
    document.documentElement.offsetHeight,
    document.documentElement.clientHeight
  );
}

var width = getWidth();
var height = getHeight();

var canvas = document.getElementById('canvas');
canvas.setAttribute("width", width + "px");
canvas.setAttribute("height", height + "px");

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

var draw = function(){
    var p = new Uint8ClampedArray(width*height*4);

    for(var y = 0; y<width; y++){
        for(var x = 0; x<height; x++){
            var i = x + width * y << 2;
            p[i    ] = p[i + 1] = p[i + 2] = 0;
            p[i + 3] = 255;
        }
    }

    var imageData = new ImageData(p, width, height);      
    ctx.putImageData(imageData, 0, 0);

    window.requestAnimationFrame(draw);
};

window.requestAnimationFrame(draw);
<canvas id="canvas"></canvas>
ggorlen
  • 44,755
  • 7
  • 76
  • 106
Paradox
  • 133
  • 1
  • 11
  • Works fine for me. – ggorlen Aug 25 '21 at 23:35
  • It should be filling up the whole screen with black pixels. It's doing that for you? – Paradox Aug 25 '21 at 23:37
  • Oh, no. Maybe you meant `var i = x + height * y << 2;` then? Your `x` and `y` seem mixed up -- `x` runs on the width and `y` runs on the height. See [this answer](https://stackoverflow.com/a/45969661/6243352) – ggorlen Aug 25 '21 at 23:39
  • That does fill up the whole screen, but then if I try to use the x and y it's all messed up. – Paradox Aug 25 '21 at 23:42
  • The information in that question I already know. I'm doing the same thing here. – Paradox Aug 25 '21 at 23:43
  • No, you're not doing the same thing. You have your `x`s and `y`s reversed and you're treating `x` as bound to height and `y` as bound to width. Use `for (var x = 0; x < width; x++) {` and `for (var y = 0; y < height; y++) {` and use the code in the linked dupe suggestion. – ggorlen Aug 25 '21 at 23:43
  • 1
    Oh. Thank you. I have no idea how I didn't notice that. Thank you! – Paradox Aug 25 '21 at 23:47

1 Answers1

0

I mixed up width and height in the for loops! I was writing to the array sideways.

Once the width and height are swapped, everything works fine :)

function getWidth() {
  return Math.max(
    document.body.scrollWidth,
    document.documentElement.scrollWidth,
    document.body.offsetWidth,
    document.documentElement.offsetWidth,
    document.documentElement.clientWidth
  );
}
function getHeight() {
  return Math.max(
    document.body.scrollHeight,
    document.documentElement.scrollHeight,
    document.body.offsetHeight,
    document.documentElement.offsetHeight,
    document.documentElement.clientHeight
  );
}

var width = getWidth();
var height = getHeight();

var canvas = document.getElementById('canvas');
canvas.setAttribute("width", width + "px");
canvas.setAttribute("height", height + "px");

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

var draw = function(){
    var p = new Uint8ClampedArray(width*height*4);

    for(var y = 0; y<height; y++){
        for(var x = 0; x<width; x++){
            var i = x + width * y << 2;
            p[i    ] = p[i + 1] = p[i + 2] = 0;
            p[i + 3] = 255;
        }
    }

    var imageData = new ImageData(p, width, height);      
    ctx.putImageData(imageData, 0, 0);

    window.requestAnimationFrame(draw);
};

window.requestAnimationFrame(draw);
<canvas id="canvas"></canvas>
Paradox
  • 133
  • 1
  • 11