MrFish Posted January 10, 2012 Share Posted January 10, 2012 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- 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 More sharing options...
justsomeguy Posted January 10, 2012 Share Posted January 10, 2012 How does that happen that the content that should be on the far right appears on the left? Also, if all you get is one large single-dimension array, how do you know how wide and tall the image should be? Link to comment Share on other sites More sharing options...
MrFish Posted January 10, 2012 Author Share Posted January 10, 2012 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 More sharing options...
justsomeguy Posted January 10, 2012 Share Posted January 10, 2012 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 More sharing options...
MrFish Posted January 10, 2012 Author Share Posted January 10, 2012 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. 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 More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.