/* * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ (function() { var canvasLayout, canvasContent, ctxLayout, ctxContent, center, watchRadius; function readJSON(path) { var xhr = new XMLHttpRequest(); xhr.open('GET', path, true); xhr.responseType = 'blob'; xhr.onload = function(e) { console.log("status " + this.status); if (this.status == 0) { var file = new File([this.response], 'temp'); var fileReader = new FileReader(); fileReader.addEventListener('load', function(){ console.log(fileReader.result); }); fileReader.readAsText(file); } } xhr.send(); } function getJSON() { var downloadRequest = new tizen.DownloadRequest('http://download.tizen.org/tools/README.txt', 'downloads'); tizen.systeminfo.getPropertyValue('NETWORK', function(networkInfo) { if (networkInfo.networkType === 'NONE') { console.log('Network connection is not available.Download is not possible.'); downloadRequest = null; } }); var listener = { /* When the download progresses (interval is platform-dependent) */ onprogress: function(id, receivedSize, totalSize) { console.log('Received with id: ' + id + ', ' + receivedSize + '/' + totalSize); }, /* When the user pauses the download */ onpaused: function(id) { console.log('Paused with id: ' + id); }, /* When the user cancels the download */ oncanceled: function(id) { console.log('Canceled with id: ' + id); }, /* When the download is completed */ oncompleted: function(id, fullPath) { console.log('Completed with id: ' + id + ', full path: ' + fullPath); readJSON(fullPath); }, /* When the download fails */ onfailed: function(id, error) { console.log('Failed with id: ' + id + ', error name: ' + error.name); } }; console.log("starting download"); downloadId = tizen.download.start(downloadRequest, listener); console.log(tizen.download.getState(downloadId)); console.log("done"); } /** * Renders a circle with specific center, radius, and color * @private * @param {object} context - the context for the circle to be placed in * @param {number} radius - the radius of the circle * @param {string} color - the color of the circle */ 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(); } /** * Renders a partial with specific center, radius, and color * @private * @param {object} context - the context for the circle to be placed in * @param {number} radius - the radius of the circle * @param {string} color - the color of the circle */ function renderArc(context, center, radius, color, startAngle, endAngle) { context.save(); context.beginPath(); seperation = 5; startAngle += seperation; if(startAngle >= 360) startAngle -= 360; endAngle -= seperation; if(endAngle<0) endAngle += 360; context.arc(center.x, center.y, radius, startAngle * Math.PI / 180., endAngle * Math.PI / 180.); context.fillStyle = color; context.strokeStyle = color; context.lineWidth = 18; context.stroke(); context.restore(); renderCircle(context, polToCart(radius, startAngle), 9, color); renderCircle(context, polToCart(radius, endAngle), 9, color); } function polToCart(radius, angle) { pos = { x: center.x + radius * Math.cos(angle * Math.PI / 180), y: center.y + radius * Math.sin(angle * Math.PI / 180) }; return pos; } function hourToAngle(hour) { } /** * Renders a needle with specific center, angle, start point, end point, width and color * @private * @param {object} context - the context for the needle to be placed in * @param {number} angle - the angle of the needle (0 ~ 360) * @param {number} startPoint - the start point of the needle (-1.0 ~ 1.0) * @param {number} startPoint - the end point of the needle (-1.0 ~ 1.0) * @param {number} width - the width of the needle * @param {string} color - the color of the needle */ 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(); } /** * Renders text at a specific center, radius, and color * @private * @param {object} context - the context for the text to be placed in * @param {string} text - the text to be placed * @param {number} x - the x-coordinate of the text * @param {number} y - the y-coordinate of the text * @param {number} textSize - the size of the text in pixel * @param {string} color - the color of the text */ 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(); } /** * Draws the basic layout of the watch * @private */ 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"); } /** * Draws the content of the watch * @private */ 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"); thickness = 18; edge = document.body.clientWidth / 2 - thickness / 2 - 2; renderArc(ctxContent, center, edge, "#808080", 75, 195); // sleep renderArc(ctxContent, center, edge, "#FF0000", 210, 277.5); // work renderArc(ctxContent, center, edge, "#FFFF00", 277.5, 292.5); // lunch renderArc(ctxContent, center, edge, "#FF0000", 292.5, 352.5); // work // 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"); } /** * Set default variables * @private */ function setDefaultVariables() { canvasLayout = document.querySelector("#canvas-layout"); ctxLayout = canvasLayout.getContext("2d"); canvasContent = document.querySelector("#canvas-content"); ctxContent = canvasContent.getContext("2d"); // Set the canvases square canvasLayout.width = document.body.clientWidth; canvasLayout.height = canvasLayout.width; canvasContent.width = document.body.clientWidth; canvasContent.height = canvasContent.width; center = { x: document.body.clientWidth / 2, y: document.body.clientHeight / 2 }; watchRadius = canvasLayout.width / 2; } /** * Set default event listeners * @private */ function setDefaultEvents() { // add eventListener to update the screen immediately when the device wakes up document.addEventListener("visibilitychange", function() { if (!document.hidden) { // Draw the content of the watch drawWatchContent(); } }); } /** * Initiates the application * @private */ function init() { setDefaultVariables(); setDefaultEvents(); // 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); } window.onload = init; }());