0% found this document useful (0 votes)
67 views

By William Malone: C P B T Html5 J S

This document discusses creating a paint bucket tool in HTML5 Canvas and JavaScript. It begins by explaining how to access pixel data from a Canvas using the imageData object. It then outlines the steps of a flood fill algorithm to fill connected areas of similar color. The algorithm works by pushing starting pixel coordinates to a stack, popping them to iterate through neighbors, and coloring pixels that match the starting color while adding neighboring pixels to the stack.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
67 views

By William Malone: C P B T Html5 J S

This document discusses creating a paint bucket tool in HTML5 Canvas and JavaScript. It begins by explaining how to access pixel data from a Canvas using the imageData object. It then outlines the steps of a flood fill algorithm to fill connected areas of similar color. The algorithm works by pushing starting pixel coordinates to a stack, popping them to iterate through neighbors, and coloring pixels that match the starting color while adding neighboring pixels to the stack.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

7/31/2019 Create a Paint Bucket Tool in HTML5 and JavaScript

0,0,0,255, 255,255,255,255,
203,53,148,255].
CREATE A PAINT BUCKET
TOOL IN HTML5 AND
JAVASCRIPT 

by  William Malone


This tutorial will show how to create a simple paint
bucket tool on an HTML5 Canvas using JavaScript. We
will be implementing a flood fill algorithm using the
HTML5 imageData object for pixel manipulation.

First we will learn how to determine the colors of the


pixel on an HTML5 canvas. Then we will go step by
step through an implementation of a flood fill algorithm
in JavaScript. Let's get started.
var imgDataArray =
context.getImageData(0, 0, 2, 2);
The HTML5 Canvas Pixel // imageData.data[0] = [255,0,0,255]
Before we start filling anything, we need to know the /* red */
// imageData.data[1] = [0,0,0,255]
colors of our image. We can utilize HTML5 imageData
object to describe our image as an array of pixel data /* black */
or more specifically a CanvasPixelArray object. Each // imageData.data[2] = [255,255,255,255]
pixel is in the form: [R, G, B, A] where R is the red /* white */
component, G is green component, B is the blue // imageData.data[3] = [203,53,148,255]
component, and A is the alpha. /* purple */

The example image we will use throughout this article


is 3 pixels wide and 5 pixels high. It consists of 15
pixels, 13 white [255,255,255,255] and 2
black[0,0,0,255]. The black pixels are in positions
3 and 7.

The getImageData method has four parameters:


location (x,y) and dimension (width, height). The
JavaScript code looks like this:
var imgData = context.getImageData(x, y,
width, height);

The image data for an image consisting of one red


pixel is described as [255, 0, 0, 255].
var imageData =
context.getImageData(0,0,canvasWidth,can
vasHeight);

// imageData.data = [
// 255,255,255,255, 255,255,255,255,
0,0,0,255,
// 255,255,255,255, 255,255,255,255,
255,255,255,255,
// 0,0,0,255, 255,255,255,255,
255,255,255,255,
var imgData = context.getImageData(0, 0, // 255,255,255,255, 255,255,255,255,
1, 1); 255,255,255,255,

// imageData.data[0] = [255,0,0,255] // 255,255,255,255, 255,255,255,255,


255,255,255,255]

The imageData for a four pixel image (red, black, white,


purple) is described as[255,0,0,255,
Preview Flood Fill Animation

http://slidepdf.com/reader/full/create-a-paint-bucket-tool-in-html5-and-javascript 1/5
7/31/2019 Create a Paint Bucket Tool in HTML5 and JavaScript

Now that we have demonstrated how we will get pixel newPos = pixelStack.pop();
data from the HTML5 Canvas via the imageData object x = newPos[0];
we will go step by step through the process of a flood y = newPos[1];
fill algorithm implemented with JavaScript.
...
The following animation shows the steps of the flood fill
algorithm on our example image:
}

We travel upward pixel by pixel until we find the image


boundary or a pixel that does not match the fill color.
We use another while loop and the
function matchStartColor which returns true if the
color matches the starting color.

Flood Fill Step by Step


Our objective is to fill of all similarly colored pixels
connected to the starting pixel with a new fill color. In pixelPos = (y*canvasWidth + x) * 4;
our example the starting pixel is white and the fill color while(y-- >= 0 &&
is Watermelon Duck purple. matchStartColor(pixelPos))
First push the starting pixel's x and y coordinate into an {
array called pixelStack. Let's start at pixel location pixelPos -= canvasWidth * 4;
(1,3). }
...
}

function matchStartColor(pixelPos)
{
var r = colorLayer.data[pixelPos];
var g = colorLayer.data[pixelPos+1];
var b = colorLayer.data[pixelPos+2];

return (r == startR && g == startG &&


b == startB);
}

After travelling up 3 pixels we encounter the edge of


var pixelStack = [[1, 3]]; the image. We know this because ybecomes -1 the
condition y-- >= 0 fails. Since we have gone too far
Next we create a while loop which will pop the most
up, we increment yand update the
recently saved pixel location inpixelStack. In the
case of our example, we pop the only coordinate (1,3) variable pixelPos. Instead of just incrementing the
and assign those values to the pixelPos by one, we increment by the canvas width
variables x and y respectively. times 4.
We initalize a couple of new
variables reachLeft and reachRight to false.
These will be used to manage additions to our pixel
stack. We will see how soon.

We create another while loop, this time travelling


downward. Unlike how we went up blindly, the way
down will involve adding new pixels to the stack and
coloring pixels.

