Bangle.js 2 welcome

pull/865/head
Gordon Williams 2021-10-26 20:58:27 +01:00
parent 0161b1a8d2
commit 762b1e6be3
7 changed files with 321 additions and 1 deletions

View File

@ -183,7 +183,8 @@
}, },
{ {
"id": "welcome", "id": "welcome",
"name": "Welcome", "name": "Welcome (Bangle.js 1)",
"shortName": "Welcome",
"version": "0.12", "version": "0.12",
"description": "Appears at first boot and explains how to use Bangle.js", "description": "Appears at first boot and explains how to use Bangle.js",
"icon": "app.png", "icon": "app.png",
@ -216,6 +217,24 @@
], ],
"data": [{"name":"mywelcome.json"}] "data": [{"name":"mywelcome.json"}]
}, },
{
"id": "welcome2",
"name": "Welcome (Bangle.js 2)",
"shortName": "Welcome",
"version": "0.13",
"description": "Appears at first boot and explains how to use Bangle.js 2",
"icon": "app.png",
"tags": "start,welcome",
"supports": ["BANGLEJS2"],
"allow_emulator": true,
"storage": [
{"name":"welcome2.boot.js","url":"boot.js"},
{"name":"welcome2.app.js","url":"app.js"},
{"name":"welcome2.settings.js","url":"settings.js"},
{"name":"welcome2.img","url":"app-icon.js","evaluate":true}
],
"data": [{"name":"welcome2.json"}]
},
{ {
"id": "gbridge", "id": "gbridge",
"name": "Gadgetbridge", "name": "Gadgetbridge",

17
apps/welcome2/ChangeLog Normal file
View File

@ -0,0 +1,17 @@
0.01: New App!
0.02: Animate balloon intro
0.03: BTN3 now won't restart when at the end
0.04: Fix regression after tweaks to Storage.readJSON
0.05: Move configuration into App/widget settings
0.06: Move loader into welcome.boot.js
0.07: Run again when updated
Don't run again when settings app is updated (or absent)
Add "Run Now" option to settings
0.08: Don't overwrite existing settings on app update
0.09: Allow welcome to run after a fresh install
More useful app menu
BTN2 now goes to menu on release
0.10: Tweaks to reduce memory usage
0.11: Fix initial screen fill colour
0.12: Fix swipe direction (#800)
0.13: Mods for Bangle.js 2

View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4AU5gAEFtoxnEwXN53WAAXO5oJB42Wy26AAIueFoPXFggAD4AwEGTQiB6otBFgwAD3QvFGC5dCFxiRGGClhrdbv67BXAIuLMBIwPsIABF4OpLwXOFxjBCF6gtBw2r1mHXoXWFxqQWFwOH62rL4IeB6xeOAAIvHGBYuC6+rR4QvCXpovXw3X1i/DR4QuPR5AvKFQOs6+GF4eod4IvPd5AvLwvWLwQvCv4fBR54vURwOHF4iQCX0yOCF4aQBX0QvHSAoAN3SOSd4WyF4yQPLyhgD1YvDMCJeIFxhgCF47BN4BeHFxpgDSAiRORpAuPMIYAFGBYuaF5aSHFwQvEFqQwOeggSBLa4xNF4X+4wAC/xeCFjIADrYwGBIIvlMQiPDBAOk0gDBz2XF8BlEF4eIxADFF8lcF9n+wIrFF05bHF9AsGF9wupGAYv/F8QupGAov/F/4wOF1gA/AH4Ap"))

256
apps/welcome2/app.js Normal file
View File

@ -0,0 +1,256 @@
// exec each function from seq one after the other
function animate(seq,period) {
var c = g.getColor();
var i = setInterval(function() {
if (seq.length) {
var f = seq.shift();
g.setColor(c);
if (f) f();
} else clearInterval(i);
},period);
}
// Fade in to FG color with angled lines
function fade(col, callback) {
var n = 0;
function f() {"ram"
g.setColor(col);
for (var i=n;i<240;i+=10) g.drawLine(i,0,0,i).drawLine(i,240,240,i);
g.flip();
n++;
if (n<10) setTimeout(f,0);
else callback();
}
f();
}
var SCENE_COUNT=10;
function getScene(n) {
if (n==0) return function() {
g.reset().setBgColor(0).clearRect(0,0,176,176);
g.setFont("6x15");
var n=0;
var l = Bangle.getLogo();
var im = g.imageMetrics(l);
var i = setInterval(function() {
n+=0.1;
g.setColor(n,n,n);
g.drawImage(l,(176-im.width)/2,(176-im.height)/2);
if (n>=1) {
clearInterval(i);
setTimeout(()=>g.drawString("Open",44,104), 500);
setTimeout(()=>g.drawString("Hackable",44,116), 1000);
setTimeout(()=>g.drawString("Smart Watch",44,128), 1500);
}
},50);
};
if (n==1) return function() {
var img = require("heatshrink").decompress(atob("ptR4n/j/4gH+8H5wl+jOukVVoHZ8dt/n//n37OtgH9sHhwHp4H5xmkGiH72MRje/LL/7iIAEE7sPEgoAC+AlagIlIiMQErPxDwUYxAABwIHCj8N7nOl3uEqa6BEggnFjfM5nCkUil3gEq5KDAAQmC6QmBE4JxSEhIABiQmB8QmSXoQlCYRMdEwIlCAAIlNhYlOiO85nNEyMPEoZwIAAcsYIYmPXoYlMiKaFExX/u9VEqLBBOYrCH+czmtVqJyDEpiaCOYsgSYszmc3qtTEqMR7hzG8AlGmd1OQglOOY6aEgYlCmmZoJMCTBrnD6SaIEoU/zOUuolSjbnBJgqaCEoU5zOXX4RyQYBBzCS4X5zNDqqZCJiERJg5zBEoVJEoM1JgYlQjhMHc4JLEmZMEEp6ZIJgPzS4WTmZMVTILmFYAK+BmglCmd1JgUYJiPNEorABEIOZygDBm5MCiJMQlhMH8ByBXwIlBJgUxJiMd5nOTIzlBTAK+BAANVq4jPAAS/HJgJyCTATAEACC/B4S/IJgIlCYAgAPiS/Kn5yEYANTEyPc5niOQxMB/LlCOapyJJgbpBYAZzROQK/Gl0ATIWfEoZzBc6IlB6SYGgBJBJgpzSlhyH8EAh5MBTIjnCuIlOjjlHTAJzC/LmDTSSYIEoTABOYIlETSKYHXwIABOYM0yYmETSCYHEobnDOYqaBExu8TAwlEc4U5EoiaCmK+NTAolFEwX0TQzBMXwXiEpTBCAAomNEoS+EEo4mIYIImKEoS+EEpDoBEyUbEo3gEo4mJdAImIJY4lJEycdEoPOOBYmPuIlE+HcJYhKKTZ1fhYkB2EAhnNcYMuEhomMr8A3YABEoJyB5gjOAAYmHm9VgELEoJMBEoXAEyXzE45YBJgXwEqx1I+ByDOYJyVJw5yCgEB3cQGgJMWJwQnCu6/CgFBigDB13S/glVAAf1qomCglEoADB1QDBADEPEoNVqEAolEgEKolKErJMDYAJMD0lE0AmaEoNaAgJMCFIYAahV/IgIiDOTgABNYJMEOToiCIoJMCOTzfCN4RMBOTxsDJIRyfIwZMBKQZzfJgRyfOYZMBOUBzCJgNKOT5zDJgLoCADxKBOAIABOT6aCAARyfOYRyjOYRyjOYlKEsBzEEsBzEOUJzDOUIABOUiaDOURzCOUZzCEscKCiY"));
var im = g.imageMetrics(img);
g.reset();
g.setBgColor("#ff00ff");
var y = 176, speed = 5;
function balloon(callback) {
y-=speed;
var x = (176-im.width)/2;
g.drawImage(img,x,y);
g.clearRect(x,y+81,x+77,y+81+speed);
if (y>30) setTimeout(balloon,0,callback);
else callback();
}
fade("#ff00ff", function() {
balloon(function() {
g.setColor(-1).setFont("6x15:2").setFontAlign(0,0);
g.drawString("Welcome.",88,130);
});
});
setTimeout(function() {
var n=0;
var i = setInterval(function() {
n+=4;
g.scroll(0,-4);
if (n>150)
clearInterval(i);
},20);
},3500);
};
if (n==2) return function() {
g.reset();
g.setBgColor("#ffff00").setColor(0).clear();
g.setFont("12x20").setFontAlign(0,0);
var x = 70, y = 25, h=25;
animate([
()=>g.drawString("Your",x,y+=h),
()=>g.drawString("Bangle.js",x,y+=h),
()=>g.drawString("has one",x,y+=h),
()=>g.drawString("button",x,y+=h),
()=>{g.setFont("12x20:2").setFontAlign(0,0,1).drawString("HERE!",150,88);}
],200);
};
if (n==3) return function() {
g.reset();
g.setBgColor("#00ffff").setColor(0).clear();
g.setFontAlign(0,0).setFont("6x15:2");
g.drawString("Press",88,40).setFontAlign(0,-1);
g.setFont("12x20");
g.drawString("To wake the\nscreen up, or to\nselect", 88,60);
};
if (n==4) return function() {
g.reset();
g.setBgColor("#00ffff").setColor(0).clear();
g.setFontAlign(0,0).setFont("6x15:2");
g.drawString("Long Press",88,40).setFontAlign(0,-1);
g.setFont("12x20");
g.drawString("To go back to\nthe clock", 88,60);
};
if (n==5) return function() {
g.reset();
g.setBgColor("#ff0000").setColor(0).clear();
g.setFontAlign(0,0).setFont("12x20");
g.drawString("If Bangle.js ever\nstops, hold the\nbutton for\nten seconds.\n\nBangle.js will\nthen reboot.", 88,78);
};
if (n==6) return function() {
g.reset();
g.setBgColor("#0000ff").setColor(-1).clear();
g.setFont("12x20").setFontAlign(0,0);
var x = 88, y = -20, h=60;
animate([
()=>{g.drawString("Bangle.js has a\nfull touchscreen",x,y+=h);},
0,0,
()=>{g.drawString("Drag up and down\nto scroll and\ntap to select",x,y+=h);},
],300);
};
if (n==7) return function() {
g.reset();
g.setBgColor("#00ff00").setColor(0).clear();
g.setFont("12x20").setFontAlign(0,0);
var x = 88, y = -35, h=80;
animate([
()=>{g.drawString("Bangle.js comes\nwith a few\napps installed",x,y+=h);},
0,0,
()=>{g.drawString("To add more, visit\nbanglejs.com/apps",x,y+=h);},
],400);
};
if (n==8) return function() {
g.reset();
g.setBgColor("#ff0000").setColor(0).clear();
g.setFont("12x20").setFontAlign(0,0);
var x = 88;
g.drawString("You can also make\nyour own apps!",x,30);
g.drawString("Check out\nbanglejs.com",x,130);
var rx = 0, ry = 0;
// draw a cube
function draw() {
// rotate
rx += 0.1;
ry += 0.11;
var rcx=Math.cos(rx),
rsx=Math.sin(rx),
rcy=Math.cos(ry),
rsy=Math.sin(ry);
// Project 3D coordinates into 2D
function p(x,y,z) {
var t;
t = x*rcy + z*rsy;
z = z*rcy - x*rsy;
x=t;
t = y*rcx + z*rsx;
z = z*rcx - y*rsx;
y=t;
z += 4;
return [88 + 60*x/z, 78+ 60*y/z];
}
var a;
// draw a series of lines to make up our cube
var s = 30;
g.clearRect(88-s,78-s,88+s,78+s);
a = p(-1,-1,-1); g.moveTo(a[0],a[1]);
a = p(1,-1,-1); g.lineTo(a[0],a[1]);
a = p(1,1,-1); g.lineTo(a[0],a[1]);
a = p(-1,1,-1); g.lineTo(a[0],a[1]);
a = p(-1,-1,-1); g.lineTo(a[0],a[1]);
a = p(-1,-1,1); g.moveTo(a[0],a[1]);
a = p(1,-1,1); g.lineTo(a[0],a[1]);
a = p(1,1,1); g.lineTo(a[0],a[1]);
a = p(-1,1,1); g.lineTo(a[0],a[1]);
a = p(-1,-1,1); g.lineTo(a[0],a[1]);
a = p(-1,-1,-1); g.moveTo(a[0],a[1]);
a = p(-1,-1,1); g.lineTo(a[0],a[1]);
a = p(1,-1,-1); g.moveTo(a[0],a[1]);
a = p(1,-1,1); g.lineTo(a[0],a[1]);
a = p(1,1,-1); g.moveTo(a[0],a[1]);
a = p(1,1,1); g.lineTo(a[0],a[1]);
a = p(-1,1,-1); g.moveTo(a[0],a[1]);
a = p(-1,1,1); g.lineTo(a[0],a[1]);
}
setInterval(draw,50);
};
if (n==9) return function() {
g.reset();
g.setBgColor("#ffffff");g.clear();
g.setFontAlign(0,0);
g.setFont("12x20");
var x = 88, y = 10, h=21;
animate([
()=>g.drawString("That's it!",x,y+=h),
()=>{g.drawString("Press",x,y+=h*2);
g.drawString("the button",x,y+=h);
g.drawString("to start",x,y+=h);
g.drawString("Bangle.js",x,y+=h);}
],400);
}
}
var sceneNumber = 0;
function move(dir) {
if (dir>0 && sceneNumber+1 == SCENE_COUNT) return; // at the end
sceneNumber = (sceneNumber+dir)%SCENE_COUNT;
if (sceneNumber<0) sceneNumber=0;
clearInterval();
getScene(sceneNumber)();
if (sceneNumber>1) {
var l = SCENE_COUNT;
for (var i=0;i<l-2;i++) {
var x = 88+(i-(l-2)/2)*12;
if (i<sceneNumber-1) {
g.setColor(-1).fillCircle(x,166,4);
} else {
g.setColor(0).fillCircle(x,166,4);
g.setColor(-1).drawCircle(x,166,4);
}
}
}
if (sceneNumber < SCENE_COUNT-1)
setTimeout(function() {
move(1);
}, 5000);
}
Bangle.on('swipe', dir => move(dir));
setWatch(()=>{
if (sceneNumber == SCENE_COUNT-1)
load();
else
move(1);
}, BTN1, {repeat:true});
(function migrateSettings(){
let global_settings = require('Storage').readJSON('setting.json', 1)
if (global_settings) {
delete global_settings.welcomed
require('Storage').write('setting.json', global_settings)
}
})()
Bangle.setLCDTimeout(0);
Bangle.setLCDPower(1);
move(0);

BIN
apps/welcome2/app.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

9
apps/welcome2/boot.js Normal file
View File

@ -0,0 +1,9 @@
(function() {
let s = require('Storage').readJSON('welcome2.json', 1) || {};
if (!s.welcomed) {
setTimeout(() => {
require('Storage').write('welcome2.json', {welcomed: true})
load('welcome2.app.js')
})
}
})()

18
apps/welcome2/settings.js Normal file
View File

@ -0,0 +1,18 @@
(function(back) {
let settings = require('Storage').readJSON('welcome2.json', 1)
|| require('Storage').readJSON('setting.json', 1) || {}
E.showMenu({
'': { 'title': 'Welcome App' },
'Run next boot': {
value: !settings.welcomed,
format: v => v ? 'Yes' : 'No',
onchange: v => require('Storage').write('welcome2.json', {welcomed: !v}),
},
'Run Now': () => load('welcome2.app.js'),
'Turn off & run next': () => {
require('Storage').write('welcome2.json', {welcomed: false});
Bangle.off();
},
'< Back': back,
})
})