Mobile Web

Task: Touch Paint

This task, based on the TouchPaint sample delivered with the Tizen SDK, demonstrates how you can use the Touch Events version 1 API to create a simple paint application using the touch events and the Canvas element. For more information on the sample functionality and creating the sample with the full source code, see TouchPaint.

This task consists of the following parts:

This sample is a fully functional application for implementing a basic drawing application.

Defining the Application Layout

The TouchPaint sample application layout contains only 1 screen: the main screen that displays a canvas on which you can draw with a finger.

The following figure shows the main screen of the application.

Figure: TouchPaint screen

TouchPaint screen

Defining the Main Screen

  1. index.html Source File

    The main screen displays a Canvas element, and a description area. The description area defines a color picker and a slider as <input> elements to allow the user can select the color and line width of their strokes. A button is also defined to allow the user to clear the canvas.

    <body>
       <h2>Touch paint</h2>
       <canvas class="canvas addHeight">
          This browser is not supported
       </canvas>
       <div class="desc">
          <label>Color: <input type="color" class="strokeColor"></label>
          <label>Line width: 
             <input type="range" min="5" max="30" step="5" value="5" class="strokeWidth">
          </label>
       </div>
       <nav></nav>
       <button class="clearBtn">Clear</button>
    </body>
    

Drawing on Canvas

This section builds upon the elements described in Handling Touch Events and Controlling Multi-point Touches.

Initializing the Canvas

  1. main.js Source File

    Define event listeners and handlers to manage the touchstart, touchmove, and touchend events on the canvas.

    window.onload = function() 
    {
       canvas = document.querySelector(".canvas");
       var context = canvas.getContext("2d");
    
       /* Canvas size setting */
       canvas.width = document.width;
       canvas.height = document.height - 130;
        
       /* Touch event listeners */
       canvas.addEventListener("touchstart", touchStartHandler, false);
       canvas.addEventListener("touchmove", touchMoveHandler, false);
       canvas.addEventListener("touchend", touchEndHandler, false);
    }    
    

Drawing Lines Based on Touch Events

