mirror of https://github.com/espruino/BangleApps
Initial push
parent
405de6d6c0
commit
9910fdcf85
|
@ -0,0 +1 @@
|
||||||
|
0.01: Initial release
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Neon X and IO X Clock
|
||||||
|
|
||||||
|
This is a clock based on Pebble's Neon X and Neon IO X watchfaces.
|
||||||
|
Can be switched between in Settings menu.
|
||||||
|
It can be accessed through the app/widget settings menu of the Bangle.js
|
||||||
|
|
||||||
|
## Settings available
|
||||||
|
|
||||||
|
### Neon IO X:
|
||||||
|
Activate the Neon IO X clock look, a bit hard to read until one gets used to it.
|
||||||
|
|
||||||
|
### Thickness
|
||||||
|
The thickness of watch lines, from 1 to 5.
|
||||||
|
|
||||||
|
### Date on touch
|
||||||
|
Shows the current date as DD MM on touch and reverts back to time after 5 seconds or with another touch.
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"id": "neonx",
|
||||||
|
"name": "Neon X & IO Clock",
|
||||||
|
"shortName": "Neon X Clock",
|
||||||
|
"version": "0.01",
|
||||||
|
"description": "Pebble Neon X & Neon IO X for Bangle.js",
|
||||||
|
"icon": "neonx.png",
|
||||||
|
"type": "clock",
|
||||||
|
"tags": "neonx,neonio,neoniox,clock",
|
||||||
|
"supports": ["BANGLEJS", "BANGLEJS2"],
|
||||||
|
"allow_emulator": true,
|
||||||
|
"screenshots": [{"url": "neonx-screenshot.png"}],
|
||||||
|
"storage": [
|
||||||
|
{"name": "neonx.app.js", "url": "neonx.app.js"},
|
||||||
|
{"name": "neonx.img", "url": "neonx-icon.js", "evaluate": true},
|
||||||
|
{"name": "neonx.settings.js", "url": "neonx.settings.js"}
|
||||||
|
],
|
||||||
|
"data": [{"name": "neonx.json"}]
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,153 @@
|
||||||
|
/**
|
||||||
|
* Bangle.js Neon X/IO X Clock
|
||||||
|
*
|
||||||
|
* Author: Bundyo
|
||||||
|
* Repo:
|
||||||
|
* Initial code based on Numerals Clock by Raik M.
|
||||||
|
* Pebble Watchface Author: Sam Jerichow
|
||||||
|
* Created: February 2022
|
||||||
|
*/
|
||||||
|
|
||||||
|
const digits = {
|
||||||
|
0:[[15,15,85,15,85,85,15,85,15,15]],
|
||||||
|
1:[[85,15,85,85]],
|
||||||
|
2:[[15,15,85,15,85,50], [15,50,15,85,85,85]],
|
||||||
|
3:[[15,15,85,15,85,85,15,85]],
|
||||||
|
4:[[15,15,15,50], [85,15,85,85]],
|
||||||
|
5:[[85,15,15,15,15,50], [85,50,85,85,15,85]],
|
||||||
|
6:[[85,15,15,15,15,85,85,85,85,50]],
|
||||||
|
7:[[15,15,85,15,85,85]],
|
||||||
|
8:[[15,15,85,15],[15,85,85,85]],
|
||||||
|
9:[[15,50,15,15,85,15,85,85,15,85]],
|
||||||
|
};
|
||||||
|
|
||||||
|
const colors = {
|
||||||
|
x: [
|
||||||
|
["#FF00FF", "#00FFFF"],
|
||||||
|
["#00FF00", "#FFFF00"]
|
||||||
|
],
|
||||||
|
io: [
|
||||||
|
["#FF00FF", "#FFFF00"],
|
||||||
|
["#00FF00", "#00FFFF"]
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const is12hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"]||false;
|
||||||
|
const screenWidth = g.getWidth();
|
||||||
|
const halfWidth = screenWidth / 2;
|
||||||
|
const scale = screenWidth / 240;
|
||||||
|
const REFRESH_RATE = 10E3;
|
||||||
|
|
||||||
|
let interval = 0;
|
||||||
|
let showingDate = false;
|
||||||
|
|
||||||
|
function drawLine(poly, thickness){
|
||||||
|
for (let i = 0; i < poly.length; i = i + 2){
|
||||||
|
if (poly[i + 2] === undefined) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (poly[i] !== poly[i + 2]) {
|
||||||
|
g.fillRect(poly[i], poly[i + 1] - thickness / 2, poly[i + 2], poly[i + 3] + thickness / 2);
|
||||||
|
} else {
|
||||||
|
g.fillRect(poly[i] - thickness / 2, poly[i + 1], poly[i + 2] + thickness / 2, poly[i + 3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
g.fillCircle(poly[i], poly[i + 1], thickness / 2);
|
||||||
|
g.fillCircle(poly[i + 2], poly[i + 3], thickness / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let settings = require('Storage').readJSON('neonx.json', 1);
|
||||||
|
|
||||||
|
if (!settings) {
|
||||||
|
settings = {
|
||||||
|
thickness: 4,
|
||||||
|
io: 0,
|
||||||
|
showDate: 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawClock(num){
|
||||||
|
let tx, ty;
|
||||||
|
|
||||||
|
for (let x = 0; x <= 1; x++) {
|
||||||
|
for (let y = 0; y <= 1; y++) {
|
||||||
|
const current = ((y + 1) * 2 + x - 1);
|
||||||
|
let newScale = scale;
|
||||||
|
|
||||||
|
g.setColor(colors[settings.io ? 'io' : 'x'][y][x]);
|
||||||
|
|
||||||
|
if (!settings.io) {
|
||||||
|
tx = (x * 100 + 18) * newScale;
|
||||||
|
ty = (y * 100 + 32) * newScale;
|
||||||
|
} else {
|
||||||
|
newScale = 0.33 + current * 0.4;
|
||||||
|
|
||||||
|
tx = (halfWidth - 139) * newScale + halfWidth;
|
||||||
|
ty = (halfWidth - 139) * newScale + halfWidth + 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < digits[num[y][x]].length; i++) {
|
||||||
|
drawLine(g.transformVertices(digits[num[y][x]][i], { x: tx, y: ty, scale: newScale}), settings.thickness);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw(date){
|
||||||
|
let d = new Date();
|
||||||
|
let l1, l2;
|
||||||
|
|
||||||
|
showingDate = date;
|
||||||
|
|
||||||
|
if (date) {
|
||||||
|
setUpdateInt(0);
|
||||||
|
|
||||||
|
l1 = ('0' + (new Date()).getDate()).substr(-2);
|
||||||
|
l2 = ('0' + ((new Date()).getMonth() + 1)).substr(-2);
|
||||||
|
|
||||||
|
setTimeout(_ => {
|
||||||
|
draw();
|
||||||
|
setUpdateInt(1);
|
||||||
|
}, 5000);
|
||||||
|
} else {
|
||||||
|
l1 = ('0' + (d.getHours() % (is12hour ? 12 : 24))).substr(-2);
|
||||||
|
l2 = ('0' + d.getMinutes()).substr(-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
g.clearRect(0,24,240,240);
|
||||||
|
|
||||||
|
drawClock([l1, l2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setUpdateInt(set){
|
||||||
|
if (interval) {
|
||||||
|
clearInterval(interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (set) {
|
||||||
|
interval = setInterval(draw, REFRESH_RATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g.clear(1);
|
||||||
|
|
||||||
|
Bangle.setUI("clock");
|
||||||
|
|
||||||
|
setUpdateInt(1);
|
||||||
|
draw();
|
||||||
|
|
||||||
|
if (settings.showDate) {
|
||||||
|
Bangle.on('touch', () => draw(!showingDate));
|
||||||
|
}
|
||||||
|
|
||||||
|
Bangle.on('lcdPower', function(on){
|
||||||
|
if (on){
|
||||||
|
draw();
|
||||||
|
setUpdateInt(1);
|
||||||
|
} else setUpdateInt(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
Bangle.drawWidgets();
|
Binary file not shown.
After Width: | Height: | Size: 885 B |
|
@ -0,0 +1,54 @@
|
||||||
|
(function(back) {
|
||||||
|
function updateSettings() {
|
||||||
|
storage.write('neonx.json', neonXSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetSettings() {
|
||||||
|
neonXSettings = {
|
||||||
|
thickness: 4,
|
||||||
|
io: 0,
|
||||||
|
showDate: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
updateSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
let neonXSettings = storage.readJSON('neonx.json',1);
|
||||||
|
|
||||||
|
if (!neonXSettings) resetSettings();
|
||||||
|
|
||||||
|
let thicknesses = [1, 2, 3, 4, 5];
|
||||||
|
|
||||||
|
const menu = {
|
||||||
|
"" : { "title":"Neon X & IO"},
|
||||||
|
"Neon IO X": {
|
||||||
|
value: 0 | neonXSettings.io,
|
||||||
|
min: 0, max: 1,
|
||||||
|
format: v => v ? "On" : "Off",
|
||||||
|
onchange: v => {
|
||||||
|
neonXSettings.showDate = v;
|
||||||
|
updateSettings();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Thickness": {
|
||||||
|
value: 0 | thicknesses.indexOf(neonXSettings.thickness),
|
||||||
|
min: 0, max: thicknesses.length - 1,
|
||||||
|
format: v => thicknesses[v],
|
||||||
|
onchange: v => {
|
||||||
|
neonXSettings.thickness = thicknesses[v];
|
||||||
|
updateSettings();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Date on touch": {
|
||||||
|
value: 0 | neonXSettings.showDate,
|
||||||
|
min: 0, max: 1,
|
||||||
|
format: v => v ? "On" : "Off",
|
||||||
|
onchange: v => {
|
||||||
|
neonXSettings.showDate = v;
|
||||||
|
updateSettings();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"< back": back
|
||||||
|
};
|
||||||
|
E.showMenu(menu);
|
||||||
|
})
|
Loading…
Reference in New Issue