|
@ -1 +1,2 @@
|
|||
0.01: New App!
|
||||
0.02: New 'Settings Menu' to choose your favorite color and switch between light or dark themes
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
# Shadow Clock
|
||||
|
||||
Shadow Clock uses the "Londrina" font in a user selectable color and surrounds it in the "Londrina Shadow" font to create a visually appealing way to show the time in a clear, easily readable manner. On the Bangle.js 2, the time can be read easily even if the screen is locked and unlit.
|
||||
|
||||
## Usage
|
||||
|
||||
* Install Shadow Clock through the Bangle.js app loader.
|
||||
* Configure it through the default Bangle.js configuration mechanism
|
||||
(Settings app, "Apps" menu, "Shadow Clock" submenu).
|
||||
* If you like it, make it your default watch face
|
||||
(Settings app, "System" menu, "Clock" submenu, select "Shadow Clock").
|
||||
|
||||
## Configuration
|
||||
|
||||
Anton Clock is configured by the standard settings mechanism of Bangle.js's operating system:
|
||||
Open the `Settings` app, then the `Apps` submenu and below it the `Shadow Clock` menu.
|
||||
You configure Shadow Clock by selecting a `Light` or `Dark` system wide theme and then selecting the `Color` of the clock numbers.
|
||||
|
||||
## Compatibility
|
||||
|
||||
Shadow Clock should be fully compatible with with Bangle.js 1 and Bangle.js 2. However, it was built and tested with Bangle.js 2
|
||||
|
||||
## Creator
|
||||
|
||||
[stweedo](https://github.com/stweedo)
|
|
@ -1 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwhHXAH4A/AH4A/AH4A/AH4A/AH4A/AFGsAAQOUA4OBDBYfHo8jAAOBByOssgICkdkF6AWEF5IOHxAHDAAVALx4VEF5AOHA4oAD0ovNoEjo6BCF5AOHF4ccp9dAoVdFxh2CioUCa44OIwIFCirwBjgFBqyNPqxJCEAOIKwOIBxYJChwfBwIABJQ7dHnIkCEAsVBxovDdiMcVYIgHFQgOJR4WIxBdMCoccshUCkdkRYJ6DBxIvDAAlkF5wWLBxQKJOAIvTroOOBQkcmU5aoYAKhwACjiqDqwOOTQQqDGwQvMAAawCcoOsAAQOL642DBAI0EAB1AC4QfBJIU5BxQ2DAAp5FF6ZJFF4xgFAAMOOwyPKjkcCgWsAoMyBxQAB1k5BAMcZAQuPDIS6EYBAIRAHKHCAIhPLAoWswIMEL6OBDIgYGHA4qCCwIKBDIgvPDggnIAw7lBF4J4KR5gVJKgZDDIgQCDMITvXXA47EHxD2aFQhOCBAY8DRiiWLD4aEBMYzuCLzgvEEQK4BFAQCDB4TACF7QA/AH4A/AH4A/AAQA=="))
|
||||
require("heatshrink").decompress(atob("mEwxH+64Afq17AAlWq2sBYOtB4Urq2BFzeBwONAAeyHAQvCrPX1g3BlYvb02BjwADF4QmBwdZF4MrleBgAvlgAwBgqQBlcAF72HF46PBwaPDwK/dVoLpBAAwMBweDFTYA/AH4A/AH4A/AF2lAAOsBRIAF6AMDp9Wp+lFyNWkYABitWFwoKCAAsHBgMyBAkVwIuO6EVCod6F50A6+BBI0VMRxGEF6BfBIwZqHABRGCo5EIF4cOgEHAAUA0scBYQDDCAIvMhx7CCYTfDAYIvDK4McNoaODh1PPgcO1jsNiskOYQTBh0cjlW1iDHfwJfDjmeoDKEABSlCgAlCF4QJGcgwPEfQ5eMFQIvDRYIfClesioADEgcrSAguEwJeNh1AAgQkBwOlkkkQoOBvQACIgRAB685F4wJBF5oAGp4UJ1i6CeQK/Dg4ECZYQvTComsnNdrp+B0rADlaKD1l6X52BgAACJIgvEFIcO0sOF4cAAgeISgYvLMg8HKoOBAAIvEAAsOL4bwGFxyuDg/QGoYZBT5AKBXQYvVCYUH1gvFqwjGTwWBGA0AOwIAN6EOhytBAwIFBh1PAoN6g8VskVmUAZoelBQVABQIuPMAS6DfYWBMgI9CwMrq2lDA2Bq1PFqLpCHBAWKMIJGBAgRDEABiKBlYTDAYcA1gKBqwgFlYMBLoIaBCIKZDABh+BDIQVBC4WsF4YOBGAmsBQSgCAIIvQFYIiBKwReDFQI3DEIlWFIIsBCwIABF6JhClZhBZQo8BAYIOBIoh0CBIJ5DAH4AEPYKBDWwSGCAoKIDAoIwcEwJ/CRYICCFoI8BQ4YKBMDhWBEwIjBYQcAAYQKBZIRfdAIJVCQgLkDAYJjCcX4A/AH4A/AFwA=="))
|
||||
|
|
|
@ -1,63 +1,95 @@
|
|||
// Clock with large colored digits using the "Londrina" font and a slightly larger "Londrina Shadow" font on top
|
||||
|
||||
Graphics.prototype.setFontLondrinaSolid = function() {
|
||||
// Actual height 59 (64 - 6)
|
||||
return this.setFontCustom(
|
||||
E.toString(require('heatshrink').decompress(atob('ADX/4AJHv/gBI8/+AJHj/4BI8P/gJHg/+BI8D/4JHgP/wBQbAFEBBJEHKBEfKCJuBUI6CBUI8P/6hHn//UI//AAImHAAJQFg4JCKAsfBJF/Do5XBAAI7FEwZPFEwZtFEwaBEEwYwFEwYwFEwaKFPwImGCYh1FTgKTHGISxGSYTPGJ4TjHWA5tCZw5QBew5QBJooACgwIHAELmIOAReGRwR8GBIhpEVgYeFBIozDBIr9DBIooDBIooDHYjhEBIxRCBIwyCdAXgbAQyCO4LxCBwP+dAb7Dv48CBIpLBHgRVEG4JvCv4iCFARGCn5fDG4JGCEQgtEEQgtEKAgTBKAgeCa4TmFS4w8BS46rGBISNCagwtCbw4JJGQoJDYAoJDFAoJDFApFCKIwJEDwavDaAjDECgq9CAEMBEpEDcYQAFg5DGQYRXGNwYJJRIirEHg4JBHg6BB/AJIIw4dBIw47BCY7dBE4LrCBwUHfgoiCc4oABSoQJGb4QJGOYTcCAAZzCHAQADOYRQBAAhzCKAIAEKF7+IAHUHNQR0BKASOCMAJVBKYaiBB4KhEB4ihEBIQPBUIgJCB4KhEBIQPBUIgJCB4KhFbwSbDKAQJCwAJCKAToC4AJCKAToC8AXCKAToC+AJCeQuABITyEBwIrB57yEBIeHeQgJBGoODeQgiBBIOBKAYuBBIWAKAa0CH4JmBKAQQB4DHCn5QE+AJCj5QE/wWB8ACBKAYAC8AqCKAQAC+AZBUIoJBDIKhFaoahFBIRQDEQKeDKAY8DR4TyFR4gJCGQQJBKAjACBIJQELYQJBKAgeCHAV/KAQPCJgQAjj5LCAAt/IIRPESQiMDBIQFCe4QJDLIReBNwiSCRgJkDPAIJDFAahBIwKRBVYojBYgQJCG4JQBYgRfCBIItCBII8CIIPwgfAEQLyE+DlBHgg3B+DlBGQJfCBITlCIwYOB/DlCPIbICcoQ3BIwQiBBIPgEAJGCv/+CwPwEAKwCEQQgDKAQiCv/8ewgYB4AWBBIJQCIwRsB8JQDRAQAEWogAEKAQbBBI48BAAhaCL4IAELQTFCBIw8GBIQyGfgZiBCY4yFBIYyFIoQoGLIQUEDYYAjh4oIeAgAEM4JPEBIgeHLgKBDAAZbBeAQADUYTwCBIzwCPIzwDAAUHRg6sEKAoJB/hQGNgP8v5QFBIP4n5QFNgPwj5QFNgPgh5QFBIRIBOw3ALgJQEBIRwCKQYdBCAIJCKQQ7Bf4hSCJ4IAEKQR3DAARSCRYYACKQSfDAAazEAAhSCBIxQEAAhQEAAhQSWwoNDBAxeCdApeDdApeDdAqvDGI4AkHAJCHS4fwBwJbDS4R/BI4iXCaAN/aYSXDaAL3DS4gOCG4ToDwAOBPQToD4AOBWoToD8AOBfgRQGGQZQFLYZQFGQZQGMoRBBBYJLCHgQEBx4kBGQJvCIIPHMIV/IwQOB8YuCPIn/+IkCFYJGCv/4EgQ3BQYU//gkCG4JQD/wkBwAJBKA3gKBH8BwJQE4aPCBIZQB8IJDUInwBIahE/CZCBIhQBTISrEKALgDMgZBBawbyFwDMCBIZQB4AoDPAQbBNgQJEKAT1DBIZQBcIYnCKAIhDJ4YAEgIcDAFhOEAASEBAALcCKIaqGBIwUEBIjTDBIpvEBIo+DBIqSBagQJEFAYJFFAZZDdA4AEKIT6EGQgJG/jyD/4MDHgTQBDAIKDHgQJGHgTyCEIRvDv4sBEIPPIwc/FgIJB4JGDNwIrC4AJDMgI2Bv/An5QCHAIsBn/gj5QCHAIOBj/wEYYkBEoMP/AjDEgIeBg/8EYJaCX4PwEIIJEDAP4KAJkEBwIyBBIoQBIIIrBNwYQCa4YJDGQOAZoTyDAwPAS4QJDFAItBBIovBEYIhBBIkHBIIhBGIYAEJ4YAgsAEDgL8DG4kDfgpLDHoTYDOgQZCbAYFCeQhzEeQg2CG4LyEGwTLCSwoOCDIZQDEQIZDKAbACKAzUFKAa1BWwZQDeQpQDBAJBF4BOCKovgIgRpF+BECPov4IgQJEKAJECTYv+IgSvFDYRYDPwhYESQgJGK4ZiDKAZiFKAZiGSYhYEU4hYEKAgJGKARiEKAhiEKAhYEKAhYFIwZYFIwYIGAEcBMwxQBn5xFI4KbCJQgGB8ByGQYSQGYAa4FBIp9DBIooDBIqvDbwbXFBIwyCdAb/FdAQADYgQJGHgTyCAAOHHgbyB/A0BwJvDeQP4CwOABgLyD/gWB4BBBIwQYBCwPgG4JGCDAIWB+AgBQYQYCEAZQEWgP+IIRQG45QFAAhQEBI6rGUKgJCHgirEHgwJCNgLyLz4JFGQS0BBIgoCQgInDFAaRDBISOBNQJzBBAYAzv48BgKqDN4ZXBLQgJCbQN/boQJDDYM/DwiyDe4JvDTwa6BFAYJC/CRB+DeF/yDB/joGTYIyDdAfAeRHgDAIyCIIIAB+AOBZQT8D/gOBMoT8DHgoEB/AlBKoI8CBIRsCBgTnCMQXAPIgiBCwJ5FWgRGBCwJGCJYIJBEARGCF4YJFEQU/LQRQCTgR7DKAgAFKAYAFKAYAFKAQlDBIqhDVwahFBIo8GdAQ8GeQwJGGQoJDZQYxELYxPCCgwIDAAcBEwYA/QoK8Bn5IFMQUfeQQJDOwMPeQSZDDQMHeQQACn4aBXYIJEj4aBGoYACh4aCTA4rCVggkBKCQAkA='))),
|
||||
46,
|
||||
atob("DyEqHigoJikpJygqEQ=="),
|
||||
81|65536
|
||||
);
|
||||
};
|
||||
|
||||
Graphics.prototype.setFontLondrinaShadow = function() {
|
||||
// Actual height 63 (67 - 5)
|
||||
return this.setFontCustom(
|
||||
E.toString(require('heatshrink').decompress(atob('ADX/8AJH4EQBI9AhwJHkEHBI8QgeABI0IgPABI0EgA8HgUAuAJGgMAnAyHwEcKBH+BI8f/4JHg//KA49CDxATInFgBI/wKA8D4BQHh8AUI88I4IJG/AfBHgsBSgKhGg4QCUIseAYShFGAJbCK4oDC/hXFGgQJEK4I0CBIgmDh5SBEw0/IoYmDgF/AgYmDgLIEvgwDbggmDj4wEXAd/OwkwAYX/RQkYHwT5FhgmCMIkAgwmHDQJNCXYxNBEwoABwAmGKAV/LgYADiJNFQQYmHV4wAa/4ABMwwGCv49FWI8AjgEDhyiGP4SGDWwbGFBIsIAYUQBIkCBJAoDBIooDHYgABnArFcooCCg/4AYToDbwP/BQIyCH4MDRoQHBYoLoDwE/SANwCwSXDvA8D4EDbwUESYdggITCFoKYCQQIJCFoRkDRwYtBHwJaBWweAgItBEQMHAgIRCEYIiBbYJaBAgJQBDAIKCJARSBYYiXFVYw3CS4QJGgYJFjxLDBJAyFBIbUFBIZ8CAAU+ewZXCBIpUDAAP+AgcPDAf8BIcBeAUPAYQACn/wdQPwBIjyDGwgUC/4wEKISPGAAMOR4yRCgwJHjEBR4r9DHIyXCZgwHCPQgACDYI8HBII8HHIMDHg1ABII8GkBvB8EPQgKYCOwMHA4YsChAaFFgUEBIraCgRhIgJ/IKASdFKAaxFKAbFFKAZGHKAxGCKA0A8BQI+BQIuACB//9QQIACRoU/BAn//gJBToQJGAFIzBAYMf/5kBAAM8f4V8gEYLwixBBYKhCPgUYgKUBUIQPDBIShCBIUHBIShCBIUDwIQCHgQJBB4IJCS4T1BB4IaCnAJEuAJCeQT/CuD2CKAToCnAXCKAToCjgJCKAUMAoN+kDyGgf/FYIVBeQYJB2EAbgJQBeQMD/A1BaQJQCwEB8CdB/xQDoAJBH4P5KAY4BBIV4wBQCEgMwJIN4oBQCCAMcBIUgKAkHFoM8DIJQDJoU8DIJQCU4UAjwZBKASdCBIIZBKAR/CgEPNQKhFBIJqBKAQiBVAWAKAY8CBIRQDDAKyC4BQDbwYJBKAcASgIJCKAkGBIXgKAgrCBIJQEbgI7BFwP//5XDAoIJBn//IYUBBIIgBg4JDABV/CQIXBBIngmADBz/wBASsBdoZFDBILtDXgYDBdoiyCBIKcCPoJ/CS4JwCegJ/CUIRjBRgIYCG4KcCXQS1CBIKcBRgKrDGoJQCDYKrCMQMOv/4DAI0BJYUPsEGIgI8CZwMP0EBww8DIIMPyEB8ZVDCwMPxBSBFAJVBgaxBwhDBG4JGBPAWCIYItBIwXAgfBIYItBKoVgFgOAgxvBUwQiB8AWBwYtBBIJVBmA5BEAJQFfYRQDEQIECDYQOBSQQAES4SuCAAd4UIYAELQSXBAAhaCUgQADjwCBZ4QJGQYIJEh4DCMQIJHGQsfAYTNCBIwoFv4EE/4ADDAgID/wJDgYJD+CJGABIgBBI6JBL4qnDSoQAEXYKVCAAbKCeAQJGagRREOAICCAAYQCCwQADEgY0BBI7wCbAkBKA0YGARQFmAzB4BQFEYMH8BQFsDaB6BQFIIMfxBQFAgMfghQEBwU/gUAu//CoQiBvxQBj/AIQKwCvgNCUYcgeYQaCKQUQTgpSChCmIIQK6HIQLYHIQLsHIQYADUYRQBWIxQCYo5QGj5QDgf/+EA///F4MHAgP//AJCKAMBBIX8PgP+EIQRCLwLoFNYREDAAuAvwJHUYIJHj5ECACpiBAAPwL4JCEAAMMKIL9DFgUHBwMMBIShCaAOAgYJCUITQBBwL1CUIfgBwMweQtwBwIoCeQc4WAQFBeQccBwMBIYJQDhwOCKIRQFGQZQFeQxQDeQjmB8E8EIJQDvBQBh48DIIIQBnAfBN4RBBFgIBBFoNwKAQsBAIItBegWAFgIBBFoJGCoBOBAIKBBIwUgFwYJBIwRQDmAJCIwJQDg/8OQRQECwQjCKAMefQiXBKAMPTIQWDKASZCZoRQD2AJDG4JQC5AJDG4RQB8wJGKANxGQZBCKAM4sAJFUISICgEfaASHBOgQJDKALGB/AFBn4JCv//CAJ1BAgIXC/6rB////wJCg//CIM/BIgADgP/FQQAWFIIABBIs/WAMDZQKlGBQJABAAS0ESwQJGgYJIgAeDBIsYAYSpDAAMGAYUgOIqlCmBWFFATeBAAgQCFYYACZwToBGQ7oBAAhbCBgKpBFwUBAYLyBS4KLDSQLyBh4JESYTyB8BhDnBTCg+AEIIHBIwVggeAEIN+gEOLoQ2BOoM/wEHMgY2B4E8oAZBgEMOYVAj0gKAQ4Bh6aBhyIBcYRSB8EQg4jBKAZBBhEDxEAvDJDhyGBMwJaCGAMHLQyhBgeBYwUeS4nAS4RkCNYJBBcIRLBGQdwZoRuCGQU4YYSSBEIccEIQJDgfABYIyBBIcAvhBBJ4MPH4UAj//CIUfCYbnBWwP/AYL3DL4U/C4IAITwICB/6lBAAQ8CJgJiCKwSrDPoTaCUIVAOYZ0BUIUgcQSQCDIUQcQSkCDIS1BHgQXBDISTBGwQRBDITQDXoYZBKAI2CAQRQGCwRQGCARQGHwRQFYQKxCKAhwDn5QEQgd/AQJQCFoUAWwRQCIIUB/wNCwEGIgUD/gJCoEDQYf4BIUggKhCg/wBIUQWgcPbAZQBAAUfLgRQCLAYJDKAJiFKAZiFKAYDCLAZQCC4RYDKARiGKAkHMQZQEh5iDKAkfMQZQELAhQEv5JDKAixCKAqxEOgn/JwpNC/5OFBw40Fj5ZBn4rFv0/gHwgJTEMQPgA4MYLYYjBjoCBgwJFgYCBdocDXItgBIoACFATUEAAIoCBIwoCFYYADKIQJGuDoEGQw/CAAcOAQMwA4YEBg4WDh6GCNAcMBIKEBawQ8BKYMHWwM8G4IvBNwMDwgJBkEAnBaCgPCgEciACBLofhEQMIIwYgBuIgBghGDJYMfAgPMIwbDDGQIJBEoJQBS4oJBgT/GL4KrGS4ahGvCXIMgMAL4IAEHwI8HjwCBHgYhCBITeDFwQJCH4a0BOYaQDvphBn4JCg4eB/geBv42D/EH/kf9/+BIc///4gf/BIgGB+AcBa4IADh57GABYaCGgKvE8BIBgTICGIQEBuCwBbQIJCSAeASYYJCQwNAAoQJDS4MggB7BagkYXQIoCUIcGhC8DBIcDggkEEIUA4QQEoAJCuICB8DyFjARBGQRBBAAMODALGCfgcHCIMOAoJBBIAWcOosPHwPHHgcGBIK/BuAMBHgIWBh+8gE4G4NwCwUHwQ5BG4M4MgUDwI5BG4JGCsEB4GAh43BIwRLB8HAg4RBg5qCBYIgBcALQCDAMcR4YjBKATkEKAS/DAAZQBcYIJFvCrFAAU8UIoACUIwACjwCBbIIAEh4CBgQJIHg0PAwQyFBIZvBAAcfBIRtFv4FD/6CCgP/DAn/AAX+BIcDBIf8JgoJCSoIAig5DCv/wBIbMBK4NgfwIACR4LGBkDyCMIUAnCxBOouAXgMIeQQACoEOXYRcEEgQrDAAQkCFYYACEgYrCAAQkDFYRQEMIMgbwaXC/DTB/5QEn6pBWAJQEh4FCWwwAFA'))),
|
||||
46,
|
||||
atob("DyEqHigoJikpJygqEQ=="),
|
||||
81|65536
|
||||
);
|
||||
};
|
||||
|
||||
(function() {
|
||||
let drawTimeout;
|
||||
|
||||
// Actually draw the watch face
|
||||
function draw() {
|
||||
const x = g.getWidth() / 2;
|
||||
const y = g.getHeight() / 2;
|
||||
g.reset().clearRect(Bangle.appRect);
|
||||
const date = new Date();
|
||||
var hour = String(date.getHours()).padStart(2, '0');
|
||||
if (hour[0] === '0') hour = hour[1];
|
||||
var minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
const timeStr = hour + ':' + minutes;
|
||||
|
||||
g.setFontAlign(0, 0).setFont("LondrinaSolid").setColor(0, 1, 1).drawString(timeStr, x - 1, y);
|
||||
g.reset().setFontAlign(0, 0).setFont("LondrinaShadow").drawString(timeStr, x - 1, y);
|
||||
|
||||
const locale = require("locale");
|
||||
const dateStr = locale.date(date, 0).toUpperCase() + "\n" +
|
||||
locale.dow(date, 0).toUpperCase();
|
||||
g.setFontAlign(0, 0).setFont("6x8", 2).drawString(dateStr, x, y + 48);
|
||||
|
||||
if (drawTimeout) clearTimeout(drawTimeout);
|
||||
drawTimeout = setTimeout(() => {
|
||||
drawTimeout = undefined;
|
||||
draw();
|
||||
}, 60000 - (Date.now() % 60000));
|
||||
}
|
||||
|
||||
Bangle.setUI({
|
||||
mode: "clock",
|
||||
remove: function() {
|
||||
// Actual height 59 (64 - 6)
|
||||
return this.setFontCustom(
|
||||
E.toString(require('heatshrink').decompress(atob('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'))),
|
||||
46,
|
||||
atob("DyEqHigoJikpJygqEQ=="),
|
||||
81 | 65536
|
||||
);
|
||||
};
|
||||
|
||||
Graphics.prototype.setFontLondrinaShadow = function() {
|
||||
// Actual height 63 (67 - 5)
|
||||
return this.setFontCustom(
|
||||
E.toString(require('heatshrink').decompress(atob('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'))),
|
||||
46,
|
||||
atob("DyEqHigoJikpJygqEQ=="),
|
||||
81 | 65536
|
||||
);
|
||||
};
|
||||
|
||||
Graphics.prototype.setFontDotGothic16 = function() {
|
||||
// Actual height 20 (19 - 0)
|
||||
return this.setFontCustom(
|
||||
E.toString(require('heatshrink').decompress(atob('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'))),
|
||||
32,
|
||||
atob("CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoA"),
|
||||
20|65536
|
||||
);
|
||||
};
|
||||
|
||||
let storage = require('Storage');
|
||||
|
||||
var settings = Object.assign({
|
||||
// default values
|
||||
color: "#0ff",
|
||||
theme: "light",
|
||||
}, storage.readJSON("shadowclk.json", true) || {});
|
||||
|
||||
(function() {
|
||||
let drawTimeout;
|
||||
|
||||
function draw() {
|
||||
var x = g.getWidth() / 2;
|
||||
var y = g.getHeight() / 2;
|
||||
g.reset().clearRect(Bangle.appRect);
|
||||
var date = new Date();
|
||||
var hour = String(date.getHours()).padStart(2, '0');
|
||||
if (hour[0] === '0') hour = hour[1];
|
||||
var minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
var timeStr = hour + ':' + minutes;
|
||||
var color = settings.color;
|
||||
g.setFontAlign(0, 0).setFont("LondrinaSolid").setColor(color).drawString(timeStr, x - 1, y);
|
||||
g.reset().setFontAlign(0, 0).setFont("LondrinaShadow").drawString(timeStr, x - 1, y);
|
||||
|
||||
var locale = require("locale");
|
||||
var dayOfMonth = date.getDate();
|
||||
var month = locale.month(date, 1).slice(0, 1).toUpperCase() + locale.month(date, 1).slice(1).toLowerCase();
|
||||
var year = date.getFullYear();
|
||||
var dayOfMonthStr = dayOfMonth.toString();
|
||||
if (dayOfMonth === 1 || dayOfMonth === 21 || dayOfMonth === 31) {
|
||||
dayOfMonthStr += "st";
|
||||
} else if (dayOfMonth === 2 || dayOfMonth === 22) {
|
||||
dayOfMonthStr += "nd";
|
||||
} else if (dayOfMonth === 3 || dayOfMonth === 23) {
|
||||
dayOfMonthStr += "rd";
|
||||
} else {
|
||||
dayOfMonthStr += "th";
|
||||
}
|
||||
var dayOfWeek = locale.dow(date, 0).slice(0, 1).toUpperCase() + locale.dow(date, 0).slice(1).toLowerCase();
|
||||
var dateStr = month + " " + dayOfMonthStr + ", " + year + "\n" + dayOfWeek;
|
||||
g.setFontAlign(0, 0).setFont("DotGothic16").drawString(dateStr, x, y + 48);
|
||||
|
||||
if (drawTimeout) clearTimeout(drawTimeout);
|
||||
drawTimeout = undefined;
|
||||
drawTimeout = setTimeout(() => {
|
||||
drawTimeout = undefined;
|
||||
draw();
|
||||
}, 60000 - (Date.now() % 60000));
|
||||
}
|
||||
});
|
||||
|
||||
Bangle.loadWidgets();
|
||||
draw();
|
||||
setTimeout(Bangle.drawWidgets, 0);
|
||||
})();
|
||||
|
||||
Bangle.setUI({
|
||||
mode: "clock",
|
||||
remove: function() {
|
||||
if (drawTimeout) clearTimeout(drawTimeout);
|
||||
drawTimeout = undefined;
|
||||
delete Graphics.prototype.setFontLondrinaSolid;
|
||||
delete Graphics.prototype.setFontLondrinaShadow;
|
||||
delete Graphics.prototype.setFontDotGothic16;
|
||||
}
|
||||
});
|
||||
Bangle.loadWidgets();
|
||||
draw();
|
||||
setTimeout(Bangle.drawWidgets, 0);
|
||||
})();
|
||||
|
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 446 B |
|
@ -0,0 +1,283 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" href="../../css/spectre.min.css">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Londrina+Solid&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Londrina+Shadow&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=DotGothic16&display=swap" rel="stylesheet">
|
||||
<title>3-Bit Color Picker</title>
|
||||
<style>
|
||||
.main-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.color-button {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: 1px solid black;
|
||||
margin: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.color-0 {
|
||||
background: #000
|
||||
}
|
||||
|
||||
.color-1 {
|
||||
background: #f00
|
||||
}
|
||||
|
||||
.color-2 {
|
||||
background: #0f0
|
||||
}
|
||||
|
||||
.color-3 {
|
||||
background: #ff0
|
||||
}
|
||||
|
||||
.color-4 {
|
||||
background: #00f
|
||||
}
|
||||
|
||||
.color-5 {
|
||||
background: #f0f
|
||||
}
|
||||
|
||||
.color-6 {
|
||||
background: #0ff
|
||||
}
|
||||
|
||||
.color-7 {
|
||||
background: #fff
|
||||
}
|
||||
|
||||
#preview-box {
|
||||
width: 176px;
|
||||
height: 176px;
|
||||
border: 1px solid black;
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: white;
|
||||
}
|
||||
|
||||
#preview-canvas {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#toggle-bg {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#upload {
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script src="../../lib/interface.js"></script>
|
||||
<div class="main-container">
|
||||
<h1>3-Bit Color Picker</h1>
|
||||
<div>
|
||||
<script>
|
||||
let colors = ['#000', '#f00', '#0f0', '#ff0', '#00f', '#f0f', '#0ff', '#fff'];
|
||||
colors.forEach((color, i) => {
|
||||
document.write(`<button class="color-button color-${i}" data-color="${color}"></button>`);
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
<button id="toggle-bg" class="btn btn-primary" onclick="toggleBackground()">Light/Dark</button>
|
||||
<div id="preview-box">
|
||||
<canvas id="preview-canvas" width="176" height="176"></canvas>
|
||||
</div>
|
||||
<button id="upload" class="btn btn-primary">Upload</button>
|
||||
<script src="../../core/lib/customize.js"></script>
|
||||
</div>
|
||||
<script>
|
||||
let selectedColor = "#0ff";
|
||||
let isDarkBg = false; // Add this line to track the background state
|
||||
document.querySelectorAll(".color-button").forEach(button => {
|
||||
button.addEventListener("click", () => {
|
||||
selectedColor = button.dataset.color;
|
||||
drawText(selectedColor);
|
||||
});
|
||||
});
|
||||
|
||||
function formatTime(date) {
|
||||
let hours = date.getHours();
|
||||
let minutes = date.getMinutes();
|
||||
let formattedHours = hours < 10 ? `${hours}` : `${hours}`;
|
||||
let formattedMinutes = minutes < 10 ? `0${minutes}` : `${minutes}`;
|
||||
return `${formattedHours}:${formattedMinutes}`;
|
||||
}
|
||||
|
||||
function getCurrentDate() {
|
||||
let months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
||||
let suffixes = ["st", "nd", "rd", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th", "th", "st"];
|
||||
let date = new Date();
|
||||
let month = months[date.getMonth()];
|
||||
let day = date.getDate();
|
||||
let suffix = suffixes[day - 1];
|
||||
let year = date.getFullYear();
|
||||
return `${month} ${day}${suffix}, ${year}`;
|
||||
}
|
||||
|
||||
function getCurrentDay() {
|
||||
let days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
||||
let date = new Date();
|
||||
return days[date.getDay()];
|
||||
}
|
||||
|
||||
function toggleBackground() {
|
||||
let previewBox = document.getElementById("preview-box");
|
||||
isDarkBg = !isDarkBg; // Toggle the background state
|
||||
previewBox.style.backgroundColor = isDarkBg ? "black" : "white";
|
||||
drawText(selectedColor); // Redraw the text with updated color
|
||||
}
|
||||
|
||||
function drawText(color) {
|
||||
let canvas = document.getElementById("preview-canvas");
|
||||
let ctx = canvas.getContext("2d");
|
||||
|
||||
// Clear the canvas
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
// Set the base font and selected color
|
||||
ctx.font = "81px Londrina Solid";
|
||||
ctx.fillStyle = color;
|
||||
|
||||
// Get the current local system time
|
||||
let currentTime = formatTime(new Date());
|
||||
|
||||
// Measure the text width and calculate the horizontal position
|
||||
let timeWidth = ctx.measureText(currentTime).width;
|
||||
let xPos = (canvas.width - timeWidth) / 2;
|
||||
|
||||
// Measure the text height based on the font size and calculate the vertical position
|
||||
let timeHeight = ctx.measureText('M').actualBoundingBoxAscent + ctx.measureText('M').actualBoundingBoxDescent;
|
||||
let yPos = (canvas.height + timeHeight) / 2;
|
||||
|
||||
// Draw the time
|
||||
ctx.fillText(currentTime, xPos, yPos);
|
||||
|
||||
// Set the outline font and color
|
||||
ctx.font = "81px Londrina Shadow";
|
||||
|
||||
// Set the text color based on the background state
|
||||
if (isDarkBg) {
|
||||
ctx.fillStyle = "#fff";
|
||||
} else {
|
||||
ctx.fillStyle = "#000";
|
||||
}
|
||||
|
||||
// Draw the time again
|
||||
ctx.fillText(currentTime, xPos, yPos);
|
||||
|
||||
// Set the font for the date
|
||||
ctx.font = "19px DotGothic16";
|
||||
|
||||
// Get the current date
|
||||
let currentDate = getCurrentDate();
|
||||
|
||||
// Measure the date width and calculate the horizontal position
|
||||
let dateWidth = ctx.measureText(currentDate).width;
|
||||
xPos = (canvas.width - dateWidth) / 2;
|
||||
|
||||
// Draw the date
|
||||
yPos += 20;
|
||||
ctx.fillText(currentDate, xPos, yPos);
|
||||
|
||||
// Get the current day of the week
|
||||
let currentDay = getCurrentDay();
|
||||
|
||||
// Measure the day width and calculate the horizontal position
|
||||
let dayWidth = ctx.measureText(currentDay).width;
|
||||
xPos = (canvas.width - dayWidth) / 2;
|
||||
|
||||
// Draw the day of the week
|
||||
ctx.fillText(currentDay, xPos, yPos + 20);
|
||||
}
|
||||
|
||||
// Update the time every second
|
||||
setInterval(() => {
|
||||
drawText(selectedColor);
|
||||
}, 1000);
|
||||
|
||||
function hexToDec(hex) {
|
||||
if (hex.length === 4) {
|
||||
hex = `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}`;
|
||||
}
|
||||
let r = parseInt(hex.slice(1, 3), 16) >> 3;
|
||||
let g = parseInt(hex.slice(3, 5), 16) >> 2;
|
||||
let b = parseInt(hex.slice(5, 7), 16) >> 3;
|
||||
return (r << 11) | (g << 5) | b;
|
||||
}
|
||||
|
||||
// Colors from 'Light BW' and 'Dark BW' themes
|
||||
function createThemeColors(isDarkBg) {
|
||||
return isDarkBg ? {
|
||||
fg: hexToDec("#fff"),
|
||||
bg: hexToDec("#000"),
|
||||
fg2: hexToDec("#fff"),
|
||||
bg2: hexToDec("#004"),
|
||||
fgH: hexToDec("#fff"),
|
||||
bgH: hexToDec("#00f"),
|
||||
dark: true
|
||||
} : {
|
||||
fg: hexToDec("#000"),
|
||||
bg: hexToDec("#fff"),
|
||||
fg2: hexToDec("#000"),
|
||||
bg2: hexToDec("#cff"),
|
||||
fgH: hexToDec("#000"),
|
||||
bgH: hexToDec("#0ff"),
|
||||
dark: false
|
||||
};
|
||||
}
|
||||
|
||||
function saveThemeToSettings(theme) {
|
||||
Puck.eval('require("Storage").readJSON("setting.json", true)', (data) => {
|
||||
if (data) {
|
||||
// Ensure that data.theme exists
|
||||
if (!data.theme) {
|
||||
data.theme = {};
|
||||
}
|
||||
|
||||
// Save all theme values
|
||||
for (let key in theme) {
|
||||
data.theme[key] = theme[key];
|
||||
}
|
||||
|
||||
data.clock = "shadowclk.app.js"; // Set Shadow Clock as default
|
||||
|
||||
Puck.write(`require("Storage").write("setting.json", ${JSON.stringify(data)});\n`, (result) => {
|
||||
console.log('Theme saved:', result);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById("upload").addEventListener("click", function () {
|
||||
// Save theme settings to Bangle.js
|
||||
let themeColors = createThemeColors(isDarkBg);
|
||||
saveThemeToSettings(themeColors);
|
||||
|
||||
// Save Shadow Clock color setting
|
||||
let data = {
|
||||
color: selectedColor,
|
||||
theme: isDarkBg ? "dark" : "light"
|
||||
};
|
||||
Puck.write(`require("Storage").write("shadowclk.json", ${JSON.stringify(data)});\n`, (result) => {
|
||||
console.log('Color saved:', result);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -1,16 +1,35 @@
|
|||
{
|
||||
"id": "shadowclk",
|
||||
"name": "Shadow Clock",
|
||||
"version": "0.01",
|
||||
"description": "A simple clock using the Londrina font with color and a shadowed outline. Based on the Anton Clock.",
|
||||
"version": "0.02",
|
||||
"description": "A simple clock using the Londrina font in color with a shadowed outline. Based on the Anton Clock.",
|
||||
"icon": "app.png",
|
||||
"screenshots": [{"url":"screenshot.png"},{"url":"screenshot-1.png"}],
|
||||
"screenshots": [{
|
||||
"url": "screenshot.png"
|
||||
}, {
|
||||
"url": "screenshot-1.png"
|
||||
}],
|
||||
"type": "clock",
|
||||
"tags": "clock",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"supports": ["BANGLEJS", "BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"interface": "interface.html",
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"shadowclk.app.js","url":"app.js"},
|
||||
{"name":"shadowclk.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
}
|
||||
"storage": [{
|
||||
"name": "shadowclk.app.js",
|
||||
"url": "app.js"
|
||||
},
|
||||
{
|
||||
"name": "shadowclk.settings.js",
|
||||
"url": "settings.js"
|
||||
},
|
||||
{
|
||||
"name": "shadowclk.img",
|
||||
"url": "app-icon.js",
|
||||
"evaluate": true
|
||||
}
|
||||
],
|
||||
"data": [{
|
||||
"name": "shadowclk.json"
|
||||
}]
|
||||
}
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 3.4 KiB |
|
@ -0,0 +1,104 @@
|
|||
(function(back) {
|
||||
let teletextColors = ["#000", "#f00", "#0f0", "#ff0", "#00f", "#f0f", "#0ff", "#fff"];
|
||||
let teletextColorNames = ["Black", "Red", "Green", "Yellow", "Blue", "Magenta", "Cyan", "White"];
|
||||
|
||||
// Load and set default settings
|
||||
let appSettings = Object.assign({
|
||||
color: teletextColors[6],
|
||||
theme: 'light',
|
||||
}, require('Storage').readJSON("shadowclk.json", true) || {});
|
||||
|
||||
// Save settings to storage
|
||||
function writeSettings() {
|
||||
require('Storage').writeJSON("shadowclk.json", appSettings);
|
||||
}
|
||||
|
||||
// Colors from 'Light BW' and 'Dark BW' themes
|
||||
function createThemeColors(mode) {
|
||||
let cl = x => g.setColor(x).getColor();
|
||||
return mode ? {
|
||||
fg: cl("#fff"),
|
||||
bg: cl("#000"),
|
||||
fg2: cl("#fff"),
|
||||
bg2: cl("#004"),
|
||||
fgH: cl("#fff"),
|
||||
bgH: cl("#00f"),
|
||||
dark: true
|
||||
} : {
|
||||
fg: cl("#000"),
|
||||
bg: cl("#fff"),
|
||||
fg2: cl("#000"),
|
||||
bg2: cl("#cff"),
|
||||
fgH: cl("#000"),
|
||||
bgH: cl("#0ff"),
|
||||
dark: false
|
||||
};
|
||||
}
|
||||
|
||||
// Switch theme and save to storage
|
||||
function switchTheme(mode) {
|
||||
if (mode === g.theme.dark) return;
|
||||
let s = require('Storage').readJSON("setting.json", 1) || {};
|
||||
s.theme = createThemeColors(mode);
|
||||
require('Storage').writeJSON("setting.json", s);
|
||||
updateTheme(mode);
|
||||
}
|
||||
|
||||
// Update the current menu with the new theme
|
||||
function updateTheme(mode) {
|
||||
let newTheme = createThemeColors(mode);
|
||||
g.theme = newTheme;
|
||||
appSettings.theme = mode ? 'dark' : 'light';
|
||||
writeSettings();
|
||||
delete g.reset;
|
||||
g._reset = g.reset;
|
||||
g.reset = function(n) {
|
||||
return g._reset().setColor(newTheme.fg).setBgColor(newTheme.bg);
|
||||
};
|
||||
g.clear = function(n) {
|
||||
if (n) g.reset();
|
||||
return g.clearRect(0, 0, g.getWidth(), g.getHeight());
|
||||
};
|
||||
g.clear(1);
|
||||
Bangle.drawWidgets();
|
||||
showMenu();
|
||||
}
|
||||
|
||||
// Read the current system theme
|
||||
function getCurrentTheme() {
|
||||
let s = require('Storage').readJSON("setting.json", 1) || {};
|
||||
if (!s.theme) {
|
||||
return appSettings.theme; // fallback to appSettings.theme (light or dark)
|
||||
}
|
||||
return s.theme.dark ? 'dark' : 'light';
|
||||
}
|
||||
|
||||
function showMenu() {
|
||||
appSettings.theme = getCurrentTheme();
|
||||
E.showMenu({
|
||||
"": {
|
||||
"title": "Shadow Clock"
|
||||
},
|
||||
"< Back": () => back(),
|
||||
'Theme:': {
|
||||
value: (appSettings.theme === 'dark'),
|
||||
format: v => v ? "Dark" : "Light",
|
||||
onchange: v => {
|
||||
switchTheme(v);
|
||||
}
|
||||
},
|
||||
'Color:': {
|
||||
value: teletextColors.indexOf(appSettings.color),
|
||||
min: 0,
|
||||
max: 7,
|
||||
onchange: v => {
|
||||
appSettings.color = teletextColors[v];
|
||||
writeSettings();
|
||||
},
|
||||
format: v => teletextColorNames[v]
|
||||
}
|
||||
});
|
||||
}
|
||||
// Initially show the menu
|
||||
showMenu();
|
||||
});
|