Touch Paint(M) Sample Overview

The Touch Paint sample application demonstrates how you can create a simple paint application using the touch events and a Canvas element.

The following figure illustrates the main screen of Touch Paint.

Figure: Touch Paint screens

Touch Paint screen

The application opens with the main screen where you can see the canvas. You can draw on the canvas with your finger.

To change the color or line width of your drawing, use the Color and Line width controls. To clear the canvas, click the Clear button.

Source Files

You can create and view the sample application project including the source files in the IDE.

File name Description
config.xml This file contains the application information for the platform to install and launch the application, including the view mode and the icon to be used in the device menu.
index.html This is a starting file from which the application starts loading. It contains the layout of the application screens.
js/main.js This file contains the code for handling the playing functionality of the application.
css/style.css This file contains the CSS styling for the application UI.

Implementation

The init() method, which is called when the whole DOM content is loaded, initializes the application. At this point the canvas size is calculated and the event listeners for all UI elements used in the application are defined.

/* main.js */
var canvas = null,
context = null,
content = null,
drawPath = {},
strokeColor = '',
strokeWidth = 5;

function init() 
{
   var strokeColorSel = document.querySelector('.color-input'),
       strokeWidthSel = document.querySelector('.range-input'),
       clearBtn = document.querySelector('.clear-input');

   content = document.querySelector('.content');
   canvas = document.querySelector('.canvas');
   context = canvas.getContext('2d');

   /* Canvas size setting */
   canvas.width = content.clientWidth;
   canvas.height = content.clientHeight;

   /* Touch events handler */
   canvas.addEventListener('touchstart', touchStartHandler, false);
   canvas.addEventListener('touchend', touchEndHandler, false);
   canvas.addEventListener('touchmove', touchMoveHandler, false);

   /* Apply eventHandler */
   strokeColorSel.addEventListener('change', changeStrokeColor, false);
   strokeWidthSel.addEventListener('change', changeStrokeWidth, false);
   clearBtn.addEventListener('click', clearCanvas, false);

   /* Add eventListener for tizenhwkey */
   window.addEventListener('tizenhwkey', function onTizenHwKey(e) 
   {
      if (e.keyName === 'back') 
      {
         try 
         {
            tizen.application.getCurrentApplication().exit();
         } 
         catch (err) 
         {
            console.error('Error: ', err);
         }
      }
   });
}

When the touchstart event is triggered, the touchStartHandler() method is called. It uses the changedTouches array event property to obtain access to the data of the current touch object. From the application point of view, the most important data are the touch coordinates stored as pageX and pageY properties of the touch object. The current touch is saved to the drawPath object, which is an associative array indexed with the identifier parameter of the current touch. The stored touch parameters are used to draw the start point when drawing a line. They are also used by the touchMoveHandler() method to obtain the start point while drawing line. The application draws the start point using the methods provided by the canvas context. The fillStyle parameter allows setting the color for drawing.

The beginPath() method begins drawing the path. The arc() method allows drawing points and circles with the given radius (strokeWidth / 2) at the location specified by the given touch coordinates. The closePath() method creates a path from the current point back to the starting point. The fill() method fills the current drawing with the previously set color.

/* main.js */
function touchStartHandler(e) 
{
   var touch = e.changedTouches[0];

   drawPath[touch.identifier] = touch;

   context.fillStyle = strokeColor;
   context.beginPath();
   context.arc(drawPath[touch.identifier].pageX - content.offsetLeft, 
               drawPath[touch.identifier].pageY - content.offsetTop,
               strokeWidth / 2, 0, Math.PI * 2, true);
   context.closePath();
   context.fill();
}

When the touchmove event is triggered, the touchMoveHandler() method is called. At the beginning it sets up the canvas context parameters. The linewidth parameter allows setting the width of the drawing line. The lineJoin parameter with its value set to round allows rounding the corners when the two lines meet. In the next steps the touchHanderMethod() method iterates through the changedTouches event property and checks whether the drawPath object contains an attribute equal to the identifier of the iterated touch. If the condition is true it means that iterated touch is still active (the finger still touches the screen) and the touchMoveHandler() method can continue drawing. The application uses the moveTo() method of the canvas context to set up the start point coordinates of drawing line. It uses the last saved coordinates of the iterated touch.

The lineTo() method of the canvas context adds a new point to create a line. It uses the current coordinates of the iterated touch.

The stroke() method of the canvas context draws a line using the moveTo() and lineTo() methods.

At the end the drawPath object parameters are updated in order to store the current touch coordinates for the next touchMoveHandler() method call.

/* main.js */
function touchMoveHandler(e) 
{
   var touches = e.changedTouches,
       touchesLength = touches.length,
       currentDrawPath = null,
       i = 0;

   context.lineWidth = strokeWidth;
   context.strokeStyle = strokeColor;
   context.lineJoin = 'round';

   for (i = 0; i < touchesLength; i += 1) 
   {
      currentDrawPath = drawPath[touches[i].identifier];
      if (currentDrawPath !== undefined) 
      {
         context.beginPath();
         context.moveTo(currentDrawPath.pageX - content.offsetLeft, currentDrawPath.pageY - content.offsetTop);
         context.lineTo(touches[i].pageX - content.offsetLeft, touches[i].pageY - content.offsetTop);
         context.closePath();
         context.stroke();

         drawPath[touches[i].identifier] = touches[i];
      }
   }
   e.preventDefault();
}

When the touchend event is triggered, the touchEndHandler() method is called. This method updates the drawPath object to remove the information about the touch that no longer exists.

/* main.js */
function touchEndHandler(e) 
{
   var touch = e.changedTouches[0];

   delete drawPath[touch.identifier];
}