mirror of https://github.com/espruino/BangleApps
248 lines
5.2 KiB
JavaScript
248 lines
5.2 KiB
JavaScript
//
|
|
// Time Travellers Watch
|
|
// Written May 2020 by Richard Hopkins
|
|
// based on a skeleton app by Gordon Williams
|
|
//
|
|
const locale = require('locale');
|
|
let timer = null;
|
|
let currentDate = new Date();
|
|
const cirRad = 2*Math.PI;
|
|
const proportion = 0.3; // relative size of hour hand
|
|
const thickness = 4; // thickness of decorative lines
|
|
// retrieve settings from menu
|
|
let settings = require('Storage').readJSON('gallifr.json',1)||{};
|
|
const decoration = !settings.decoration;
|
|
const widgets = !settings.widgets;
|
|
if (widgets) {
|
|
widgetHeight = 24;}
|
|
else {
|
|
widgetHeight = 0;}
|
|
const colours = ["green","red","blue","80s"];
|
|
const colour = colours[settings.colour];
|
|
const centerX = Math.round(g.getWidth() / 2);
|
|
const centerY = widgetHeight + Math.round((g.getHeight()-widgetHeight) / 2);
|
|
const radius = Math.round(Math.min(g.getWidth()/2,(g.getHeight()-widgetHeight) / 2));
|
|
|
|
const drawSegment = (params) => {
|
|
angle1 = params.start/360*cirRad;
|
|
angle2 = (params.start + params.arc)/360*cirRad;
|
|
segRadius = Math.round(params.radius*radius);
|
|
x = centerX + (params.x * radius);
|
|
y = centerY - (params.y *radius);
|
|
g.setColor(0,0,0);
|
|
incr = cirRad/15;
|
|
for (i = angle1; i < angle2; i=i+incr) {
|
|
brush = thickness * (angle2-angle1) /angle2;
|
|
points = [
|
|
x + Math.sin(i) * (segRadius+brush),
|
|
y - Math.cos(i) * (segRadius+brush),
|
|
x + Math.sin(i+incr) * (segRadius+brush),
|
|
y - Math.cos(i+incr) * (segRadius+brush),
|
|
x + Math.sin(i+incr) * (segRadius-brush),
|
|
y - Math.cos(i+incr) * (segRadius-brush),
|
|
x + Math.sin(i) * (segRadius-brush),
|
|
y - Math.cos(i) * (segRadius-brush)
|
|
];
|
|
g.fillPoly(points);
|
|
}
|
|
};
|
|
|
|
const drawThickLine = (params) => {
|
|
g.setColor(0,0,0);
|
|
from = {
|
|
x: centerX + (params.fromX * radius),
|
|
y: centerY - (params.fromY * radius)
|
|
};
|
|
to = {
|
|
x: centerX + (params.toX * radius),
|
|
y: centerY - (params.toY * radius)
|
|
};
|
|
vec = {};
|
|
vec.x = to.x - from.x;
|
|
vec.y = to.y - from.y;
|
|
pVec = {};
|
|
pVec.x = vec.y;
|
|
pVec.y = -vec.x;
|
|
length = Math.sqrt(pVec.x * pVec.x + pVec.y * pVec.y);
|
|
nVec = {};
|
|
nVec.x = pVec.x / length;
|
|
nVec.y = pVec.y / length;
|
|
array = [
|
|
from.x + nVec.x * thickness,
|
|
from.y + nVec.y * thickness,
|
|
from.x - nVec.x * thickness,
|
|
from.y - nVec.y * thickness,
|
|
to.x + nVec.x * thickness,
|
|
to.y + nVec.y * thickness,
|
|
to.x - nVec.x * thickness,
|
|
to.y - nVec.y * thickness
|
|
];
|
|
g.fillPoly(array);
|
|
};
|
|
|
|
|
|
|
|
const drawHands = () => {
|
|
drawMinuteHand();
|
|
drawHourHand();
|
|
if (decoration) {
|
|
drawDecoration();
|
|
}
|
|
};
|
|
|
|
const drawDecoration = () => {
|
|
params = {
|
|
start: 210,
|
|
arc: 295,
|
|
radius: 0.7,
|
|
x: 0,
|
|
y: 0
|
|
};
|
|
drawSegment(params);
|
|
params = {
|
|
start: 290,
|
|
arc: 135,
|
|
radius: 0.4,
|
|
x: 0,
|
|
y: -0.7
|
|
};
|
|
drawSegment(params);
|
|
params = {
|
|
start: 0,
|
|
arc: 360,
|
|
radius: 0.4,
|
|
x: 0,
|
|
y: 0.3
|
|
};
|
|
drawSegment(params);
|
|
params = {
|
|
start: 0,
|
|
arc: 360,
|
|
radius: 0.15,
|
|
x: 0,
|
|
y: 0.3
|
|
};
|
|
drawSegment(params);
|
|
params = {
|
|
start: 0,
|
|
arc: 360,
|
|
radius: 0.15,
|
|
x: 0.7,
|
|
y: 0
|
|
};
|
|
drawSegment(params);
|
|
params = {
|
|
fromX: 0.4,
|
|
fromY: 0.2,
|
|
toX: 0.6,
|
|
toY: 0.1
|
|
};
|
|
drawThickLine(params);
|
|
params = {
|
|
fromX: -0.2,
|
|
fromY: -0.05,
|
|
toX: -0.7,
|
|
toY: -0.7
|
|
};
|
|
drawThickLine(params);
|
|
params = {
|
|
fromX: -0.3,
|
|
fromY: 0.05,
|
|
toX: -0.95,
|
|
toY: -0.3
|
|
};
|
|
drawThickLine(params);
|
|
};
|
|
|
|
const drawMinuteHand = () => {
|
|
angle = currentDate.getMinutes()/60 * cirRad;
|
|
//angle = currentDate.getSeconds()/60 * cirRad;
|
|
switch(colour) {
|
|
case "red":
|
|
g.setColor(1,0,0);
|
|
break;
|
|
case "green":
|
|
g.setColor(0,1,0);
|
|
break;
|
|
case "blue":
|
|
g.setColor(0,0,1);
|
|
break;
|
|
case "80s":
|
|
g.setColor(1,0,0);
|
|
break;
|
|
default:
|
|
g.setColor(0,1,0);
|
|
}
|
|
|
|
var points = [centerX,centerY];
|
|
for (i = 0; i < angle; i=i+cirRad/60) {
|
|
points.push(Math.round(centerX + Math.sin(i) * radius),
|
|
Math.round(centerY - Math.cos(i) * radius));
|
|
}
|
|
g.fillPoly(points);
|
|
};
|
|
|
|
const drawHourHand = () => {
|
|
g.setColor(0,0,0);
|
|
//angle = currentDate.getMinutes()/60 * cirRad;
|
|
angle = currentDate.getHours()/12 * cirRad;
|
|
g.fillCircle(
|
|
Math.round(centerX + Math.sin(angle) * radius * (1-proportion)),
|
|
Math.round(centerY - Math.cos(angle) * radius * (1-proportion)),
|
|
radius * proportion
|
|
);
|
|
};
|
|
|
|
const drawClockFace = () => {
|
|
switch(colour) {
|
|
case "red":
|
|
g.setColor(0.8,0.3,0);
|
|
break;
|
|
case "green":
|
|
g.setColor(0.1,0.7,0);
|
|
break;
|
|
case "blue":
|
|
g.setColor(0,0.3,0.8);
|
|
break;
|
|
case "80s":
|
|
g.setColor(1,1,1);
|
|
break;
|
|
default:
|
|
g.setColor(0.1,0.7,0);
|
|
}
|
|
g.fillCircle(centerX,centerY,radius*0.98);
|
|
};
|
|
|
|
const drawAll = () => {
|
|
currentDate = new Date();
|
|
g.clear();
|
|
if (widgets) {Bangle.drawWidgets();}
|
|
drawClockFace();
|
|
drawHands();
|
|
};
|
|
|
|
|
|
const startTimers = () => {
|
|
//timer = setInterval(drawAll, 1000);
|
|
timer = setInterval(drawAll, 1000*20);
|
|
};
|
|
|
|
Bangle.on('lcdPower', (on) => {
|
|
if (on) {
|
|
startTimers();
|
|
drawAll();
|
|
} else {
|
|
if (timer) {
|
|
clearInterval(timer);
|
|
}
|
|
}
|
|
});
|
|
|
|
g.clear();
|
|
startTimers();
|
|
Bangle.loadWidgets();
|
|
drawAll();
|
|
|
|
// Show launcher when button pressed
|
|
Bangle.setUI("clock");
|