Add Bold clock app, Pedometer and Digital clock widgets

Add Bold clock app
Add Pedometer widget
Add Digital clock widget
pull/75/head
Shunya Sato 2020-01-03 16:18:44 +09:00
parent d306209da7
commit b27ada31c6
11 changed files with 291 additions and 0 deletions

View File

@ -624,6 +624,44 @@
{"name":"*blobclk","url":"clock-blob-icon.js","evaluate":true}
]
},
{ "id": "boldclk",
"name": "Bold Clock",
"icon": "bold_clock.png",
"version":"0.01",
"description": "Simple, readable and practical clock",
"tags": "clock",
"type":"clock",
"allow_emulator":true,
"storage": [
{"name":"+boldclk","url":"bold_clock.json"},
{"name":"-boldclk","url":"bold_clock.js"},
{"name":"*boldclk","url":"bold_clock-icon.js","evaluate":true}
]
},
{ "id": "wdclk",
"name": "Digital clock widget",
"icon": "digital_clock_widget.png",
"version":"0.01",
"description": "A simple digital clock widget",
"tags": "widget,clock",
"type":"widget",
"storage": [
{"name":"+wdclk","url":"digital_clock_widget.json"},
{"name":"=wdclk","url":"digital_clock_widget.js"}
]
},
{ "id": "wpedom",
"name": "Pedometer widget",
"icon": "pedometer_widget.png",
"version":"0.01",
"description": "Daily pedometer widget",
"tags": "widget",
"type":"widget",
"storage": [
{"name":"+wpedom","url":"pedometer_widget.json"},
{"name":"=wpedom","url":"pedometer_widget.js"}
]
},
{ "id": "berlinc",
"name": "Berlin Clock",
"icon": "berlin-clock.png",

View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEwwkE/4AHmXw+EPh8jBxAAHgch+EwgcPiUwCpszh8RmPzF4M/icR+EzCxXxFAIOCC4IgCkMwj4WI+cigIGDC4YABiEyn4XIgcQBYYXE+cBmAXH+UDkcwCQYXEAgMymEvC4sviIaBKhHyCgMR+QKFLggALiCjFmIXPiarEkBOGABPygS7DkaXIW5JuCmEBC6MATIU/iB3RgXzRoXzUwIAOCAKRCVgwANRQPwiYXTmMP+YXVn8yRqCREkchVQQAR+MSCqYADgBHVgDBCACc/gAABegQAN+AUCC65HYO6ynXa68yI6sj+cTC6cxn/wC6q7B+QXTl4CBgPzgIVPiEviDBCiECC58ggMzegUBSKMQgaqCkYXQ+czL4Q1BAgYAM+RZEmcxC58TLwQACR6KsGiI5BY4IAG+JVBiLSG+UDkcwC4fwAgkDmUwOA/zgcQSYYXEcoMwT5HzkRiEC4hcBkS3J+MPiThDC4UzkPwj7JLh8RmPzC4M/icR+DlOgYoBmEDGwMwWZ//mXwF4MPkYOIA"))

146
apps/boldclk/bold_clock.js Normal file
View File

@ -0,0 +1,146 @@
(() => {
// https://www.espruino.com/Image+Converter
var hour_hand = {
width : 61, height : 8, bpp : 1,
transparent : 0,
buffer : E.toArrayBuffer(atob("/////////////////////////////////////////////////////////////////////////////////w=="))
};
var minute_hand = {
width : 110, height : 4, bpp : 1,
transparent : 0,
buffer : E.toArrayBuffer(atob("/////////////////////////////////////////////////////////////////////////w=="))
};
//g.fillRect(0,24,239,239); // Apps area
let intervalRef = null;
const p180 = Math.PI/180;
const clock_center = {x:Math.floor((240-1)/2), y:24+Math.floor((239-24)/2)};
// ={ x: 119, y: 131 }
const radius = Math.floor((239-24+1)/2); // =108
let tick0 = Graphics.createArrayBuffer(30,8,1);
tick0.fillRect(0,0,tick0.getWidth()-1, tick0.getHeight()-1);
let tick5 = Graphics.createArrayBuffer(20,6,1);
tick5.fillRect(0,0,tick5.getWidth()-1, tick5.getHeight()-1);
let tick1 = Graphics.createArrayBuffer(8,4,1);
tick1.fillRect(0,0,tick1.getWidth()-1, tick1.getHeight()-1);
function big_wheel_x(angle){
return clock_center.x + radius * Math.cos(angle*p180);
}
function big_wheel_y(angle){
return clock_center.y + radius * Math.sin(angle*p180);
}
function rotate_around_x(center_x, angle, tick){
return center_x + Math.cos(angle*p180) * tick.getWidth()/2;
}
function rotate_around_y(center_y, angle, tick){
return center_y + Math.sin(angle*p180) * tick.getWidth()/2;
}
function hour_pos_x(angle){
return clock_center.x + Math.cos(angle*p180) * hour_hand.width/2;
}
function hour_pos_y(angle){
return clock_center.y + Math.sin(angle*p180) * hour_hand.width/2;
}
function minute_pos_x(angle){
return clock_center.x + Math.cos(angle*p180) * minute_hand.width/2;
}
function minute_pos_y(angle){
return clock_center.y + Math.sin(angle*p180) * minute_hand.width/2;
}
function minute_angle(date){
//let minutes = date.getMinutes() + date.getSeconds()/60;
let minutes = date.getMinutes();
return 6*minutes - 90;
}
function hour_angle(date){
let hours= date.getHours() + date.getMinutes()/60;
return 30*hours - 90;
}
function draw_clock(){
//console.log("draw_clock");
let date = new Date();
//g.clear();
g.setBgColor(0,0,0);
g.setColor(0,0,0);
g.fillRect(0,24,239,239); // clear app area
g.setColor(1,1,1);
// draw cross lines for testing
// g.setColor(1,0,0);
// g.drawLine(clock_center.x - radius, clock_center.y, clock_center.x + radius, clock_center.y);
// g.drawLine(clock_center.x, clock_center.y - radius, clock_center.x, clock_center.y + radius);
g.setColor(1,1,1);
let ticks = [0, 90, 180, 270];
ticks.forEach((item)=>{
let agl = item+180;
g.drawImage(tick0.asImage(), rotate_around_x(big_wheel_x(item), agl, tick0), rotate_around_y(big_wheel_y(item), agl, tick0), {rotate:agl*p180});
});
ticks = [30, 60, 120, 150, 210, 240, 300, 330];
ticks.forEach((item)=>{
let agl = item+180;
g.drawImage(tick5.asImage(), rotate_around_x(big_wheel_x(item), agl, tick5), rotate_around_y(big_wheel_y(item), agl, tick5), {rotate:agl*p180});
});
let hour_agl = hour_angle(date);
let minute_agl = minute_angle(date);
g.drawImage(hour_hand, hour_pos_x(hour_agl), hour_pos_y(hour_agl), {rotate:hour_agl*p180}); //
g.drawImage(minute_hand, minute_pos_x(minute_agl), minute_pos_y(minute_agl), {rotate:minute_agl*p180}); //
g.setColor(1,1,1);
g.fillCircle(clock_center.x, clock_center.y, 6);
g.setColor(0,0,0);
g.fillCircle(clock_center.x, clock_center.y, 3);
// draw minute ticks. Takes long time to draw!
g.setColor(1,1,1);
for (var i=0; i<60; i++){
let agl = i*6+180;
g.drawImage(tick1.asImage(), rotate_around_x(big_wheel_x(i*6), agl, tick1), rotate_around_y(big_wheel_y(i*6), agl, tick1), {rotate:agl*p180});
}
g.flip();
//console.log(date);
}
function clearTimers(){
//console.log("clearTimers");
if(intervalRef) {
clearInterval(intervalRef);
intervalRef = null;
//console.log("interval is cleared");
}
}
function startTimers(){
//console.log("startTimers");
if(intervalRef) clearTimers();
intervalRef = setInterval(draw_clock, 60*1000);
//console.log("interval is set");
draw_clock();
}
Bangle.on('lcdPower', (on) => {
if (on) {
//console.log("lcdPower: on");
try { if (drawWidgets) { drawWidgets();} } catch(err) {}
startTimers();
} else {
//console.log("lcdPower: off");
clearTimers();
}
});
Bangle.on('faceUp',function(up){
//console.log("faceUp: " + up + " LCD: " + Bangle.isLCDOn());
if (up && !Bangle.isLCDOn()) {
//console.log("faceUp and LCD off");
clearTimers();
Bangle.setLCDPower(true);
}
});
g.clear();
//Bangle.setLCDPower(true);
startTimers();
})();

View File

@ -0,0 +1,7 @@
{
"name":"Bold Clock",
"type":"clock",
"icon":"*boldclk",
"src":"-boldclk",
"sortorder":-10
}

BIN
apps/boldclk/bold_clock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,39 @@
(() => {
let intervalRef = null;
var width = 5 * 6*2
var xpos = WIDGETPOS.tr - width;
WIDGETPOS.tr -= (width + 2);
function draw() {
// Widget (0,0,239,23)
let date = new Date();
var dateArray = date.toString().split(" ");
g.setColor(1,1,1);
g.setFont("6x8", 2);
g.setFontAlign(-1, 0);
g.drawString(dateArray[4].substr(0, 5), xpos, 11, true); // 5 * 6*2 = 60
g.flip();
}
function clearTimers(){
if(intervalRef) {
clearInterval(intervalRef);
intervalRef = null;
}
}
function startTimers(){
if(intervalRef) clearTimers();
intervalRef = setInterval(draw, 60*1000);
draw();
}
Bangle.on('lcdPower', (on) => {
if (on) {
// startTimers(); // comment out as it is called by app anyway
} else {
clearTimers();
}
});
// add your widget
WIDGETS["wdclk"]={draw:startTimers};
})()

View File

@ -0,0 +1,5 @@
{
"name":"Digital Clock Widget", "type":"widget",
"src":"=wdclk"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

View File

@ -0,0 +1,50 @@
(() => {
// add the width
// WIDGETPOS.tr is originally 208 without any widgets
var xpos = WIDGETPOS.tr; // draw string with right alignment
var width = 48;
WIDGETPOS.tr -= (width + 2);
let lastUpdate = new Date();
let stp_today = 0;
function erase() {
g.clearRect(xpos-width, 0, xpos, 23);
}
// draw your widget at xpos
function draw() {
// Widget (0,0,239,23)
if (stp_today > 99999){
stp_today = stp_today % 100000; // cap to five digits + comma = 6 characters
erase();
}
let stps = stp_today.toString();
if (stps.length > 3){
stps = stps.slice(0,-3) + "," + stps.slice(-3);
}
g.setColor(1,1,1);
g.setFont("4x6", 2);
g.setFontAlign(1, 0); // align to x: right, y: center
g.drawString(stps, xpos, 11, true); // 6 * 4*2 = 48
g.flip();
}
Bangle.on('step', (up) => {
let date = new Date();
if (lastUpdate.getDate() == date.getDate()){
stp_today += 1;
} else {
stp_today = 1;
erase();
}
lastUpdate = date;
//console.log("up: " + up + " stp: " + stp_today + " " + date.toString());
draw();
});
// add your widget
WIDGETS["wpedom"]={draw:draw};
})()

View File

@ -0,0 +1,5 @@
{
"name":"Pedometer Widget", "type":"widget",
"src":"=wpedom"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB