mirror of https://github.com/espruino/BangleApps
cogclock: new clock
parent
17cb0de69e
commit
66a36ec215
|
@ -0,0 +1,2 @@
|
|||
0.01: New clock
|
||||
0.02: Use ClockFace library, add settings
|
|
@ -4,18 +4,6 @@ Graphics.prototype.setFont15x32N = function() {
|
|||
"/////oAAAAKAAAACgAAAAoAAAAKAAAACgf//AoEAAQKB//8CgAAAAoAAAAKAAAACgAAAAoAAAAL////+/wAB/oEAAQKBAAECgf//AoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAAC////AgAAAQIAAAH+/w///oEIAAKBCAACgQgAAoEIAAKBCAACgQg/AoEIIQKB+CECgAAhAoAAIQKAACECgAAhAoAAIQL//+H+/w/h/oEIIQKBCCECgQghAoEIIQKBCCECgQghAoEIIQKB+D8CgAAAAoAAAAKAAAACgAAAAoAAAAL////+///gAIAAIACAACAAgAAgAIAAIAD/+CAAAAggAAAIIAAACD/+//gAAoAAAAKAAAACgAAAAoAAAAL////+///h/oAAIQKAACECgAAhAoAAIQKAACECgfghAoEIIQKBCD8CgQgAAoEIAAKBCAACgQgAAoEIAAL/D//+/////oAAAAKAAAACgAAAAoAAAAKAAAACgfg/AoEIIQKBCD8CgQgAAoEIAAKBCAACgQgAAoEIAAL/D//+/wAAAIEAAACBAAAAgQAAAIEAAACBAAAAgQAAAIH///6AAAACgAAAAoAAAAKAAAACgAAAAoAAAAL////+/////oAAAAKAAAACgAAAAoAAAAKAAAACgfg/AoEIIQKB+D8CgAAAAoAAAAKAAAACgAAAAoAAAAL////+///h/oAAIQKAACECgAAhAoAAIQKAACECgfghAoEIIQKB+D8CgAAAAoAAAAKAAAACgAAAAoAAAAL////+"
|
||||
), "0".charCodeAt(0), 15, 32);
|
||||
};
|
||||
const SHOW_DATE = false; // TODO: make into setting?
|
||||
Bangle.setUI("clock"); // set UI first, so widgets know about Bangle.CLOCK
|
||||
Bangle.loadWidgets(); // load widgets, so Bangle.appRect knows about them
|
||||
|
||||
const r1 = 84, // inner radius
|
||||
r3 = Math.min(Bangle.appRect.w/2, Bangle.appRect.h/2), // outer radius
|
||||
r2 = (r1*3+r3*2)/5,
|
||||
teeth = 12,
|
||||
edge = 0.45, point = 0.35; // as fraction of arc
|
||||
|
||||
const x = Bangle.appRect.x+Bangle.appRect.w/2,
|
||||
y = Bangle.appRect.y+Bangle.appRect.h/2;
|
||||
|
||||
/**
|
||||
* Add coordinates for nth tooth to vertices
|
||||
|
@ -24,9 +12,11 @@ const x = Bangle.appRect.x+Bangle.appRect.w/2,
|
|||
*/
|
||||
function addTooth(poly, n) {
|
||||
const
|
||||
tau = Math.PI*2, arc = tau/teeth,
|
||||
e = arc*edge, p = arc*point, s = (arc-(e+p))/2; // edge,point,slopes
|
||||
const sin = Math.sin, cos = Math.cos;
|
||||
tau = Math.PI*2, arc = tau/clock.teeth,
|
||||
e = arc*clock.edge, p = arc*clock.point, s = (arc-(e+p))/2; // edge,point,slopes
|
||||
const sin = Math.sin, cos = Math.cos,
|
||||
x = clock.x, y = clock.y,
|
||||
r2 = clock.r2, r3 = clock.r3;
|
||||
let r = (n-1)*arc+e/2; // rads
|
||||
poly.push(x+r2*sin(r), y-r2*cos(r));
|
||||
r += s;
|
||||
|
@ -37,18 +27,6 @@ function addTooth(poly, n) {
|
|||
poly.push(x+r2*sin(r), y-r2*cos(r));
|
||||
}
|
||||
|
||||
function drawCog() {
|
||||
g.reset();
|
||||
g.setColor(g.theme.bg2).fillCircle(x, y, r2) // fill cog
|
||||
.setColor(g.theme.bg).fillCircle(x, y, r1) // clear center
|
||||
.setColor(g.theme.fg2).drawCircle(x, y, r1); // draw inner border
|
||||
let poly = []; // complete teeth outline
|
||||
for(let t = 1; t<=teeth; t++) {
|
||||
fillTooth(t, g.theme.bg2);
|
||||
addTooth(poly, t);
|
||||
}
|
||||
g.drawPoly(poly, true); // draw outer border
|
||||
}
|
||||
/**
|
||||
* @param {number} n Tooth number to fill (1-based)
|
||||
* @param col Fill color
|
||||
|
@ -61,62 +39,73 @@ function fillTooth(n, col) {
|
|||
.setColor(g.theme.fg2).drawPoly(poly); // fillPoly colored over the outline
|
||||
}
|
||||
|
||||
let last = {tooth: 0}, timeOut;
|
||||
function draw() {
|
||||
if (!Bangle.isLCDOn()) return; // no drawing, also no new update scheduled
|
||||
const ClockFace = require("ClockFace");
|
||||
const clock = new ClockFace({
|
||||
precision: 1,
|
||||
settingsFile: "cogclock.settings.json",
|
||||
init: function() {
|
||||
this.r1 = 84; // inner radius
|
||||
this.r3 = Math.min(Bangle.appRect.w/2, Bangle.appRect.h/2); // outer radius
|
||||
this.r2 = (this.r1*3+this.r3*2)/5;
|
||||
this.teeth = 12;
|
||||
this.edge = 0.45;
|
||||
this.point = 0.35; // as fraction of arc
|
||||
this.x = Bangle.appRect.x+Bangle.appRect.w/2;
|
||||
this.y = Bangle.appRect.y+Bangle.appRect.h/2;
|
||||
},
|
||||
draw: function(d) {
|
||||
const x = this.x, y = this.y;
|
||||
g.setColor(g.theme.bg2).fillCircle(x, y, this.r2) // fill cog
|
||||
.setColor(g.theme.bg).fillCircle(x, y, this.r1) // clear center
|
||||
.setColor(g.theme.fg2).drawCircle(x, y, this.r1); // draw inner border
|
||||
let poly = []; // complete teeth outline
|
||||
for(let t = 1; t<=this.teeth; t++) {
|
||||
fillTooth(t, g.theme.bg2);
|
||||
addTooth(poly, t);
|
||||
}
|
||||
g.drawPoly(poly, true); // draw outer border
|
||||
if (!this.showDate) {
|
||||
// draw top/bottom rectangles (instead of year/date)
|
||||
g.reset()
|
||||
.fillRect(x-30, y-60, x+29, y-33).clearRect(x-28, y-58, x+27, y-33)
|
||||
.fillRect(x-30, y+60, x+29, y+30).clearRect(x-28, y+58, x+27, y+30);
|
||||
}
|
||||
this.tooth = 0;
|
||||
this.update(d, {s: 1, m: 1, h: 1, d: 1});
|
||||
},
|
||||
update: function(d, c) {
|
||||
g.reset();
|
||||
const pad2 = num => (num<10 ? "0" : "")+num,
|
||||
d = new Date(),
|
||||
year = d.getFullYear(),
|
||||
date = pad2(d.getDate())+pad2(d.getMonth()),
|
||||
time = pad2(d.getHours())+pad2(d.getMinutes()),
|
||||
tooth = Math.round(d.getSeconds()/60*teeth),
|
||||
m = d.getMilliseconds();
|
||||
if (time!==last.time) {
|
||||
tooth = Math.round(d.getSeconds()/60*this.teeth);
|
||||
const x = this.x, y = this.y;
|
||||
if (c.m) {
|
||||
g.setFont("15x32N:2").setFontAlign(0, 0) // center middle
|
||||
.drawString(time, x, y, true);
|
||||
}
|
||||
if (SHOW_DATE) {
|
||||
if (year!==last.year) {
|
||||
if (this.showDate) {
|
||||
if (c.d) {
|
||||
g.setFont("15x32N").setFontAlign(0, -1) // center top
|
||||
.drawString(year, x, y+32, true);
|
||||
}
|
||||
if (date!==last.date) {
|
||||
g.setFont("15x32N").setFontAlign(0, 1) // center bottom
|
||||
.drawString(year, x, y+32, true)
|
||||
.setFont("15x32N").setFontAlign(0, 1) // center bottom
|
||||
.drawString(date, x, y-32, true);
|
||||
}
|
||||
} else if (time!==last.time) {
|
||||
g.fillRect(x-30, y-60, x+29, y-33).clearRect(x-28, y-58, x+27, y-33);
|
||||
g.fillRect(x-30, y+60, x+29, y+30).clearRect(x-28, y+58, x+27, y+30);
|
||||
}
|
||||
if (tooth!==last.tooth) {
|
||||
if (tooth>last.tooth) {
|
||||
for(let t = last.tooth; t<=tooth; t++) { // fill missing teeth
|
||||
|
||||
if (tooth!==this.tooth) {
|
||||
if (tooth>this.tooth) {
|
||||
for(let t = this.tooth; t<=tooth; t++) { // fill missing teeth
|
||||
fillTooth(t, g.theme.fg2);
|
||||
}
|
||||
} else {
|
||||
for(let t = last.tooth; t>tooth; t--) { // erase extraneous teeth
|
||||
for(let t = this.tooth; t>tooth; t--) { // erase extraneous teeth
|
||||
fillTooth(t, g.theme.bg2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
last = {
|
||||
year: year,
|
||||
date: date,
|
||||
time: time,
|
||||
tooth: tooth,
|
||||
};
|
||||
timeOut = setTimeout(draw, 1000-m);
|
||||
}
|
||||
g.clear();
|
||||
Bangle.drawWidgets();
|
||||
Bangle.on("lcdPower", on => {
|
||||
if (timeOut) {
|
||||
clearTimeout(timeOut);
|
||||
timeOut = undefined;
|
||||
this.tooth = tooth;
|
||||
}
|
||||
if (on) draw();
|
||||
});
|
||||
drawCog();
|
||||
draw();
|
||||
clock.start();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"id": "cogclock",
|
||||
"name": "Cog Clock",
|
||||
"version": "0.01",
|
||||
"description": "A clock inside a cog",
|
||||
"version": "0.02",
|
||||
"description": "A cross-shaped clock inside a cog",
|
||||
"icon": "icon.png",
|
||||
"screenshots": [{"url":"screenshot.png"}],
|
||||
"type": "clock",
|
||||
|
@ -11,6 +11,10 @@
|
|||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"cogclock.app.js","url":"app.js"},
|
||||
{"name":"cogclock.settings.js","url":"settings.js"},
|
||||
{"name":"cogclock.img","url":"icon.js","evaluate":true}
|
||||
],
|
||||
"data": [
|
||||
{"name": "cogclock.settings.json"}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
(function(back) {
|
||||
let s = require('Storage').readJSON("cogclock.settings.json", true) || {};
|
||||
|
||||
function saver(key) {
|
||||
return value => {
|
||||
s[key] = value;
|
||||
require('Storage').writeJSON("cogclock.settings.json", s);
|
||||
}
|
||||
}
|
||||
|
||||
const menu = {
|
||||
"": {"title": /*LANG*/"Cog Clock"},
|
||||
/*LANG*/"< Back": back,
|
||||
/*LANG*/"Show date": require("ClockFace_menu").showDate(s.showDate, saver('showDate')),
|
||||
/*LANG*/"Load widgets": require("ClockFace_menu").loadWidgets(s.loadWidgets, saver('loadWidgets')),
|
||||
};
|
||||
|
||||
E.showMenu(menu);
|
||||
});
|
Loading…
Reference in New Issue