mirror of https://github.com/espruino/BangleApps
add clock_info
parent
3aa0e09f28
commit
684e62eb7f
|
@ -1,25 +1,11 @@
|
||||||
# Clock Name
|
# Meridian Clock
|
||||||
|
|
||||||
More info on making Clock Faces: https://www.espruino.com/Bangle.js+Clock
|
An elegant clock with 2 clock info
|
||||||
|
|
||||||
Describe the Clock...
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Describe how to use it
|
Tap on a widget and swipe left/right/up/down to change the displayed info
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
Name the function
|
|
||||||
|
|
||||||
## Controls
|
|
||||||
|
|
||||||
Name the buttons and what they are used for
|
|
||||||
|
|
||||||
## Requests
|
|
||||||
|
|
||||||
Name who should be contacted for support/update requests
|
|
||||||
|
|
||||||
## Creator
|
## Creator
|
||||||
|
|
||||||
Your name
|
Spioune
|
||||||
|
|
|
@ -1,21 +1,16 @@
|
||||||
require("FontDylex7x13").add(Graphics);
|
|
||||||
|
|
||||||
var weather = require("Storage").readJSON("weather.json", 1) || {};
|
|
||||||
|
|
||||||
function getArcXY(centerX,centerY,radius,angle){
|
function getArcXY(centerX,centerY,radius,angle){
|
||||||
var s,
|
var s,r = [];
|
||||||
r = [];
|
s = 2 * Math.PI * angle / 360;
|
||||||
s = (2 * Math.PI * angle) / 360;
|
|
||||||
r.push(centerX + Math.round(Math.cos(s) * radius));
|
r.push(centerX + Math.round(Math.cos(s) * radius));
|
||||||
r.push(centerY + Math.round(Math.sin(s) * radius));
|
r.push(centerY + Math.round(Math.sin(s) * radius));
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getArc(centerX,centerY,radius,startAngle,endAngle){
|
function getArc(centerX,centerY,radius,startAngle,endAngle){
|
||||||
var xy,
|
var r = [], actAngle = startAngle;
|
||||||
r = [],
|
var stepAngle = (radius + radius) * Math.PI / 60;
|
||||||
actAngle = startAngle;
|
|
||||||
var stepAngle = ((radius + radius) * Math.PI) / 60;
|
|
||||||
stepAngle = 6;
|
stepAngle = 6;
|
||||||
while(actAngle < endAngle){
|
while(actAngle < endAngle){
|
||||||
r = r.concat(getArcXY(centerX,centerY,radius,actAngle));
|
r = r.concat(getArcXY(centerX,centerY,radius,actAngle));
|
||||||
|
@ -25,14 +20,58 @@ function getArc(centerX, centerY, radius, startAngle, endAngle) {
|
||||||
return r.concat(getArcXY(centerX,centerY,radius,endAngle));
|
return r.concat(getArcXY(centerX,centerY,radius,endAngle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let clockInfoItems = require("clock_info").load();
|
||||||
|
|
||||||
|
clockInfoItems[0].items.unshift({
|
||||||
|
name : "BatteryRing",
|
||||||
|
hasRange : true,
|
||||||
|
get : () => {
|
||||||
|
var s = 30;
|
||||||
|
var mid=s/2;
|
||||||
|
var v = E.getBattery();
|
||||||
|
var img;
|
||||||
|
var g = Graphics.createArrayBuffer(s,s,4);
|
||||||
|
|
||||||
|
const outerarc = getArc(mid,mid,14,-90,Math.max(v*3.6, 10)-90);
|
||||||
|
const innerarc = getArc(mid,mid,11,-92,Math.max(v*3.6, 10)-88);
|
||||||
|
|
||||||
|
g.reset();
|
||||||
|
g.setColor('#00FF00').fillPoly([mid, mid].concat(outerarc));
|
||||||
|
g.setColor('#000').fillPoly([mid, mid].concat(innerarc));
|
||||||
|
g.setFont("6x8").setColor('#FFF').setFontAlign(0, 0).drawString(v, mid, mid);
|
||||||
|
img = g.asImage("object");
|
||||||
|
return { v : v, min:0, max:100, img : img };
|
||||||
|
},
|
||||||
|
show : function() { },
|
||||||
|
hide : function() { },
|
||||||
|
});
|
||||||
|
|
||||||
|
function drawInfoClock(itm,info,options){
|
||||||
|
g.reset().clearRect(options.x-1, options.y-1, options.x+options.w+1, options.y+options.h+1);
|
||||||
|
if (options.focus) g.drawRect(options.x-1, options.y-1, options.x+options.w+1, options.y+options.h+1);
|
||||||
|
if (info.img) g.drawImage(info.img, options.x+options.w/2-(info.img.width||options.w)*options.scale/2,options.y, {scale:options.scale});
|
||||||
|
if(info.text) g.setFont("6x8").setFontAlign(0,1).drawString(info.text, options.x+options.w/2,options.y+options.h);
|
||||||
|
}
|
||||||
|
|
||||||
|
const topleft = require("clock_info").addInteractive(clockInfoItems, {
|
||||||
|
x : g.getWidth()*(1/4)-15, y: g.getHeight()*(1/4)-15, w: 30, h:30, scale:1,
|
||||||
|
draw : drawInfoClock
|
||||||
|
});
|
||||||
|
|
||||||
|
const topright = require("clock_info").addInteractive(clockInfoItems, {
|
||||||
|
x : g.getWidth()*(3/4)-15, y: g.getHeight()*(1/4)-15, w: 30, h:30, scale:1,
|
||||||
|
draw : drawInfoClock
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
var timeout;
|
var timeout;
|
||||||
|
|
||||||
function fillLine(x1,y1,x2,y2,thickness){
|
function fillLine(x1,y1,x2,y2,thickness){
|
||||||
const angle = Math.atan2(y2 - y1, x2 - x1);
|
const angle = Math.atan2(y2 - y1, x2 - x1);
|
||||||
const offset_x = (thickness * Math.sin(angle)) / 2;
|
const offset_x = thickness * Math.sin(angle) / 2;
|
||||||
const offset_y = (thickness * Math.cos(angle)) / 2;
|
const offset_y = thickness * Math.cos(angle) / 2;
|
||||||
g.fillPoly(
|
g.fillPoly([
|
||||||
[
|
|
||||||
x1 + offset_x,
|
x1 + offset_x,
|
||||||
y1 - offset_y,
|
y1 - offset_y,
|
||||||
x1 - offset_x,
|
x1 - offset_x,
|
||||||
|
@ -40,136 +79,47 @@ function fillLine(x1, y1, x2, y2, thickness) {
|
||||||
x2 - offset_x,
|
x2 - offset_x,
|
||||||
y2 + offset_y,
|
y2 + offset_y,
|
||||||
x2 + offset_x,
|
x2 + offset_x,
|
||||||
y2 - offset_y,
|
y2 - offset_y
|
||||||
],
|
],true);
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWeatherIcon(txt) {
|
|
||||||
txt = txt.toLowerCase();
|
|
||||||
if (txt == "rainy") {
|
|
||||||
return atob("EhCBAAAAAPwAf4A/8A/8D//H//v////////3//j//AjEBiMDEIAAAA==");
|
|
||||||
} else if (txt == "cloudy") {
|
|
||||||
return atob("FA6BAABgAD/AB/4Af+A//wf/+H//7//+//////////f//j//4P/4");
|
|
||||||
} else if (txt == "sunny") {
|
|
||||||
return atob(
|
|
||||||
"FBSBAABgAAYAAAABgBgY8YA/wAf+AH/gD/8M//PP/zD/8Af+AH/gA/wBjxgYAYAAAABgAAYA"
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw(){
|
function draw(){
|
||||||
g.setTheme({ fg: 0xffff, bg: 0 });
|
g.setTheme({fg:0xFFFF, bg:0});
|
||||||
|
|
||||||
if(timeout){
|
if(timeout){
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
timeout = undefined;
|
timeout = undefined;
|
||||||
}
|
}
|
||||||
g.reset().clear();
|
g.reset().clear();
|
||||||
g.setColor("#FFF");
|
|
||||||
|
|
||||||
const mid=g.getWidth()/2;
|
const mid=g.getWidth()/2;
|
||||||
g.drawImage(
|
g.drawImage(require("heatshrink").decompress(atob("2GwgIGDhwMEgPAAwk4Dg8HCpdwCqnwCo8DwAVK8AVIB4gVFgIVIB4wFKD5IPFG4pLJCosHMYiNJCozNJvAVJh4VJkAKJgT/PAH4A/AH4A/AH4A/AH4A/ADWACqngCicD/AVTh9+Cqc/n4VTv0P4AURgP4gZuSCYQrTVwNACqT/6AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4Ah//ACaMD/4VrQP4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/ADlACSMBAQPACqMDwED8AVS8EPFaUB/E/Nad+vwVTn/4CqcPNiSEDd/4A/AH4A/AH4A/AH4A/AH8gAgcB4AFDgwVJvAVJh4VJuAVJg4VJ8AVJgeACg8BCqoPEApYfECpY3EGpIlGCpEHCpfwCo6jFCoylEA=")));
|
||||||
require("heatshrink").decompress(
|
|
||||||
atob(
|
|
||||||
"2GwgIGDhwMEgPAAwk4Dg8HCpdwCqnwCo8DwAVK8AVIB4gVFgIVIB4wFKD5IPFG4pLJCosHMYiNJCozNJvAVJh4VJkAKJgT/PAH4A/AH4A/AH4A/AH4A/ADWACqngCicD/AVTh9+Cqc/n4VTv0P4AURgP4gZuSCYQrTVwNACqT/6AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4Ah//ACaMD/4VrQP4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/ADlACSMBAQPACqMDwED8AVS8EPFaUB/E/Nad+vwVTn/4CqcPNiSEDd/4A/AH4A/AH4A/AH4A/AH8gAgcB4AFDgwVJvAVJh4VJuAVJg4VJ8AVJgeACg8BCqoPEApYfECpY3EGpIlGCpEHCpfwCo6jFCoylEA="
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
g.setFontAlign(0, 0);
|
|
||||||
g.setFont("Dylex7x13", 1);
|
|
||||||
|
|
||||||
const battery = E.getBattery() || 50;
|
topleft.redraw();
|
||||||
const outerarc = getArc(
|
topright.redraw();
|
||||||
g.getWidth() * (1 / 4) + 1,
|
|
||||||
g.getHeight() * (1 / 4) - 1,
|
|
||||||
14,
|
|
||||||
-90,
|
|
||||||
Math.max(battery * 3.6, 10) - 90
|
|
||||||
);
|
|
||||||
const innerarc = getArc(
|
|
||||||
g.getWidth() * (1 / 4) + 1,
|
|
||||||
g.getHeight() * (1 / 4) - 1,
|
|
||||||
11,
|
|
||||||
-92,
|
|
||||||
Math.max(battery * 3.6, 10) - 88
|
|
||||||
);
|
|
||||||
g.setColor("#00FF00").fillPoly(
|
|
||||||
[g.getWidth() * (1 / 4), g.getHeight() * (1 / 4) - 2].concat(outerarc)
|
|
||||||
);
|
|
||||||
g.setColor("#000").fillPoly(
|
|
||||||
[g.getWidth() * (1 / 4), g.getHeight() * (1 / 4) - 2].concat(innerarc)
|
|
||||||
);
|
|
||||||
g.setColor("#FFF").drawString(
|
|
||||||
battery,
|
|
||||||
g.getWidth() * (1 / 4),
|
|
||||||
g.getHeight() * (1 / 4)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (weather && weather.txt) {
|
|
||||||
const icon = getWeatherIcon(weather.txt);
|
|
||||||
if (icon) {
|
|
||||||
g.drawImage(
|
|
||||||
icon,
|
|
||||||
g.getWidth() * (3 / 4) - 10,
|
|
||||||
g.getHeight() * (1 / 4) - 10
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
g.drawString(
|
|
||||||
weather.txt,
|
|
||||||
g.getWidth() * (3 / 4),
|
|
||||||
g.getHeight() * (1 / 4)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
g.drawString(
|
|
||||||
weather.temp || "-",
|
|
||||||
g.getWidth() * (3 / 4),
|
|
||||||
g.getHeight() * (1 / 4) + 16
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|
||||||
g.setFont("Vector",14);
|
g.setFont("Vector",14);
|
||||||
|
g.setColor('#FFF');
|
||||||
|
g.setFontAlign(0,0);
|
||||||
// Date (ex. MON 8)
|
// Date (ex. MON 8)
|
||||||
g.drawString(
|
g.drawString(require("locale").dow(now, 1).toUpperCase() + " " + now.getDate(), g.getWidth()/2, g.getHeight()*(3/4));
|
||||||
require("locale").dow(now, 1).toUpperCase() + " " + now.getDate(),
|
|
||||||
g.getWidth() / 2,
|
|
||||||
g.getHeight() * (3 / 4)
|
|
||||||
);
|
|
||||||
|
|
||||||
let rhour =
|
let rhour = (now.getHours()*Math.PI/6)+(now.getMinutes()*Math.PI/30/12)-Math.PI/2;
|
||||||
(now.getHours() * Math.PI) / 6 +
|
let rmin = now.getMinutes()*Math.PI/30-Math.PI/2;
|
||||||
(now.getMinutes() * Math.PI) / 30 / 12 -
|
|
||||||
Math.PI / 2;
|
|
||||||
let rmin = (now.getMinutes() * Math.PI) / 30 - Math.PI / 2;
|
|
||||||
|
|
||||||
// Middle circle
|
// Middle circle
|
||||||
g.fillCircle(mid,mid,4);
|
g.fillCircle(mid,mid,4);
|
||||||
|
|
||||||
// Hours hand
|
// Hours hand
|
||||||
fillLine(mid, mid, mid+Math.cos(rhour)*10, mid+Math.sin(rhour)*10,3);
|
fillLine(mid, mid, mid+Math.cos(rhour)*10, mid+Math.sin(rhour)*10,3);
|
||||||
fillLine(
|
fillLine(mid+Math.cos(rhour)*10, mid+Math.sin(rhour)*10, mid+Math.cos(rhour)*50, mid+Math.sin(rhour)*50,7);
|
||||||
mid + Math.cos(rhour) * 10,
|
|
||||||
mid + Math.sin(rhour) * 10,
|
|
||||||
mid + Math.cos(rhour) * 50,
|
|
||||||
mid + Math.sin(rhour) * 50,
|
|
||||||
7
|
|
||||||
);
|
|
||||||
|
|
||||||
// Minutes hand
|
// Minutes hand
|
||||||
fillLine(mid, mid, mid+Math.cos(rmin)*10, mid+Math.sin(rmin)*10,3);
|
fillLine(mid, mid, mid+Math.cos(rmin)*10, mid+Math.sin(rmin)*10,3);
|
||||||
fillLine(
|
fillLine(mid+Math.cos(rmin)*10, mid+Math.sin(rmin)*10, mid+Math.cos(rmin)*76, mid+Math.sin(rmin)*76,7);
|
||||||
mid + Math.cos(rmin) * 10,
|
|
||||||
mid + Math.sin(rmin) * 10,
|
|
||||||
mid + Math.cos(rmin) * 76,
|
|
||||||
mid + Math.sin(rmin) * 76,
|
|
||||||
7
|
|
||||||
);
|
|
||||||
|
|
||||||
if(now.getMinutes()==0){
|
if(now.getMinutes()==0){
|
||||||
Bangle.buzz();
|
Bangle.buzz();
|
||||||
|
@ -182,7 +132,4 @@ function draw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
draw();
|
draw();
|
||||||
|
|
||||||
Bangle.setUI("clock");
|
Bangle.setUI("clock");
|
||||||
Bangle.loadWidgets();
|
|
||||||
Bangle.drawWidgets();
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.5 KiB |
|
@ -3,9 +3,9 @@
|
||||||
"name": "Meridian Clock",
|
"name": "Meridian Clock",
|
||||||
"shortName": "Meridian",
|
"shortName": "Meridian",
|
||||||
"version": "0.01",
|
"version": "0.01",
|
||||||
"description": "An Elegant Clock",
|
"description": "An elegant clock",
|
||||||
"screenshots": [{ "url": "screenshot.png" }],
|
"screenshots": [{ "url": "screenshot.png" }],
|
||||||
"icon": "app.png",
|
"icon": "screenshot.png",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"supports": ["BANGLEJS2"],
|
"supports": ["BANGLEJS2"],
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.3 KiB |
Loading…
Reference in New Issue