Wearable 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 2 screens: the main screen displaying a canvas on which you can draw with a finger, and the Options screen which allows you to set up the color and the thickness of the line being drawn.

The following figure shows the main screens of the application.

Figure: TouchPaint screens

TouchPaint screens

Defining the Main Screen

  1. index.html Source File

    The main screen displays a Canvas element and 2 buttons (for accessing the Options screen and for clearing the canvas area).

    <div class="ui-page ui-page-active" id="main">
       <div class="ui-header" id="main-header" data-position="fixed">
          <h2 class="ui-title">TouchPaint</h2>
       </div>
       <div class="ui-content" id="main-content"></div>
       <div class="ui-footer ui-grid-col-2" id="main-footer">
          <button type="button" class="ui-btn" id="main-options-btn">Options</button>
          <button type="button" class="ui-btn" id="main-clear-btn">Clear</button>
       </div>
    </div>
    

    The above code snippet does not contain the canvas element, which is added to the <div id="main-content"> element by the JavaScript code after the application start.

Defining the Options Screen

  1. index.html Source File

    The Options screen displays a slider element, line preview, four-color (white, red, green, and blue) picker and 2 buttons (Cancel and OK).

    The slider allows the user to change the line width. Each slider position change results in a change in the line preview thickness. A tap action on the color picker results in a change in the line preview color. A tap action on the buttons moves the user to main screen without or with saving the changes.

    <div class="ui-page" id="options">
       <div class="ui-header" data-position="fixed">
          <h2 class="ui-title">Options</h2>
       </div>
       <div class="ui-content">
          <input type="range" min="1" max="20" value="1" id="options-range"></input>
          <div id="options-preview"></div>
          <div id="options-colors">
             <div id="options-colors-white" class="options-colors"></div>
             <div id="options-colors-red" class="options-colors"></div>
             <div id="options-colors-green" class="options-colors"></div>
             <div id="options-colors-blue" class="options-colors"></div>
          </div>
       </div>
       <div class="ui-footer ui-grid-col-2">
          <button type="button" class="ui-btn" id="options-cancel-btn">Cancel</button>
          <button type="button" class="ui-btn" id="options-ok-btn">OK</button>
       </div>
    </div>
    

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

    The canvas is initialized in JavaScript, and includes the size calculation, ID setting, and adding of the element to the main page content.

    function initCanvas() 
    {
       canvas = document.createElement('canvas');
       canvas.width = window.innerWidth;
       canvas.height = window.innerHeight - header.offsetHeight - footer.offsetHeight;
       canvas.setAttribute('id', 'main-canvas');
       content.appendChild(canvas);
       context = canvas.getContext('2d');
    }
    

Drawing Lines Based on Touch Events

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

  1. main.js Source File
    1. Define event listeners and handlers to manage the touchstart, touchmove, and touchend events on the canvas.

      function addCanvasListeners() 
      {
         canvas.addEventListener('touchstart', onCanvasTouchStart);
         canvas.addEventListener('touchend', onCanvasTouchEnd);
         canvas.addEventListener('touchmove', onCanvasTouchMove);
         footer.addEventListener('touchend', onFooterTouchEnd);
      }
      
    2. Handle the events:

      • At touch start, an arc is drawn in case of a single tap performed by the user.
      • On touch move, a line is drawn trough the touch path with a given width and color.

        The drawPath array stores the order of the triggered touch events, which are used to draw a line that follows the finger.

      • At touch end, the touch event is removed from the drawPath array, stopping the line drawing.
      function onCanvasTouchStart(ev) 
      {
         var touch = ev.changedTouches[0];
      
         drawPath[touch.identifier] = touch;
      
         context.fillStyle = strokeColor;
         context.beginPath();
         context.arc(drawPath[touch.identifier].pageX - canvas.offsetLeft,
                     drawPath[touch.identifier].pageY - canvas.offsetTop - header.offsetHeight,
                     strokeWidth / 2,
                     0,
                     Math.PI * 2,
                     true);
         context.closePath();
         context.fill();
      }
      
      function onCanvasTouchEnd(ev) 
      {
         var touch = ev.changedTouches[0];
      
         delete drawPath[touch.identifier];
      }
      
      function onCanvasTouchMove(ev) 
      {
         var touches = ev.changedTouches,
             touchesLength = touches.length,
             currentDrawPath = null,
             i = 0;
      
         context.lineWidth = strokeWidth + ADDITIONAL_LINE_WIDTH;
         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 - canvas.offsetLeft + HALF_PIXEL,
                              currentDrawPath.pageY - canvas.offsetTop + HALF_PIXEL - header.offsetHeight);
               context.lineTo(touches[i].pageX - canvas.offsetLeft + HALF_PIXEL,
                              touches[i].pageY - canvas.offsetTop + HALF_PIXEL - header.offsetHeight);
               context.closePath();
               context.stroke();
      
               drawPath[touches[i].identifier] = touches[i];
            }
         }
         ev.preventDefault();
      }
      

Using Drawing Features

Changing the Line Thickness

  1. options.js Source File

    The user changes the line thickness using a slider. The new slider value is set as the width of the preview element, as well as a value in the options object.

    function onRangeChange(ev) 
    {
       setPreviewHeight(ev.target.value);
    }
    function setPreviewHeight(value) 
    {
       preview.style.height = value + 'px';
    }
    function setOptionValues() 
    {
       options.setStrokeWidth(range.value);
    }
    
  2. main.js Source File

    During drawing, the selected thickness is applied to the line being drawn.

    function getOptionValues() 
    {
       strokeWidth = options.getStrokeWidth();
    }
    
    context.lineWidth = strokeWidth + ADDITIONAL_LINE_WIDTH;
    

Changing the Line Color

  1. options.js Source File

    The user changes the line color by selecting it from the color picker. The new color is set as the preview element background, as well as a value in the options object.

    function onWhiteTap() 
    {
       preview.style.backgroundColor = '#fff';
    }
    
    function setOptionValues() 
    {
       o.setStrokeColor(preview.style.backgroundColor);
    }
    
  2. main.js Source File

    During drawing, the selected color is applied to the line being drawn.

    function getOptionValues() 
    {
       strokeColor = o.getStrokeColor();
    }
    
    context.strokeStyle = strokeColor;
    
Go to top