So I am aware the HTML5 canvas pixel methods are a little different then normal. I am porting a ray-tracer from a Scala Swing application where the old draw method looked like this:
for {
x <- pixels.s.indices
y <- pixels.s(x).indices
} {
g.setColor(pixels.s(x)(y))
g.fillRect(x, y, x, y)
}
Where pixels.s was a 2D array like so:
[[Color, Color, Color],
[Color, Color, Color],
[Color, Color, Color]]
I.e. it mapped exactly to a 2D cartesian plane.
So now I have changed tack slightly, and I have a FLATTENED array of objects with x, y and color:
[{ x: 0, y: 0, color: { red: 33, green: 220, blue: 181 },
{ x: 0, y: 1, color: { red: 33, green: 220, blue: 231 },
{ x: 0, y: 2, color: { red: 33, green: 220, blue: 221 },
...
{ x: 319, y: 238, color: { red: 23, green: 10, blue: 31 },
{ x: 319, y: 239, color: { red: 13, green: 120, blue: 11 }]
I’m trying to draw my flattened array of colors to the screen using this code:
var imageData = context.createImageData(width, height);
var numPixels = width*height;
for (var i = 0; i < numPixels; i++) {
imageData.data[(i*4)] = tracedScene[i].color.red;
imageData.data[(i*4) + 1] = tracedScene[i].color.green;
imageData.data[(i*4) + 2] = tracedScene[i].color.blue;
imageData.data[(i*4) + 3] = 255; // alpha color
};
context.putImageData(imageData, 0, 0);
But it’s coming out a bit wrong. I’ve tripled checked my tests and the actual array is the correct screen data. I’m just rendering it incorrectly. I’m currently getting this:

Whereas I should see:

Now I’ve had the exact same graphical oddities in the Swing version before (years ago), and it was because of the way I was drawing the image. I can’t remember how I fixed it however.
What I am looking to be able to do, is have some method:
drawPixel(x, y, color, canvas) { ... }
that is able to draw a particular pixel at x, y with a color. OR… a way to do it traditionally.
Your input “flattened” array in wrong order: it should be by rows, but yours is by columns.
(Assuming y is top to bottom, x – left to right)