diff --git a/apps/widanibat/app-icon.js b/apps/widanibat/app-icon.js new file mode 100644 index 000000000..75cc259f9 --- /dev/null +++ b/apps/widanibat/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("oFAwMB/4A/AH38RIkDA7M/EofDA7M8EgQHQ4E/A/4HdN5Sffb7wA/AH4")); diff --git a/apps/widanibat/battery.png b/apps/widanibat/battery.png new file mode 100644 index 000000000..e212ec5df Binary files /dev/null and b/apps/widanibat/battery.png differ diff --git a/apps/widanibat/metadata.json b/apps/widanibat/metadata.json new file mode 100644 index 000000000..4a14d93fc --- /dev/null +++ b/apps/widanibat/metadata.json @@ -0,0 +1,13 @@ +{ "id": "widanibat", + "name": "Battery level widget with charging animation", + "shortName":"Battery Widget", + "icon": "battery.png", + "version":"0.01", + "description": "Battery level widget with pulsing charging animation.", + "requires": ["BANGLEJS2"], + "tags": "", + "storage": [ + {"name":"widanibat.widget.js","url":"widget.js"}, + {"name":"widanibat.img","url":"app-icon.js","evaluate":true} + ] +} diff --git a/apps/widanibat/widget.js b/apps/widanibat/widget.js new file mode 100644 index 000000000..33334465d --- /dev/null +++ b/apps/widanibat/widget.js @@ -0,0 +1,72 @@ +(()=>{ + const w = 26; + const h = 13; + var s, t, scale, batInt; + + const animateUpdateInterval = 300; + const staticUpdateInterval = 1000 * 60 * 10; // 10 minutes + + function draw(){ + + if (s==undefined||!Bangle.isCharging()) s = w; + if (t==undefined||!Bangle.isCharging()) t = h; + if (scale==undefined||!Bangle.isCharging()) scale = 1; + + const x = this.x; + const y = this.y + 4; + const midX = ((2 * x) + w)/2; + const midY = ((2 * y) + h)/2; + + g.setColor(g.theme.fg); + g.reset(); + + drawBattery = ()=>{ + var halfS = s/2; + var halfT = t/2; + + g.clearRect(x, y, x+w, y+h); + g.fillRect(midX-halfS, midY-halfT, midX+halfS-3, midY+halfT); // outer + g.clearRect(midX-halfS+2, midY-halfT+2, midX+halfS-3-2, midY+halfT-2); // centre + g.fillRect(midX+halfS-3, midY-2, midX+halfS, midY+2); // contact + g.fillRect(midX-halfS+3, midY-halfT+3,((s-9)/100*E.getBattery())+midX-halfS+3, midY+halfT-3); // the level + }; + + animateBattery = ()=>{ + scale = 1; + var dir = 0; + if (batInt) clearInterval(batInt); + + batInt = setInterval(()=>{ + s = w * scale; + t = h * scale; + drawBattery(); + scale = dir==0?scale-0.1:scale+0.1; + if (scale <= 0.7) dir=1; + if (scale >= 1) dir=0; + }, animateUpdateInterval); + }; + + staticBattery = ()=>{ + s = w; + t = h; + if (batInt) clearInterval(batInt); + batInt = setInterval(drawBattery, staticUpdateInterval); + drawBattery(); + }; + + if (Bangle.isCharging()) { + animateBattery(); + } else { + staticBattery(); + } + } + + WIDGETS["widanibat"]={ + area:"tr", + width:w, + draw:draw + }; + + Bangle.on('charging', (charging)=>{WIDGETS.widanibat.draw();}); + +})(); \ No newline at end of file