Update the sunrise watchface

master
Luc Tielen 2023-06-09 20:36:43 +02:00
parent d620ff25be
commit 239c2777b1
4 changed files with 111 additions and 47 deletions

View File

@ -1,2 +1,3 @@
0.01: First release 0.01: First release
0.02: Faster sinus line and fix button to open menu 0.02: Faster sinus line and fix button to open menu
0.03: Show day/month, add animations, fix !mylocation and text glitch

View File

@ -6,17 +6,15 @@ This is a work-in-progress app, so you may expect missfeatures, bugs and heavy
battery draining. There's still a lot of things to optimize and improve, so take battery draining. There's still a lot of things to optimize and improve, so take
this into account before complaining :-) this into account before complaining :-)
* Lat/Lon hardcoded to Barcelona, but it's configurable if you install the "mylocation app" * Requires to configure the location in Settings -> Apps -> My Location
* Shows sea level and make the sun/moon glow depending on the x position * Shows sea level and make the sun/moon glow depending on the x position
* The sinus is fixed, so the sea level is curved to match the sunrise/sunset positions) * The sinus is fixed, so the sea level is curved to match the sunrise/sunset positions)
## TODO ## TODO
* Access GPS on first start to cache lat+lon to compute sunrise/sunset times * Improved gradients and add support for banglejs1
* Cache constant values once
* Show month and day too?
* Improved gradients
* Faster rendering, by reducing sinus stepsize, only refreshing whats needed, etc * Faster rendering, by reducing sinus stepsize, only refreshing whats needed, etc
* Show red vertical lines or dots inside the sinus if there are alarms
## Author ## Author

View File

