In this article we will be building a simple sketch pad
application in JavaScript from scratch. It will have a brush and eraser with
variable size. For simplicity, lets limit it to draw and erase. The finished application can be viewed here.
The requirements for
this application are basic knowledge of html and JavaScript.
The file structure of application looks like this:
- index.js : contains the html code
- script.js : contains the JavaScript of the application
First
of all let us start with the html file. We will need one canvas for
rendering, one textbox for changing the stroke of brush and one button
for toggling between brush and eraser. The html code is shown below :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <html> <head> <title> SketchPad </title> </head> <body> <!--Canvas to draw--> <canvas id="canvas" height="500px" width="500px" style="border-style:solid"></canvas> <br> <!--Textbox to change the size of stroke--> <input type="text" id="size" value="1" /> <!--Button to switch eraser and pen--> <button id="toggle">Brush/eraser</button> <!--JavaScript file--> <script type="text/javascript" src="script.js"></script> </body> </html> |
The canvas is given the height and width of ‘500px’ and border style ‘solid’ so we can view it clearly. It is given the id ‘canvas’ to reference it from script.js file. Another element is a textbox with id ‘size’ and its initially set to 1 i.e. the initial brush size is 1. The next one is a button with id ‘toggle’. The <script> tag loads the ‘script.js’ file. It is inserted at last to make page load faster. That’s all for HTML. Open it in your browser and you will see a white square and some controls.
Now let’s move on to scripting part. Initially we get reference to the canvas so that we can draw on it.
1 2 3 4 | var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); ctx.lineCap = 'round'; ctx.lineJoin = 'round'; |
In order to use canvas we get reference to the context of
the canvas. The parameter ‘2d’ is passed, which specifies that we are working
in 2D. To draw smooth and round lines linecap and linejoin property of ctx are set to round. Next, we declare some variables to hold mouse
coordinates, tool type and mousedown flag.
1 2 3 4 5 6 | var iX, //initial iY,//and fX,//final fY,//positions mousedown = false, // initially set mousedown to false tool = 'brush'; |
(iX,iY) and (fX,fY) hold initial and final mouse position.
‘mousedown’ and ‘tool’ specifies mouse status and current tool. If mouse is
pressed mousedown is set to true, else false. The tool is initially set to
‘brush’.
Then we take care of
three mouse events on canvas : mousedown, mouseup, mousemove. When mouse
is down/pressed, the coordinate of mouse at that instant is stored in iX, iY and mousedown is set to true. Similarly,
when the pressed mouse is released/up mousedown is set to false.
1 2 3 4 5 6 7 8 9 10 11 | canvas.onmousedown = function (e) { // on mousedown set initial positions iX = e.pageX; iY = e.pageY; mousedown = true; } canvas.onmouseup = function (e) { // on mouse up set 'mousedown' to false mousedown = false; } |
The actual magic happens when the mouse is moved . Let’s explain it line by line.
Initial line checks whether the mouse is pressed or not. If pressed, the code inside the braces will execute. In our case let’s assume its pressed . Then it sets the final positions (fX, fY) to the latest mouse coordinates. The next if..else block checks whether current tool is brush or eraser. If its eraser it sets the brush color to white, else to black.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | canvas.onmousemove = function (e) { // draw if mouse is pressed if (mousedown) { //set fX & fY to final position of cursor fX = e.pageX; fY = e.pageY; // check if its brush or eraser if (tool === 'brush') ctx.strokeStyle = 'black'; else ctx.strokeStyle = 'white'; // draw line from (iX,iY) to (fX, fY) ctx.beginPath(); ctx.moveTo(iX, iY); ctx.lineTo(fX, fY); ctx.stroke(); ctx.closePath(); //set initial positions to final positions iX = fX; iY = fY; } } |
The above code is the main logic of the application. The moveTo() function sets the initial position of line to (iX,iY) and lineTo() sets final position to (fX,fY). Ctx.draw() draws a line joining the two specific points. Each line is drawn irrespective of the previous one, so beginpath() and closepath() are called each time at the beginning and end. Once a line is drawn, we then set the (iX,iY) to (fX,fY) for drawing next line.
The same process happens again and again each time the mouse is moved. What it basically does is that it joins initial and final position of a mouse once it is moved. Save the code and run it in browser, you can draw like pencil in the canvas.
Finally, we add some more features to our application so that we can increase the size of brush and erase what we draw.
1 2 3 4 5 6 7 8 9 10 | document.getElementById('size').onkeyup = function (e) { //set linewidth of ctx to the value of textbox ctx.lineWidth = parseInt(document.getElementById('size').value); } document.getElementById('toggle').onclick = function () { //toggle tool if (tool === 'brush') tool = 'eraser'; else tool = 'brush'; } |
That’s it. Now open the ‘index.html’ file in your browser and view your sketchpad in action.
What we made it just a simple application. You can add more features like:
- Color Picker
- Separate cursor icon for pencil and eraser
- Option to change background and pencil color
- Save canvas as image file etc.
Have any queries ? Please do ask in the comments
below. I will be happy to answer.
Happy Coding !!
Nice tutorial
ReplyDelete