New futures

- Hole can be circle or square
- Hole can be with number or without
- Draw circle takes whole object in as a variable
pull/2685/head
pinq- 2023-04-01 07:34:32 +03:00
parent a517c5ef02
commit 28927f7849
2 changed files with 351 additions and 12 deletions

View File

@ -10,9 +10,9 @@
const watch = {
x:0, y:0, w:0, h:0,
color:"#000000",
dateRing : { size:109, weight:20, color:"#00FF00", cursor:14, numbers: true },
hourRing : { size:85, weight:20, color:"#00FFFF", cursor:14, numbers: true },
minuteRing : { size:61, weight:20, color:"#FFFF00", cursor:14, numbers: true },
dateRing : { size:109, weight:20, color:"#00FF00", numbers: true, range: 30 , bubble:false},
hourRing : { size:82, weight:20, color:"#00FFFF", numbers: true, range: 12, bubble:true},
minuteRing : { size:55, weight:18, color:"#FFFF00", numbers: false, range: 60, bubble:false},
screen : { width:g.getWidth(), height:g.getHeight(), centerX: g.getWidth() *0.5, centerY: g.getHeight() * 0.5, cursor: 14, font:"6x8:2" },
};
@ -72,6 +72,52 @@ function drawTimeCircle(color, size, weight, range, value ) {
}
function drawCircle(ringValues, offset, value ) {
// variables for vertex transformations and positioning time
let tver, tobj, tran;
let ttime = (value / ringValues.range) * (Math.PI * 2);
// draw circle
g.setColor(ringValues.color).fillCircle(watch.screen.centerX, watch.screen.centerY, ringValues.size + offset);
g.setColor("#000000").fillCircle(watch.screen.centerX, watch.screen.centerY, ringValues.size - ringValues.weight + offset);
// draw line
//let location_x = watch.screen.centerX +(ringValues.size + offset) * Math.cos((-(value / ringValues.range)+0.25)*2*Math.PI);
//let location_y = watch.screen.centerY -(ringValues.size + offset) * Math.sin((-(value / ringValues.range)+0.25)*2*Math.PI);
tobj = { x:watch.screen.centerX, y:watch.screen.centerY, scale:1, rotate:ttime };
if(ringValues.bubble){
tver = [-1, 0, 1, 0, 1, -ringValues.size-offset, -1, -(ringValues.size + offset -21)];
tran = g.transformVertices(tver, tobj);
if(ringValues.numbers){
g.setColor("#000000").fillCircle((tran[4]+tran[6]) / 2 , (tran[5]+tran[7]) / 2, 17 + offset/10);
}else{
g.setColor("#000000").fillCircle((tran[4]+tran[6]) / 2 , (tran[5]+tran[7]) / 2, 10 + offset/10);
}
}else{
if(ringValues.numbers){
tver = [-watch.screen.cursor, 0, watch.screen.cursor, 0, watch.screen.cursor, -ringValues.size*1.01 - offset, -watch.screen.cursor, -ringValues.size*1.05 - offset];
}else{
tver = [-watch.screen.cursor * 0.4, 0, watch.screen.cursor * 0.4, 0, watch.screen.cursor *0.4, -ringValues.size*1.01 - offset, -watch.screen.cursor*0.4, -ringValues.size*1.05 - offset];
}
tran = g.transformVertices(tver, tobj);
g.fillPoly(tran);
}
// Draw numbers
if(ringValues.numbers){
// size - 21 is the right offset to get the numbers aligned in the circle.
tver = [-1, 0, 1, 0, 1, -ringValues.size-offset, -1, -(ringValues.size + offset -21)];
tran = g.transformVertices(tver, tobj);
//g.setColor(1,1,1);
g.setFontAlign(0,0).setFont(watch.screen.font, 2).setColor(1,1,1);
g.drawString(value, (tran[4]+tran[6]) / 2 , (tran[5]+tran[7]) / 2 );
}
}
// Draws text for month and year in date circle
function drawMonthCircleText( text, circleSize, range, value){
@ -87,7 +133,7 @@ function drawMonthCircleText( text, circleSize, range, value){
var gr = Graphics.createArrayBuffer(24,16,1,{msb:true});
var grimg = gr.asImage();
grimg.transparent = 1;
monthCircleTextBuffer.setColor(0,0,0);
monthCircleTextBuffer.setColor(1,1,1);
for(z=0; z < text.length; z++){
tobj = { x:watch.screen.centerX, y:watch.screen.centerY, scale:1, rotate: ((z + 1) / range) * (Math.PI * 2) };
@ -142,14 +188,17 @@ function shrinkCircles(toggle){
// Draw the date ring (unless it's the last run of an expansion).
if(counter < 11 || toggle){
drawTimeCircle(watch.dateRing.color, watch.dateRing.size + delta, watch.dateRing.weight, getDays(date.getFullYear(), date.getMonth()+1), date.getDate() );
//drawTimeCircle(watch.dateRing.color, watch.dateRing.size + delta, watch.dateRing.weight, getDays(date.getFullYear(), date.getMonth()+1), date.getDate() );
drawCircle(watch.dateRing, delta, date.getDate());
// Draw month and year in date ring
drawMonthCircleText( month[date.getMonth()]+" "+date.getFullYear(), watch.dateRing.size - 24, getDays(date.getFullYear(), date.getMonth()+1), date.getDate()) ;
}
drawTimeCircle(watch.hourRing.color, watch.hourRing.size + delta, watch.hourRing.weight, 12, date.getHours() );
drawTimeCircle(watch.minuteRing.color, watch.minuteRing.size + delta, watch.minuteRing.weight, 60, date.getMinutes() );
//drawTimeCircle(watch.hourRing.color, watch.hourRing.size + delta, watch.hourRing.weight, 12, date.getHours() );
drawCircle(watch.hourRing, delta, date.getHours());
drawCircle(watch.minuteRing, delta, date.getMinutes());
//drawTimeCircle(watch.minuteRing.color, watch.minuteRing.size + delta, watch.minuteRing.weight, 60, date.getMinutes() );
counter += 1;
setTimeout(shrinkCircles, 10, toggle);
@ -172,13 +221,19 @@ function draw() {
// If unlocked, draw date ring and text and make hour and minute rings smaller
if(!Bangle.isLocked()){
unLockedOffset = 24;
drawTimeCircle(watch.dateRing.color, watch.dateRing.size - unLockedOffset, watch.dateRing.weight, getDays(date.getFullYear(), date.getMonth()+1), date.getDate() );
console.log("jee");
var days_month = getDays(date.getFullYear(), date.getMonth()+1);
// if the day has changed
if(watch.dateRing.range != days_month) watch.dateRing.range = days_month;
//drawTimeCircle(watch.dateRing.color, watch.dateRing.size - unLockedOffset, watch.dateRing.weight, getDays(date.getFullYear(), date.getMonth()+1), date.getDate() );
drawCircle(watch.dateRing, -unLockedOffset, days_month);
drawMonthCircleText( month[date.getMonth()]+" "+date.getFullYear(), watch.dateRing.size - unLockedOffset, getDays(date.getFullYear(), date.getMonth()+1), date.getDate()) ;
}
drawTimeCircle(watch.hourRing.color, watch.hourRing.size - unLockedOffset, watch.hourRing.weight, 12, date.getHours() );
drawTimeCircle(watch.minuteRing.color, watch.minuteRing.size -unLockedOffset , watch.minuteRing.weight, 60, date.getMinutes() );
//drawTimeCircle(watch.hourRing.color, watch.hourRing.size - unLockedOffset, watch.hourRing.weight, 12, date.getHours() );
//drawTimeCircle(watch.minuteRing.color, watch.minuteRing.size -unLockedOffset , watch.minuteRing.weight, 60, date.getMinutes() );
drawCircle(watch.hourRing, -unLockedOffset, date.getHours());
drawCircle(watch.minuteRing, -unLockedOffset, date.getMinutes());
queueDraw();
}

284
apps/rings/battery.js Normal file
View File

@ -0,0 +1,284 @@
// Rings watch face
// for Bangle.js 2
// by Amos Blanton
// Remixed from / inspired by Rinkulainen watch face by Jukio Kallio
// To Do:
// Make Month / year text buffer 1/2 size
// Optimize text positioning transforms
const watch = {
x:0, y:0, w:0, h:0,
color:"#000000",
dateRing : { size:109, weight:20, color:"#00FF00", numbers: true, range: 30 , bubble:true},
hourRing : { size:82, weight:20, color:"#00FFFF", numbers: true, range: 12, bubble:true},
minuteRing : { size:55, weight:18, color:"#FFFF00", numbers: true, range: 60, bubble:false},
batteryRing: { size :30, weight:10, color:"#ff3300", numbers: false, range: 100, bubble:false},
screen : { width:g.getWidth(), height:g.getHeight(), centerX: g.getWidth() *0.5, centerY: g.getHeight() * 0.5, cursor: 14, font:"6x8:2" },
};
const month= ["JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE","JULY",
"AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"];
var wait = 60000; // wait time, normally a minute
// timeout used to update every minute
var drawTimeout;
// Global for use in shrink / unshrink animations
var counter = 1;
// Buffer for month circle text, 1/2 screen size (will be scaled up)
var monthCircleTextBuffer= Graphics.createArrayBuffer(watch.screen.width,watch.screen.height,1,{msb:true});
var monthCircleTextImg = monthCircleTextBuffer.asImage();
monthCircleTextImg.transparent = 1;
var lastMonthCircleImageText = "";
// Calculate number of days in this month / year for date ring
const getDays = (year, thisMonth) => {
return new Date(year, thisMonth, 0).getDate(); // getMonth() Jan = 0.
};
// Schedule a draw for the next minute
function queueDraw() {
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function() {
drawTimeout = undefined;
draw();
}, wait - (Date.now() % wait));
}
// Draws a time circle (date, hours, minutes)
function drawTimeCircle(color, size, weight, range, value ) {
// variables for vertex transformations and positioning time
var tver, tobj, tran;
var ttime = (value / range) * (Math.PI * 2);
// draw circle and line
g.setColor(color).fillCircle(watch.screen.centerX, watch.screen.centerY, size);
g.setColor("#000000").fillCircle(watch.screen.centerX, watch.screen.centerY, size - weight);
tver = [-watch.screen.cursor, 0, watch.screen.cursor, 0, watch.screen.cursor, -size*1.01, -watch.screen.cursor, -size*1.05];
tobj = { x:watch.screen.centerX, y:watch.screen.centerY, scale:1, rotate:ttime };
tran = g.transformVertices(tver, tobj);
g.fillPoly(tran);
// Draw numbers
g.setFontAlign(0,0).setFont(watch.screen.font, 2).setColor(1,1,1);
// size - 21 is the right offset to get the numbers aligned in the circle.
tver = [-1, 0, 1, 0, 1, -size, -1, -(size -21)];
tran = g.transformVertices(tver, tobj);
g.setColor(1,1,1);
g.drawString(value, (tran[4]+tran[6]) / 2 , (tran[5]+tran[7]) / 2 );
}
function drawArc(percent, color, ArchR) {
let offset = 0;
let end = 360;
let radius = ArchR + 2;
if (percent <= 0) return; // no gauge needed
if (percent > 1) percent = 1;
let startRotation = -offset;
let endRotation = startRotation - (end * percent);
g.setColor(color);
// convert to radians
startRotation *= Math.PI / 180;
let amt = Math.PI / 10;
endRotation = (endRotation * Math.PI / 180) - amt;
// all we need to draw is an arc, because we'll fill the center
let poly = [watch.screen.centerX, watch.screen.centerY];
for (let r = startRotation; r > endRotation; r -= amt)
poly.push(
watch.screen.centerX - radius * Math.sin(r),
watch.screen.centerY - radius * Math.cos(r)
);
g.fillPoly(poly);
g.setColor("#000000").fillCircle(watch.screen.centerX, watch.screen.centerY, ArchR - 10);
g.setColor(color).fillCircle(watch.screen.centerX - (radius -5) * Math.sin(endRotation + amt), watch.screen.centerY - (radius -5) * Math.cos(endRotation + amt), 4);
}
function drawCircle(ringValues, offset, value ) {
// variables for vertex transformations and positioning time
let tver, tobj, tran;
let ttime = (value / ringValues.range) * (Math.PI * 2);
// draw circle
g.setColor(ringValues.color).fillCircle(watch.screen.centerX, watch.screen.centerY, ringValues.size + offset);
g.setColor("#000000").fillCircle(watch.screen.centerX, watch.screen.centerY, ringValues.size - ringValues.weight + offset);
// draw line
//let location_x = watch.screen.centerX +(ringValues.size + offset) * Math.cos((-(value / ringValues.range)+0.25)*2*Math.PI);
//let location_y = watch.screen.centerY -(ringValues.size + offset) * Math.sin((-(value / ringValues.range)+0.25)*2*Math.PI);
tobj = { x:watch.screen.centerX, y:watch.screen.centerY, scale:1, rotate:ttime };
if(ringValues.bubble){
tver = [-1, 0, 1, 0, 1, -ringValues.size-offset, -1, -(ringValues.size + offset -21)];
tran = g.transformVertices(tver, tobj);
g.setColor("#000000").fillCircle((tran[4]+tran[6]) / 2 , (tran[5]+tran[7]) / 2, 17 + offset/10);
}else{
tver = [-watch.screen.cursor, 0, watch.screen.cursor, 0, watch.screen.cursor, -ringValues.size*1.01 - offset, -watch.screen.cursor, -ringValues.size*1.05 - offset];
tran = g.transformVertices(tver, tobj);
g.fillPoly(tran);
}
// Draw numbers
if(ringValues.numbers){
// size - 21 is the right offset to get the numbers aligned in the circle.
tver = [-1, 0, 1, 0, 1, -ringValues.size-offset, -1, -(ringValues.size + offset -21)];
tran = g.transformVertices(tver, tobj);
//g.setColor(1,1,1);
g.setFontAlign(0,0).setFont(watch.screen.font, 2).setColor(1,1,1);
g.drawString(value, (tran[4]+tran[6]) / 2 , (tran[5]+tran[7]) / 2 );
}
}
// Draws text for month and year in date circle
function drawMonthCircleText( text, circleSize, range, value, delta){
// If the text isn't the same as last time, write it into a graphic object.
if(text != lastMonthCircleImageText){
monthCircleTextBuffer.clear();
monthCircleTextBuffer.fillRect(0,0,watch.screen.width,watch.screen.height);
var tver, tobj, tran;
// From here: https://forum.espruino.com/comments/16781795/
var gr = Graphics.createArrayBuffer(24,16,1,{msb:true});
var grimg = gr.asImage();
grimg.transparent = 1;
monthCircleTextBuffer.setColor(1,1,1);
for(z=0; z < text.length; z++){
tobj = { x:watch.screen.centerX, y:watch.screen.centerY, scale:1, rotate: ((z + 1) / range) * (Math.PI * 2) };
tver = [-1, 0, 1, 0, 1, -circleSize, -1, -(circleSize -21)];
tran = monthCircleTextBuffer.transformVertices(tver, tobj);
gr.clear().setColor(1,1,1).fillRect(0,0,24,16).setColor(0,0,0).setFont(watch.screen.font).setFontAlign(0,0).drawString(text[z],12,8);
monthCircleTextBuffer.drawImage(grimg,
(tran[4]+tran[6]) / 2,
(tran[5]+tran[7]) / 2,
{rotate:((z+1) / range) * (Math.PI * 2) });
}
lastMonthCircleImageText = text;
}
// Determine correct rotation for text in ring ( opposite the date position )
var offset = value + (range / 2) - (text.length / 2);
if(offset > range)
offset = offset - range;
var rotation = (offset / range) * (Math.PI * 2);
// Draw the image of text to the screen at that rotation
g.drawImage(monthCircleTextImg, watch.screen.centerX, watch.screen.centerY, {scale:1, rotate:rotation });
}
// Animate by shrinking or expanding circles
function shrinkCircles(toggle){
// If there's a queued draw operation,removeit so animation isn't interrupted.
if (drawTimeout) clearTimeout(drawTimeout);
var date = new Date();
var delta = 1;
if(counter > 12)
{
counter = 1;
// We're finished, so queue next draw.
queueDraw();
return;
}
if(toggle) // We are shrinking
delta = counter * 2 * -1;
else // We are expanding
delta = counter *2 - 24;
// Clear space on screen.
g.setColor(watch.color);
g.fillRect(0, 0, watch.screen.width, watch.screen.height);
// Draw the date ring (unless it's the last run of an expansion).
if(counter < 11 || toggle){
drawTimeCircle(watch.dateRing.color, watch.dateRing.size + delta, watch.dateRing.weight, getDays(date.getFullYear(), date.getMonth()+1), date.getDate() );
//drawCircle(watch.dateRing, delta, date.getDate());
// Draw month and year in date ring
drawMonthCircleText( month[date.getMonth()]+" "+date.getFullYear(), watch.dateRing.size - 24, getDays(date.getFullYear(), date.getMonth()+1), date.getDate()) ;
}
drawCircle(watch.hourRing, delta, date.getHours());
drawCircle(watch.minuteRing, delta, date.getMinutes());
counter += 1;
setTimeout(shrinkCircles, 10, toggle);
}
// main draw function
function draw() {
// make date object
var date = new Date();
var unLockedOffset = 0;
// Reset the state of the graphics library
g.reset();
// Clear the area where we want to draw the time
g.setColor(watch.color);
g.fillRect(0, 0, watch.screen.width, watch.screen.height);
// If unlocked, draw date ring and text and make hour and minute rings smaller
if(!Bangle.isLocked()){
unLockedOffset = 24;
var days_month = getDays(date.getFullYear(), date.getMonth()+1);
// if the day has changed
if(watch.dateRing.range != days_month) watch.dateRing.range = days_month;
//drawTimeCircle(watch.dateRing.color, watch.dateRing.size - unLockedOffset, watch.dateRing.weight, getDays(date.getFullYear(), date.getMonth()+1), date.getDate() );
drawCircle(watch.dateRing, -unLockedOffset, days_month);
drawMonthCircleText( month[date.getMonth()]+" "+date.getFullYear(), watch.dateRing.size - unLockedOffset, getDays(date.getFullYear(), date.getMonth()+1), date.getDate()) ;
}
//drawTimeCircle(watch.hourRing.color, watch.hourRing.size - unLockedOffset, watch.hourRing.weight, 12, date.getHours() );
//drawTimeCircle(watch.minuteRing.color, watch.minuteRing.size -unLockedOffset , watch.minuteRing.weight, 60, date.getMinutes() );
drawCircle(watch.hourRing, -unLockedOffset, date.getHours());
drawCircle(watch.minuteRing, -unLockedOffset, date.getMinutes());
drawArc(1, watch.batteryRing.color, watch.batteryRing.size);
//drawCircle(watch.batteryRing, -unLockedOffset, E.getBattery());
queueDraw();
}
// Trigger shrink / expand animation on unlock / lock events
Bangle.on('lock', on=>{
if (on) { // locked, expand circles
counter = 1;
shrinkCircles(false);
} else
{ // unlocked, shrink circles and show date ring
counter = 1;
shrinkCircles(true);
}
});
// End function definitions / start of initial execution.
// Clear the screen once, at startup
g.clear();
// draw immediately at first
draw();
// console.log("Whatevs");
// Show launcher when middle button pressed
Bangle.setUI("clock");