@ -4,18 +4,20 @@
const LOCATION_FILE = 'mylocation.json'; const LOCATION_FILE = 'mylocation.json';
let location; let location;
Bangle.setUI('clock');
Bangle.loadWidgets();
// requires the myLocation app // requires the myLocation app
function loadLocation () { function loadLocation () {
try { try {
return require('Storage').readJSON(LOCATION_FILE, 1); return require('Storage').readJSON(LOCATION_FILE, 1);
} catch (e) { } catch (e) {
return { }; return { lat: 41.38, lon: 2.168 };
} }
} }
let frames = 0; // amount of pending frames to render (0 if none)
Bangle.setUI("clock"); let curPos = 0; // x position of the sun
Bangle.loadWidgets(); let realPos = 0; // x position of the sun depending on currentime
const latlon = loadLocation(); const latlon = loadLocation() || {};
const lat = latlon.lat || 41.38; const lat = latlon.lat || 41.38;
const lon = latlon.lon || 2.168; const lon = latlon.lon || 2.168;
@ -172,11 +174,6 @@ const w = g.getWidth();
const h = g.getHeight(); const h = g.getHeight();
const oy = h / 1.7; const oy = h / 1.7;
function ypos (x) {
const pc = (x * 100 / w);
return oy + (32 * Math.sin(1.7 + (pc / 16)));
}
let sunRiseX = 0; let sunRiseX = 0;
let sunSetX = 0; let sunSetX = 0;
const sinStep = 12; const sinStep = 12;
@ -201,21 +198,27 @@ function drawSinuses () {
} }
// sea level line // sea level line
const sl0 = seaLevel(sunrise.getHours()); const hh0 = sunrise.getHours();
const sl1 = seaLevel(sunset.getHours()); const hh1 = sunset.getHours();
sunRiseX = xfromTime(sunrise.getHours()); const sl0 = seaLevel(hh0);
sunSetX = xfromTime(sunset.getHours()); const sl1 = seaLevel(hh1);
g.setColor(0.5, 0.5, 1); sunRiseX = xfromTime(hh0) + (r / 2);
sunSetX = xfromTime(hh1) + (r / 2);
g.setColor(0, 0, 1);
g.drawLine(0, sl0, w, sl1); g.drawLine(0, sl0, w, sl1);
g.setColor(0, 0, 1); g.setColor(0, 0, 1);
g.drawLine(0, sl0 + 1, w, sl1 + 1); g.drawLine(0, sl0 + 1, w, sl1 + 1);
/*
g.setColor(0, 0, 1);
g.drawLine(0, sl0 + 1, w, sl1 + 1);
g.setColor(0, 0, 0.5); g.setColor(0, 0, 0.5);
g.drawLine(0, sl0 + 2, w, sl1 + 2); g.drawLine(0, sl0 + 2, w, sl1 + 2);
*/
} }
function drawTimes () { function drawTimes () {
g.setColor(1, 1, 1); g.setColor(1, 1, 1);
g.setFont('Vector', 20); g.setFont('6x8', 2);
g.drawString(sr, 10, h - 20); g.drawString(sr, 10, h - 20);
g.drawString(ss, w - 60, h - 20); g.drawString(ss, w - 60, h - 20);
} }
@ -226,17 +229,23 @@ const r = 10;
function drawGlow () { function drawGlow () {
const now = new Date(); const now = new Date();
if (realTime) { if (frames < 1 && realTime) {
pos = xfromTime(now.getHours()); pos = xfromTime(now.getHours());
} }
const rh = r / 2;
const x = pos; const x = pos;
const y = ypos(x - (r / 2)); const y = ypos(x - r);
const r2 = (x > sunRiseX && x < sunSetX) ? r + 20 : r + 10; const r2 = 0;
if (x > sunRiseX && x < sunSetX) {
g.setColor(0.3, 0.3, 0.3); g.setColor(0.2, 0.2, 0);
g.fillCircle(x, y, r2); g.fillCircle(x, y, r + 20);
g.setColor(0.5, 0.5, 0.5); g.setColor(0.5, 0.5, 0);
g.fillCircle(x, y, r + 3); // wide glow
} else {
g.setColor(0.2, 0.2, 0);
}
// smol glow
g.fillCircle(x, y, r + 8);
} }
function seaLevel (hour) { function seaLevel (hour) {
@ -245,6 +254,11 @@ function seaLevel (hour) {
return ypos(xfromTime(hour)); return ypos(xfromTime(hour));
} }
function ypos (x) {
const pc = (x * 100 / w);
return oy + (32 * Math.sin(1.7 + (pc / 16)));
}
function xfromTime (t) { function xfromTime (t) {
return (w / 24) * t; return (w / 24) * t;
} }
@ -252,47 +266,66 @@ function xfromTime (t) {
function drawBall () { function drawBall () {
let x = pos; let x = pos;
const now = new Date(); const now = new Date();
if (realTime) { if (frames < 1 && realTime) {
x = xfromTime(now.getHours()); x = xfromTime(now.getHours());
pos = x;
} }
const y = ypos(x - (r / 2)); const y = ypos(x - r);
// glow // glow
g.setColor(1, 1, 0); if (x < sunRiseX || x > sunSetX) {
if (x < sunRiseX) { g.setColor(0.5, 0.5, 0);
g.setColor(0.2, 0.2, 0); } else {
} else if (x > sunSetX) {
g.setColor(0.2, 0.2, 0);
}
g.fillCircle(x, y, r);
g.setColor(1, 1, 1); g.setColor(1, 1, 1);
}
const rh = r / 2;
g.fillCircle(x, y, r);
g.setColor(1, 1, 0);
g.drawCircle(x, y, r); g.drawCircle(x, y, r);
}
function drawClock () {
const now = new Date();
let curTime = ''; let curTime = '';
let fhours = 0.0; let fhours = 0.0;
let fmins = 0.0; let fmins = 0.0;
let ypos = 32;
if (realTime) { if (realTime) {
fhours = now.getHours(); fhours = now.getHours();
fmins = now.getMinutes(); fmins = now.getMinutes();
} else { } else {
ypos = 32;
fhours = 24 * (pos / w); fhours = 24 * (pos / w);
if (fhours > 23) { if (fhours > 23) {
fhours = 0; fhours = 0;
} }
fmins = (24 - fhours) % 60; const nexth = 24 * 60 * (pos / w);
fmins = 59 - ((24 * 60) - nexth) % 60;
if (fmins < 0) { if (fmins < 0) {
fmins = 0; fmins = 0;
} }
} }
if (fmins > 59) {
fmins = 59;
}
const hours = ((fhours < 10) ? '0' : '') + (0 | fhours); const hours = ((fhours < 10) ? '0' : '') + (0 | fhours);
const mins = ((fmins < 10) ? '0' : '') + (0 | fmins); const mins = ((fmins < 10) ? '0' : '') + (0 | fmins);
curTime = hours + ':' + mins; curTime = hours + ':' + mins;
g.setFont('Vector', 30); g.setFont('Vector', 30);
g.setColor(1, 1, 1); g.setColor(1, 1, 1);
g.drawString(curTime, w / 1.9, 32); g.drawString(curTime, w / 1.9, ypos);
// day-month
if (realTime) {
const mo = now.getMonth() + 1;
const da = now.getDate();
const daymonth = '' + da + '/' + mo;
g.setFont('6x8', 2);
g.drawString(daymonth, 5, 30);
}
} }
function renderScreen () { function renderScreen () {
realPos = xfromTime((new Date()).getHours());
g.setFontAlign(-1, -1, 0);
g.setBgColor(0, 0, 0); g.setBgColor(0, 0, 0);
g.clear(); g.clear();
if (realTime) { if (realTime) {
@ -301,23 +334,55 @@ function renderScreen () {
drawGlow(); drawGlow();
drawSinuses(); drawSinuses();
drawTimes(); drawTimes();
drawClock();
drawBall(); drawBall();
} }
Bangle.on('drag', function (tap, top) { Bangle.on('drag', function (tap, top) {
pos = tap.x; if (tap.y < h / 3) {
curPos = pos;
initialAnimation();
} else {
pos = tap.x - 5;
realTime = false; realTime = false;
}
renderScreen(); renderScreen();
}); });
Bangle.on('lock', () => { Bangle.on('lock', () => {
// TODO: render animation here
realTime = Bangle.isLocked(); realTime = Bangle.isLocked();
renderScreen(); renderScreen();
}); });
Bangle.on('tap', () => {
realTime = true;
renderScreen();
});
renderScreen(); renderScreen();
realPos = xfromTime((new Date()).getHours());
function initialAnimationFrame () {
curPos += (realPos - curPos) / 3;
pos = curPos;
renderScreen();
if (curPos >= realPos) {
frame = 0;
}
frames--;
if (frames-- > 0) {
setTimeout(initialAnimationFrame, 50);
} else {
realTime = true;
renderScreen();
}
}
function initialAnimation () {
const distance = Math.abs(realPos - pos);
frames = distance / 4;
realTime = false;
initialAnimationFrame();
}
setInterval(renderScreen, 60 * 1000); setInterval(renderScreen, 60 * 1000);
pos = 0;
initialAnimation();

View File

@ -2,7 +2,7 @@
"id": "sunrise", "id": "sunrise",
"name": "Sunrise", "name": "Sunrise",
"shortName": "Sunrise", "shortName": "Sunrise",
"version": "0.02", "version": "0.03",
"type": "clock", "type": "clock",
"description": "Show sunrise and sunset times", "description": "Show sunrise and sunset times",
"icon": "app.png", "icon": "app.png",