The line drawing functionality is implemented in the main.js file.

  1. Drawing based on Retrieved Event Coordinates

    To draw an image with fingers, you must find out the coordinates of the triggered touch events. Retrieve the coordinates in the touchMoveHandler() event handler.

    function touchMoveHandler(e) 
    {
       touches = e.touches.item(0);
        
       log.innerHTML ='<strong>pageX:</strong> ' + touches.pageX + 
                      '<br><strong>pageY:</strong> ' + touches.pageY;
        
       context.fillStyle = "#f00";
        
       /* For accurate coordinates, calculate minus offset(Left) from page(X) */
       context.fillRect(touches.pageX - this.offsetLeft, 
                        touches.pageY - this.offsetTop, 5, 5);
    }
    

    Every time a touchmove event is fired, the pageX and pageY coordinates of the page are shown in the log, and a quadrangle of 5 x 5 pixels is created. However, since it is difficult to implement line drawing this way, use the changedTouches attribute instead, as shown below.

  2. Drawing based on Stored Event Coordinates

    Create a drawPath array that remembers the order of the triggered touch events, and edit the touchStartHandler() and touchMoveHandler() event handlers to define the lines the user is drawing.

    1. When a touchstart event is triggered, the event handler stores the initial position.

      var touches;
      /* Remember the order of the touch events */ 
      var drawPath = new Array();
      /* Flag for displaying the touching point */
      var isMoved = false;
          
      function touchStartHandler(e) 
      {
         /* Store the current touch information (coordinates) */
         touches = e.changedTouches;
         drawPath.push(touches[0]);  
      }
      
    2. When a touchmove event is triggered, the coordinates of the previously triggered touchmove event stored in the changedTouches attribute are saved in the drawPath array and assigned as a parameter value of the moveTo() method. The coordinates of the current touchmove event are assigned as a parameter value of the lineTo() method, and thus the connected line is indicated.

      function touchMoveHandler(e) 
      {
         isMoved = true;
         touches = e.changedTouches;
          
         /* Assign the line style to be drawn */ 
         context.lineWidth = strokeWidth;
         context.strokeStyle = strokeColor;
         context.lineJoin = "round";
      
         for (var i = 0; i < touches.length; i++) 
         {
            var idx = drawPathSetting(touches[i].identifier);
          
            /* Draw a line from the stored coordinates to the current coordinates */
            context.beginPath();
            context.moveTo(drawPath[idx].pageX - this.offsetLeft, 
                           drawPath[idx].pageY - this.offsetTop);
            context.lineTo(touches[i].pageX - this.offsetLeft, 
                           touches[i].pageY - this.offsetTop);
      
            context.closePath();
            context.stroke();
      
            /* Delete the stored coordinates and store the current ones */    
            drawPath.splice(idx, 1, touches[i]); 
         }
         e.preventDefault();
      }
      
    3. When a touchend event is triggered, it deletes the stored position.

      function touchEndHandler() 
      {
         /* Display the touching point */
         if (!isMoved)
         {
            var startPoint = (Math.PI/180)*0;
            var endPoint = (Math.PI/180)*360;
            context.fillStyle = strokeColor;
            context.beginPath();
            context.arc(touches[0].pageX - this.offsetLeft, touches[0].pageY - this.offsetTop, 
                        strokeWidth/2, startPoint, endPoint, true);
            context.closePath();
            context.fill();
         }
         isMoved=false;
         drawPath.length = 0; /* Initialize the stored coordinates */ 
      }
      
  3. Drawing based on Multi-point Touches

    If the application is controlled with fingers, you must handle multi-point touches (a mouse-controlled application only create one touch at a time and only needs 2 events to handle it). To manage multi-touches, the index of the touches[index] array is used.

    The drawPathSetting() method allows the application to handle multi-point touches since the existing and current coordinates of the touch events are connected respectively.

    The touchMoveHandler() event handler uses the drawPathSetting() method to return the index of the drawPath array (which contains the touch event details saved so far). Since the information is similar to the identifier of the touch event which has been currently triggered, the array enables each touch event to have its own information.

    function drawPathSetting(idx) 
    {
       for (var i = 0; i < drawPath.length; i++) 
       {
          var _idx = drawPath[i].identifier;
          if (_idx === idx) 
          {
             return i;
          }
       }
    
       return -1;
    }    
    

Using Drawing Features

Initializing Drawing

  1. main.js Source File

    Variables are declared to store and display the color and line width selection of the user.

    var strokeColorSel, strokeWidthSel;
    var strokeColor;
    var strokeWidth = 5;
    

Applying the Stroke Styles

  1. main.js Source File
    1. Add the color and line width values that the user has selected to the applicable variables, and define event handlers to track changes in the user selection.
      window.onload = function() 
      {
         strokeColorSel = document.querySelector(".strokeColor");
         strokeWidthSel = document.querySelector(".strokeWidth");
          
         /* Add event listeners */
         strokeColorSel.addEventListener("change", changeStrokeColor, false);
         strokeWidthSel.addEventListener("change", changeStrokeWidth, false);
      
    2. If the user changes the color or line width, the event handlers call the changeStrokeColor() or changeStrokeWidth() method to set the new style value.
         function changeStrokeColor() 
         {
            strokeColor = this.value;
         }
      
         function changeStrokeWidth() 
         {
            strokeWidth = this.value;
         }
      }
      
    3. To use the style values, apply them in the touchMoveHandler() event handler, which draws the user's strokes on the canvas.
      function touchMoveHandler(e) 
      {
         context.lineWidth = strokeWidth; /* Selected line width */ 
         context.strokeStyle = strokeColor; /* Selected line color */ 
      
         /* Draw the strokes */
      } 
      
Go to top