Let's start by coloring our first pixel at (1,0) with the fill
color purple.

while(pixelStack.length)
{

http://slidepdf.com/reader/full/create-a-paint-bucket-tool-in-html5-and-javascript 2/5
7/31/2019 Create a Paint Bucket Tool in HTML5 and JavaScript

Now we look to the right. The pixel on the right is black


which does not match the starting pixel so we do not
add it to the stack. We continue the march downward.

 
pixelPos += canvasWidth * 4;
++y;
reachLeft = false;
reachRight = false;
while(y++ < canvasHeight-1 && if(x < canvasWidth-1)
matchStartColor(pixelPos)) {
{ if(matchStartColor(pixelPos + 4))
colorPixel(pixelPos); {
if(!reachRight)
{
... pixelStack.push([x + 1, y]);
} reachRight = true;
}
}
After filling the pixel at (1,0) we must now determine if
else if(reachRight)
its neighbors to the left and right need filling too. First
let's investigate the pixel to the left. {
reachRight = false;
Ignoring any pixels with x position less than zero we }
check if the color matches the start color. In our }
example the pixel to the left is white just like our start
pixel, so we add it to the stack to handle later. We also pixelPos += canvasWidth * 4;
set the boolean reachLeft to true. This will prevent
us adding pixels that will eventually handled by the
downward march of the pixel we just added. The pixel below matches our starting pixel so we color
it purple.

if(x > 0)
{ We look to the left of our new purple pixel and find it
if(matchStartColor(pixelPos - 4)) matches, but reachLeft is true so we don't add it to
{ the stack. The right pixel also matches but its
if(!reachLeft){ variable reachRight is false so we do add it to the
pixelStack.push([x - 1, y]); stack.
reachLeft = true;
}
}
else if(reachLeft)
{
reachLeft = false;
}
}

http://slidepdf.com/reader/full/create-a-paint-bucket-tool-in-html5-and-javascript 3/5
7/31/2019 Create a Paint Bucket Tool in HTML5 and JavaScript

Color the pixel below. The


booleans reachLeft and reachRight to the right
and left are true so we don't add them to the stack.

 
Color the next pixel. Look to the left, no match this time
so we change reachLeft to false. Looking to the
right matches but reachRight is true so we do
nothing.
We have reached the bottom of the image thus are
done with the column of our starting pixel.

Color the next pixel. It happens to be the starting pixel


but other than for reasons of nostalgia it's not
significant.

Empty the Stack


The first column has been filled however they are still
pixels in the stack which means there are more
columns to fill. Pop the next pixel from the stack which
is the pixel (0,3).

We look to the left and the color matches. Since we


changed reachLeft to false last time, we add it to
the stack. The right side matches too, but its
boolean reachRight is true so we don't add it.

We continue the process until the pixel stack is empty


and there are no more columns to fill.

http://slidepdf.com/reader/full/create-a-paint-bucket-tool-in-html5-and-javascript 4/5
7/31/2019 Create a Paint Bucket Tool in HTML5 and JavaScript

Eight pixels later we have filled all the matching pixels reachLeft = false;
in our example image. Although our example image }
was small the process is the same for larger images. }

if(x < canvasWidth-1)


{
if(matchStartColor(pixelPos + 4))
HTML5 JS Paint Bucket Code {
if(!reachRight)
{
A few things to note about the code: pixelStack.push([x + 1, y]);
 
 Internet Explorer does not support HTML5 pixel reachRight = true;
manipulation even with use ofExplorerCanvas  }
 
 Firefox does not support pixel manipulation locally. It will }
work when hosted on a site, but if you try to test locally else if(reachRight)
you will what Firebug describes as 'Security error" code: {
"1000'. The best explanation for this error was described reachRight = false;
by skarabaeus here.  }
}

pixelPos += canvasWidth * 4;
}
}
context.putImageData(colorLayer, 0, 0);

function matchStartColor(pixelPos)
{
var r = colorLayer.data[pixelPos];
var g = colorLayer.data[pixelPos+1];
var b = colorLayer.data[pixelPos+2];

pixelStack = [[startX, startY]]; return (r == startR && g == startG &&


b == startB);
while(pixelStack.length) }
{
var newPos, x, y, pixelPos, reachLeft, function colorPixel(pixelPos)
reachRight; {
newPos = pixelStack.pop(); colorLayer.data[pixelPos] =
x = newPos[0]; fillColorR;
y = newPos[1]; colorLayer.data[pixelPos+1] =
fillColorG;
pixelPos = (y*canvasWidth + x) * 4; colorLayer.data[pixelPos+2] =
while(y-- >= drawingBoundTop && fillColorB;
matchStartColor(pixelPos)) colorLayer.data[pixelPos+3] = 255;
{ }
pixelPos -= canvasWidth * 4;
}
pixelPos += canvasWidth * 4; Download Source Code
++y;
reachLeft = false;
reachRight = false;
while(y++ < canvasHeight-1 &&
Code Available at github
matchStartColor(pixelPos)) https://github.com/williammalone/HTML5-Paint-Bucket-Tool 
{
colorPixel(pixelPos);
Source:
if(x > 0) http://www.williammalone.com/articles/html5-
{
canvas-javascript-paint-bucket-tool/ 
if(matchStartColor(pixelPos - 4))
{
if(!reachLeft){
pixelStack.push([x - 1, y]);
reachLeft = true;
}
}
else if(reachLeft)
{

http://slidepdf.com/reader/full/create-a-paint-bucket-tool-in-html5-and-javascript 5/5

You might also like