Canvas Watch Sample Overview

The Canvas Watch sample application demonstrates how you can create a simple application using the Canvas element.

The following figure illustrates the main screen of the Canvas Watch.

Figure: Canvas Watch screen

Canvas Watch screen

Watch applications are available in system setting:

  • Open Settings on the wearable emulator/device
  • Tap Clock
  • Move right or left to select a Watch application

The application opens with the screen that shows the current time in an analog watch face.

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.
css/style.css This file contains the CSS styling for the application UI.
index.html This is a starting file from which the application starts loading. It contains the layout of the application screen.
js/app.js This file contains the code for handling the main functionality of the application.

Implementation

For watch applications, a specific category (http://tizen.org/category/wearable_clock) must be set in config.xml.

<!-- config.xml -->	

<widget xmlns="http://www.w3.org/ns/widgets">
   <tizen:category name="http://tizen.org/category/wearable_clock" />
</widget>

The getContext() method returns an object which provides methods and properties on the canvas.

/* js/app.js */

canvasLayout = document.querySelector("#canvas-layout");
ctxLayout = canvasLayout.getContext("2d");


// Set the canvases square
canvasLayout.width = document.body.clientWidth;
canvasLayout.height = canvasLayout.width;

The application uses the properties and methods of the getContext("2d") object to draw circles, lines, and texts on the canvas.

  • The arc() method is used to create circle elements:
    To created circle, set start angle to 0 and the end angle to 2 * Math.PI.
  • /* js/app.js */
    
    function renderCircle(context, center, radius, color) {
        context.save();
        context.beginPath();
        context.fillStyle = color;
        context.arc(center.x, center.y, radius, 0, 2 * Math.PI);
        context.fill();
        context.closePath();
        context.restore();
    }
  • The moveTo() and the lineTo() methods are used to create needle elements:
  • /* js/app.js */
    
    function renderNeedle(context, angle, startPoint, endPoint, width, color) {
        var radius = context.canvas.width / 2,
            centerX = context.canvas.width / 2,
            centerY = context.canvas.height / 2,
            dxi = radius * Math.cos(angle) * startPoint,
            dyi = radius * Math.sin(angle) * startPoint,
            dxf = radius * Math.cos(angle) * endPoint,
            dyf = radius * Math.sin(angle) * endPoint;
    
        context.save();
        context.beginPath();
        context.lineWidth = width;
        context.strokeStyle = color;
        context.moveTo(centerX + dxi, centerY + dyi);
        context.lineTo(centerX + dxf, centerY + dyf);
        context.stroke();
        context.closePath();
        context.restore();
    }
  • The font property and the fillText() method are used to create text elements:
  • /* js/app.js */
    
    function renderText(context, text, x, y, textSize, color) {
        context.save();
        context.beginPath();
        context.font = textSize + "px Courier";
        context.textAlign = "center";
        context.textBaseline = "middle";
        context.fillStyle = color;
        context.fillText(text, x, y);
        context.closePath();
        context.restore();
    }

The application draws the layout and the content of the watch on the canvas.

  • For drawing the basic layout of the watch:
  • /* js/app.js */
    	
    function drawWatchLayout() {
        var grd,
            angle,
            i,
            j;
    
        // Clear canvas
        ctxLayout.clearRect(0, 0, ctxLayout.canvas.width, ctxLayout.canvas.height);
    
        // Draw the background circle
        renderCircle(ctxLayout, center, watchRadius, "#000000");
        grd = ctxLayout.createLinearGradient(0, 0, watchRadius * 2, 0);
        grd.addColorStop(0, "#000000");
        grd.addColorStop(0.5, "#454545");
        grd.addColorStop(1, "#000000");
        ctxLayout.fillStyle = grd;
        renderCircle(ctxLayout, center, watchRadius * 0.945, grd);
        renderCircle(ctxLayout, center, watchRadius * 0.7, "#000000");
    
        // Draw the dividers
        // 60 unit divider
        for (i = 1; i <= 60; i++) {
            angle = (i - 15) * (Math.PI * 2) / 60;
            renderNeedle(ctxLayout, angle, 0.95, 1.0, 1, "#c4c4c4");
        }
    
        // 12 unit divider
        for (j = 1; j <= 12; j++) {
            angle = (j - 3) * (Math.PI * 2) / 12;
            renderNeedle(ctxLayout, angle, 0.7, 0.945, 10, "#c4c4c4");
        }
    
        renderText(ctxLayout, "TIZEN WATCH", center.x, center.y - (watchRadius * 0.4), 25, "#999999");
    }
  • For drawing the content of the watch:
    The getCurrentDateTime() method returns the current time and date object from the Tizen Time API.
  • /* js/app.js */
    
    function drawWatchContent() {
        var datetime = tizen.time.getCurrentDateTime(),
            hour = datetime.getHours(),
            minute = datetime.getMinutes(),
            second = datetime.getSeconds(),
            date = datetime.getDate();
    
        // Clear canvas
        ctxContent.clearRect(0, 0, ctxContent.canvas.width, ctxContent.canvas.height);
    
        // Draw the hour needle
        renderNeedle(ctxContent, Math.PI * (((hour + minute / 60) / 6) - 0.5), 0, 0.50, 3, "#454545");
    
        // Draw the minute needle
        renderNeedle(ctxContent, Math.PI * (((minute + second / 60) / 30) - 0.5), 0, 0.70, 3, "#454545");
    
        // Draw the minute/hour circle
        renderCircle(ctxContent, center, 8, "#454545");
    
        // Draw the second needle
        ctxContent.shadowOffsetX = 4;
        ctxContent.shadowOffsetY = 4;
        renderNeedle(ctxContent, Math.PI * ((second / 30) - 0.5), -0.10, 0.85, 1, "#c4c4c4");
    
        // Draw the second circle
        ctxContent.shadowOffsetX = 0;
        ctxContent.shadowOffsetY = 0;
        renderCircle(ctxContent, center, 5, "#c4c4c4");
    
        // Draw the center circle
        renderCircle(ctxContent, center, 2, "#454545");
    
        // Draw the text for date
        renderText(ctxContent, date, center.x, center.y + (watchRadius * 0.5), 25, "#999999");
    }

The layout of the watch is drawn only once at the beginning, and the content of the watch gets updated every second.

/* js/app.js */

function init() {
    // Draw the basic layout and the content of the watch at the beginning
    drawWatchLayout();
    drawWatchContent();

    // Update the content of the watch every second
    setInterval(function() {
        drawWatchContent();
    }, 1000);
}