Jump to content

Js Canvas - Writing My Own Viewports


MrFish

Recommended Posts

I'm working on a project where I need to be able to manage frames and panels inside of JS Canvas. They all need to have an independent view but all compile to a flat image when the paint() method is called. It's written so far to be similar to Java's JPanel (in fact I'm calling it MPanel for a lack of creativity). Everything is built around the MPanel class. An MPanel can have an array of other MPanels inside it with different x/y/z properties. When paint() is called the MPanel loops through all it's MPanels and calls paint() on them (which branches out through every MPanel until they have all called paint). The paint() method takes the image data of the panels inside it and draws it to it's own image data (calculating opacities and all). The lousy thing about Canvas is that the image data is not in a 2 dimensional array and is one long array of numbers (every 4 numbers represents the rgba values. So data[0] - data[3] is the first pixel in the top left). This causes a problem when MPanel child is slightly outside the parents view. It turns out looking like this- mcanvas.jpg What do you all think? Any creative solutions without using an if statment on all 640,000 pixels in the ramen noodle cup?

Link to comment
Share on other sites

It appears on the left because since it's one long array as I'm looping through the box image data I'm looping through the cup image data as well starting at a specific offset. After your reach the far right of the cup image the pixels after will start 1px down and all the way to the left. So as I loop it starts drawing to the left of the image. I have to keep track of the width and the height of the canvas. To find the next pixel to draw I do this-

var columns = panel.width*4;  var rows = panel.height;   var offset = (canvasW*4*y)+x*4;  for(var r = 0; r < panel.height; r++)  {   var lineOffset = (size.width*4 - columns)*r + offset;   for(var c = 0; c < columns; c+=4)   {    var start = (r*columns)+c;    var destStart = start+lineOffset;    var red = imageData[start];    var green = imageData[start+1];    var blue = imageData[start+2];    var alpha = imageData[start+3];       var destRed = canvasData[destStart];    var destGreen = canvasData[destStart+1];    var destBlue = canvasData[destStart+2];    var destAlpha = canvasData[destStart+3];

Link to comment
Share on other sites

If the result for all pixels and all layers is a single array then I'm not sure how you would differentiate between things like that. It sounds like the array for the pixels in the box is incorrect if they are all part of the same array as the pixels for the cup. The total width should be larger, the pixels to the right of the cup image should be transparent, and the pixels in the box that show up on the left should be on the right. That sounds like an issue with how the array is generated, it's not using the correct total width for the final image.

Link to comment
Share on other sites

I don't generate the image array- chrome does. The pixels to the right of the cup are transparent but they are not part of the same panel. The cup is actually a much larger image but is only displayed inside that view. Instead of drawing one big image then cropping it I'm trying to save processing but only drawing whats in view. I did find the solution though. Only needed to use 4 extra if statements. mcanvas.jpg

var w = panel.width;  var h = panel.height;   if(x < 0)   var cutSX = abs(x);  else   cutSX = 0;    if(y < 0)   var cutSY = abs(y);  else   cutSY = 0;    if(x+w > size.width)   var cutEX = x+w - size.width;  else   cutEX = w;    if(y+h > size.height)   var cutEY = y+h - size.height;  else cutEY = h;   var newWidth = cutEX - cutSX;  var newColumns = newWidth*4;  var newHeight = cutEY - cutSY;  var imageData = panel.getImage(cutSX, cutSY, cutEX, cutEY).data;   var columns = newWidth*4;  var rows = newHeight;

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...