Flood fill with "opera-2dgame" canvas context

  • joebert
  • Fart Bubbles
  • Genius
  • User avatar
  • Posts: 13504
  • Loc: Florida

Post 3+ Months Ago

Anyone tried doing Flood Fills and undoing them with an HTMLCanvas ?

I've got the fill working, in two different ways.
1) Doesn't cross diagnal lines (4 way recursive)
2) Does cross diagnal lines (8 way recursive)

I haven't quite worked out how to handle an undo function yet though.
One thought I have is pushing copies of the canvas element into an array & just handling ALL undo operations with that, I'm not sure yet if the bitmap data will travel with the canvas elements or how the contexts will deal with having their canvas replaced via somthing like this.
Code: [ Select ]
context.canvas.parentNode.replaceChild(context.stack.shift(), context.canvas);


This will only apply to Opera at the moment, untill I'm aware of other browsers that have canvas contexts with Pixel methods.

Here's how I'm doing my fill.
Code: [ Select ]
function getPixels(ctx, colorCheckingFor, colorPaintingTo, x, y){

    // Holder for the neighboring pixels that are the color we're filling
    var pixels = new Array();

    // Go ahead and paint this one
    ctx.setPixel(x, y, colorPaintingTo);

    // 4 direction
    var horsemen = [{x:x, y:y-1}, {x:x, y:y+1}, {x:x-1, y:y}, {x:x+1, y:y}];

    // 8 direction (results in 2 * as many checks but will bleedthrough diagnal lines)
    if(bleedThrough){horsemen = horsemen.concat([{x:x-1, y:y-1}, {x:x+1, y:y-1}, {x:x-1, y:y+1}, {x:x+1, y:y+1}]);}

    // Check the 4 or 8 neighboring pixels
    for(var i=0; i<horsemen.length; i++){

        // Make sure the pixel is inbounds, Opera will hang if it's not
        if((horsemen[i].x > -1) && (horsemen[i].x < ctx.canvas.width) && (horsemen[i].y > -1) && (horsemen[i].y < ctx.canvas.height)){

            // If it's the color we're filling, paint it & add it to the list to check its' neighbors
            if( ctx.getPixel(horsemen[i].x, horsemen[i].y) == colorCheckingFor){
                ctx.setPixel(horsemen[i].x, horsemen[i].y, colorPaintingTo);
                pixels.push(horsemen[i]);
            }
        }
    }

    // Return the list
    return pixels;
}
function floodFill(ctx, x, y, currentColor){

    // Where to start the fill
    var toFill = ctx.getPixel(x, y);

    // Create a stack with the first cords
    var fillStack = [{x:x, y:y}];

    // This will keep returning an array untill there's no pixels left to fill
    while(fillStack.length > 0){

        // Get the next in line
        var pixel = fillStack.shift();

        // Get neighbors & fill this one
        var pixels = getPixels(ctx, toFill, currentColor, pixel.x, pixel.y);

        // Append the list of neighbors returned to the end of the stack
        fillStack = fillStack.concat(pixels);
    }

    // Update the canvas
    ctx.updateCanvas();
}
  1. function getPixels(ctx, colorCheckingFor, colorPaintingTo, x, y){
  2.     // Holder for the neighboring pixels that are the color we're filling
  3.     var pixels = new Array();
  4.     // Go ahead and paint this one
  5.     ctx.setPixel(x, y, colorPaintingTo);
  6.     // 4 direction
  7.     var horsemen = [{x:x, y:y-1}, {x:x, y:y+1}, {x:x-1, y:y}, {x:x+1, y:y}];
  8.     // 8 direction (results in 2 * as many checks but will bleedthrough diagnal lines)
  9.     if(bleedThrough){horsemen = horsemen.concat([{x:x-1, y:y-1}, {x:x+1, y:y-1}, {x:x-1, y:y+1}, {x:x+1, y:y+1}]);}
  10.     // Check the 4 or 8 neighboring pixels
  11.     for(var i=0; i<horsemen.length; i++){
  12.         // Make sure the pixel is inbounds, Opera will hang if it's not
  13.         if((horsemen[i].x > -1) && (horsemen[i].x < ctx.canvas.width) && (horsemen[i].y > -1) && (horsemen[i].y < ctx.canvas.height)){
  14.             // If it's the color we're filling, paint it & add it to the list to check its' neighbors
  15.             if( ctx.getPixel(horsemen[i].x, horsemen[i].y) == colorCheckingFor){
  16.                 ctx.setPixel(horsemen[i].x, horsemen[i].y, colorPaintingTo);
  17.                 pixels.push(horsemen[i]);
  18.             }
  19.         }
  20.     }
  21.     // Return the list
  22.     return pixels;
  23. }
  24. function floodFill(ctx, x, y, currentColor){
  25.     // Where to start the fill
  26.     var toFill = ctx.getPixel(x, y);
  27.     // Create a stack with the first cords
  28.     var fillStack = [{x:x, y:y}];
  29.     // This will keep returning an array untill there's no pixels left to fill
  30.     while(fillStack.length > 0){
  31.         // Get the next in line
  32.         var pixel = fillStack.shift();
  33.         // Get neighbors & fill this one
  34.         var pixels = getPixels(ctx, toFill, currentColor, pixel.x, pixel.y);
  35.         // Append the list of neighbors returned to the end of the stack
  36.         fillStack = fillStack.concat(pixels);
  37.     }
  38.     // Update the canvas
  39.     ctx.updateCanvas();
  40. }

Post Information

  • Total Posts in this topic: 1 post
  • Users browsing this forum: No registered users and 125 guests
  • You cannot post new topics in this forum
  • You cannot reply to topics in this forum
  • You cannot edit your posts in this forum
  • You cannot delete your posts in this forum
  • You cannot post attachments in this forum
 
cron
 

© 1998-2014. Ozzu® is a registered trademark of Unmelted, LLC.