not really known
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

431 lines
16 KiB

  1. define(["sugar-web/activity/activity","sugar-web/env","sugar-web/graphics/radiobuttonsgroup","mustache","moment-with-locales.min","webL10n"], function (activity,env,radioButtonsGroup,mustache,moment) {
  2. // Manipulate the DOM only when it is ready.
  3. requirejs(['domReady!'], function (doc) {
  4. // Initialize the activity.
  5. activity.setup();
  6. setTranslatedStrings();
  7. var array=["simple","none","none"];
  8. env.getEnvironment(function(err, environment) {
  9. currentenv = environment;
  10. // Load from datastore
  11. if (!environment.objectId) {
  12. console.log("New instance");
  13. } else {
  14. activity.getDatastoreObject().loadAsText(function(error, metadata, data) {
  15. if (error==null && data!=null) {
  16. Clock.face=data[0];
  17. console.log(data);
  18. if(data[0]=="simple"){
  19. document.getElementById("simple-clock-button").classList.add("active");
  20. document.getElementById("nice-clock-button").classList.remove("active");
  21. clock.changeFace("simple");
  22. }else{
  23. document.getElementById("nice-clock-button").classList.add("active");
  24. document.getElementById("simple-clock-button").classList.remove("active");
  25. clock.changeFace("nice");
  26. }
  27. if(data[1]=="block"){
  28. document.getElementById("write-time-button").classList.add("active");
  29. clock.changeWriteTime(true);
  30. }else{
  31. document.getElementById("write-time-button").classList.remove("active");
  32. }
  33. if(data[2]=="block"){
  34. document.getElementById("write-date-button").classList.add("active");
  35. clock.changeWriteDate(true);
  36. }else{
  37. document.getElementById("write-date-button").classList.remove("active");
  38. }
  39. }
  40. });
  41. }
  42. });
  43. var requestAnimationFrame = window.requestAnimationFrame ||
  44. window.mozRequestAnimationFrame ||
  45. window.webkitRequestAnimationFrame ||
  46. window.msRequestAnimationFrame;
  47. function Clock() {
  48. this.face = "simple";
  49. this.handAngles = {
  50. 'hours': 0,
  51. 'minutes': 0,
  52. 'seconds': 0
  53. };
  54. this.colors = {
  55. 'black': "#000000",
  56. 'white': "#FFFFFF",
  57. 'hours': "#005FE4",
  58. 'minutes': "#00B20D",
  59. 'seconds': "#E6000A"
  60. };
  61. this.writeTime = false;
  62. this.writeDate = false;
  63. // These are calculated on each resize to fill the available space.
  64. this.size = undefined;
  65. this.margin = undefined;
  66. this.radius = undefined;
  67. this.centerX = undefined;
  68. this.centerY = undefined;
  69. this.lineWidthBase = undefined;
  70. this.handSizes = undefined;
  71. this.lineWidths = undefined;
  72. // DOM elements.
  73. this.textTimeElem = document.getElementById('text-time');
  74. this.textDateElem = document.getElementById('text-date');
  75. this.clockCanvasElem = document.getElementById("clock-canvas");
  76. this.clockContainerElem = this.clockCanvasElem.parentNode;
  77. this.bgCanvasElem = document.createElement('canvas');
  78. this.clockContainerElem.insertBefore(this.bgCanvasElem,
  79. this.clockCanvasElem);
  80. var that = this;
  81. window.onresize = function (event) {
  82. that.updateSizes();
  83. that.drawBackground();
  84. };
  85. }
  86. function setTranslatedStrings() {
  87. document.getElementById("simple-clock-button").title = l10n_s.get("SimpleClock");
  88. document.getElementById("nice-clock-button").title = l10n_s.get("NiceClock");
  89. document.getElementById("write-time-button").title = l10n_s.get("WriteTime");
  90. document.getElementById("write-date-button").title = l10n_s.get("WriteDate");
  91. document.getElementById("text-time").innerHTML = l10n_s.get("WhatTime");
  92. }
  93. Clock.prototype.start = function (face) {
  94. this.updateSizes();
  95. this.drawBackground();
  96. this.update();
  97. this.drawHands();
  98. this.previousTime = Date.now();
  99. this.tick();
  100. }
  101. Clock.prototype.tick = function () {
  102. var currentTime = Date.now();
  103. // Update each second (1000 miliseconds).
  104. if ((currentTime - this.previousTime) > 1000) {
  105. this.previousTime = currentTime;
  106. this.update();
  107. this.drawHands();
  108. if (/Android/i.test(navigator.userAgent) && document.location.protocol.substr(0,4) != "http") {
  109. // HACK: Force redraw on Android
  110. this.clockCanvasElem.style.display='none';
  111. this.clockCanvasElem.offsetHeight;
  112. this.clockCanvasElem.style.display='block';
  113. }
  114. }
  115. requestAnimationFrame(this.tick.bind(this));
  116. }
  117. Clock.prototype.changeFace = function (face) {
  118. this.face = face;
  119. this.drawBackground();
  120. array[0]=face;
  121. }
  122. Clock.prototype.changeWriteTime = function (writeTime) {
  123. this.writeTime = writeTime;
  124. if (writeTime) {
  125. this.textTimeElem.style.display = "block";
  126. } else {
  127. this.textTimeElem.style.display = "none";
  128. }
  129. array[1]=this.textTimeElem.style.display;
  130. this.updateSizes();
  131. this.update();
  132. this.drawBackground();
  133. }
  134. Clock.prototype.changeWriteDate = function (writeDate) {
  135. this.writeDate = writeDate;
  136. if (writeDate) {
  137. this.textDateElem.style.display = "block";
  138. } else {
  139. this.textDateElem.style.display = "none";
  140. }
  141. array[2]=this.textDateElem.style.display;
  142. this.updateSizes();
  143. this.update();
  144. this.drawBackground();
  145. }
  146. Clock.prototype.updateSizes = function () {
  147. var toolbarElem = document.getElementById("main-toolbar");
  148. var textContainerElem = document.getElementById("text-container");
  149. var height = window.innerHeight - (textContainerElem.offsetHeight +
  150. toolbarElem.offsetHeight) - 1;
  151. this.size = Math.min(window.innerWidth, height);
  152. this.clockCanvasElem.width = this.size;
  153. this.clockCanvasElem.height = this.size;
  154. this.bgCanvasElem.width = this.size;
  155. this.bgCanvasElem.height = this.size;
  156. this.clockContainerElem.style.width = this.size + "px";
  157. this.clockContainerElem.style.height = this.size + "px";
  158. this.clockCanvasElem.style.width = (this.size+4) + "px";
  159. this.margin = this.size * 0.02;
  160. this.radius = (this.size - (2 * this.margin)) / 2;
  161. this.centerX = this.radius + this.margin;
  162. this.centerY = this.radius + this.margin;
  163. this.lineWidthBase = this.radius / 150;
  164. this.handSizes = {
  165. 'hours': this.radius * 0.5,
  166. 'minutes': this.radius * 0.7,
  167. 'seconds': this.radius * 0.8
  168. };
  169. this.lineWidths = {
  170. 'hours': this.lineWidthBase * 9,
  171. 'minutes': this.lineWidthBase * 6,
  172. 'seconds': this.lineWidthBase * 4
  173. };
  174. }
  175. // Update text and hand angles using the current time.
  176. Clock.prototype.update = function () {
  177. var date = new Date();
  178. var hours = date.getHours();
  179. var minutes = date.getMinutes();
  180. var seconds = date.getSeconds();
  181. var zeroFill = function (number) {
  182. return ('00' + number).substr(-2);
  183. };
  184. var template =
  185. '<span style="color: {{ colors.hours }}">{{ hours }}' +
  186. '</span>' +
  187. ':<span style="color: {{ colors.minutes }}">{{ minutes }}' +
  188. '</span>' +
  189. ':<span style="color: {{ colors.seconds }}">{{ seconds }}' +
  190. '</span>';
  191. if (this.writeTime) {
  192. var templateData = {'colors': this.colors,
  193. 'hours': zeroFill(hours),
  194. 'minutes': zeroFill(minutes),
  195. 'seconds': zeroFill(seconds)
  196. }
  197. this.textTimeElem.innerHTML = mustache.render(template,
  198. templateData);
  199. }
  200. if (this.writeDate) {
  201. var momentDate = moment(date);
  202. this.textDateElem.innerHTML = momentDate.format('LLLL').replace(momentDate.format('LT'), '');
  203. }
  204. this.handAngles.hours = Math.PI - (Math.PI / 6 * hours +
  205. Math.PI / 360 * minutes);
  206. this.handAngles.minutes = Math.PI - Math.PI / 30 * minutes;
  207. this.handAngles.seconds = Math.PI - Math.PI / 30 * seconds;
  208. }
  209. Clock.prototype.drawBackground = function () {
  210. if (this.face == "simple") {
  211. this.drawSimpleBackground();
  212. this.drawNumbers();
  213. }
  214. else {
  215. this.drawNiceBackground();
  216. }
  217. this.drawHands();
  218. }
  219. // Draw the background of the simple clock.
  220. //
  221. // The simple clock background is a white disk, with hours and
  222. // minutes ticks, and the hour numbers.
  223. Clock.prototype.drawSimpleBackground = function () {
  224. var ctx = this.bgCanvasElem.getContext('2d');
  225. ctx.clearRect(0, 0, this.size, this.size);
  226. // Simple clock background
  227. var lineWidthBackground = this.lineWidthBase * 4;
  228. ctx.lineCap = 'round';
  229. ctx.lineWidth = lineWidthBackground;
  230. ctx.strokeStyle = this.colors.black;
  231. ctx.fillStyle = this.colors.white;
  232. ctx.beginPath();
  233. ctx.arc(this.centerX, this.centerY,
  234. this.radius - lineWidthBackground, 0, 2 * Math.PI);
  235. ctx.fill();
  236. ctx.stroke();
  237. // Clock ticks
  238. for (var i = 0; i < 60; i++) {
  239. var inset;
  240. if (i % 15 === 0) {
  241. inset = 0.15 * this.radius;
  242. ctx.lineWidth = this.lineWidthBase * 7;
  243. }
  244. else if (i % 5 === 0) {
  245. inset = 0.12 * this.radius;
  246. ctx.lineWidth = this.lineWidthBase * 5;
  247. }
  248. else {
  249. inset = 0.08 * this.radius;
  250. ctx.lineWidth = this.lineWidthBase * 4;
  251. }
  252. ctx.lineCap = 'round';
  253. ctx.beginPath();
  254. var cos = Math.cos(i * Math.PI / 30);
  255. var sin = Math.sin(i * Math.PI / 30);
  256. ctx.save();
  257. ctx.translate(this.margin, this.margin);
  258. ctx.moveTo(
  259. this.radius + (this.radius - inset) * cos,
  260. this.radius + (this.radius - inset) * sin);
  261. ctx.lineTo(
  262. this.radius + (this.radius - ctx.lineWidth) * cos,
  263. this.radius + (this.radius - ctx.lineWidth) * sin);
  264. ctx.stroke();
  265. ctx.restore();
  266. }
  267. }
  268. Clock.prototype.drawNiceBackground = function () {
  269. var ctx = this.bgCanvasElem.getContext('2d');
  270. var niceImageElem = document.createElement('img');
  271. var that = this;
  272. var onLoad = function () {
  273. ctx.clearRect(that.margin, that.margin,
  274. that.radius * 2, that.radius * 2);
  275. ctx.drawImage(niceImageElem, that.margin, that.margin,
  276. that.radius * 2, that.radius * 2);
  277. };
  278. niceImageElem.addEventListener('load', onLoad, false);
  279. niceImageElem.src = "clock.svg";
  280. }
  281. // Draw the numbers of the hours.
  282. Clock.prototype.drawNumbers = function () {
  283. var ctx = this.bgCanvasElem.getContext('2d');
  284. var fontSize = 30 * this.radius / 160;
  285. ctx.fillStyle = this.colors.hours;
  286. ctx.textBaseline = 'middle';
  287. ctx.font = "bold " + fontSize + "px sans-serif";
  288. for (var i = 0; i < 12; i++) {
  289. var cos = Math.cos((i - 2) * Math.PI / 6);
  290. var sin = Math.sin((i - 2) * Math.PI / 6);
  291. var text = i + 1;
  292. var textWidth = ctx.measureText(text).width;
  293. ctx.save();
  294. ctx.translate(this.centerX - textWidth / 2, this.centerY);
  295. ctx.translate(this.radius * 0.75 * cos,
  296. this.radius * 0.75 * sin);
  297. ctx.fillText(text, 0, 0);
  298. ctx.restore();
  299. }
  300. }
  301. // Draw the hands of the analog clocks.
  302. Clock.prototype.drawHands = function () {
  303. var ctx = this.clockCanvasElem.getContext("2d");
  304. // Clear canvas first.
  305. ctx.clearRect(this.margin, this.margin, this.radius * 2,
  306. this.radius * 2);
  307. var handNames = ['hours', 'minutes', 'seconds'];
  308. for (var i = 0; i < handNames.length; i++) {
  309. var name = handNames[i];
  310. ctx.lineCap = 'round';
  311. ctx.lineWidth = this.lineWidths[name];
  312. ctx.strokeStyle = this.colors[name];
  313. ctx.beginPath();
  314. ctx.arc(this.centerX, this.centerY, ctx.lineWidth * 0.6, 0,
  315. 2 * Math.PI);
  316. ctx.moveTo(this.centerX, this.centerY);
  317. ctx.lineTo(
  318. this.centerX + this.handSizes[name] *
  319. Math.sin(this.handAngles[name]),
  320. this.centerY + this.handSizes[name] *
  321. Math.cos(this.handAngles[name]));
  322. ctx.stroke();
  323. }
  324. }
  325. // Create the clock.
  326. var clock = new Clock();
  327. clock.start();
  328. // UI controls.
  329. var simpleClockButton = document.getElementById("simple-clock-button");
  330. simpleClockButton.onclick = function () {
  331. clock.changeFace("simple");
  332. };
  333. var niceClockButton = document.getElementById("nice-clock-button");
  334. niceClockButton.onclick = function () {
  335. clock.changeFace("nice");
  336. };
  337. var simpleNiceRadio = new radioButtonsGroup.RadioButtonsGroup(
  338. [simpleClockButton, niceClockButton]);
  339. var writeTimeButton = document.getElementById("write-time-button");
  340. writeTimeButton.onclick = function () {
  341. this.classList.toggle('active');
  342. var active = this.classList.contains('active');
  343. clock.changeWriteTime(active);
  344. };
  345. var writeDateButton = document.getElementById("write-date-button");
  346. writeDateButton.onclick = function () {
  347. this.classList.toggle('active');
  348. var active = this.classList.contains('active');
  349. clock.changeWriteDate(active);
  350. };
  351. document.getElementById("stop-button").addEventListener('click', function (event) {
  352. activity.getDatastoreObject().setDataAsText(array);
  353. activity.getDatastoreObject().save(function (error) {
  354. if (error === null) {
  355. console.log("write done.");
  356. } else {
  357. console.log("write failed.");
  358. }
  359. });
  360. });
  361. });
  362. });