-
Thinking about I'm wondering - would it be better to generate an image from the array,it would need to be a full 8bpp, could probably get away with 5 or 6.
If I can make the image roll around the screen then I can use that as the pre-calculated background?
I think having to shift or unshift the arrays is where it's slowing down so it seems like a good place generate it once and reuse itFor the effect, Each filled rectangle width is (screen width / total gradient array length) so you get the effect of each colour at the edge and the wide bar of each colour, and a pretty smooth gradient effect.
I was thinking also pre-storing all the theme steps instead of generating them each time, but if it's only run once I think having the function seems better as it's only a single calculation each time.
I also wanted a random option, but BangleJS's Math.random isn't random enough! I even tried adding a multiplier from the accelerator each time the function was called to make it more random but it was still generating colour combinations too close to each other.
-
-
Hey,
I'm working on a clock face - It's a gradient generator with some themes and configuration.
The themes are each two colours, and a function in the watch generates more colours based on the passed number of steps.
It then creates an array and appends the reversed version to it to create one smooth gradient field.
Using the accelerometer to decide the direction the gradient moves in so you get an effect of the background moving - you can also switch it between horizontal and vertical
To get this working effectively I'm using LCD Mode "doublebuffered" which works great - if I try it in normal I get a lot of flickering and haven't really figured of if it's possible with that I'm doing to do in that mode.
But I've noticed that despite my best efforts, the screen never goes off with the LCD Timeout, and I'm wondering what I'm doing wrong? This isn't the most memory-efficient clock, and it does a lot of drawing (once per 100ms to be smooth) by shifting the entire array of colours so when the screen isn't on I'd definitely like to stop any running timers.
Can anyone spot what I'm doing wrong?
-
Hey @Gordon - thanks for the feedback.
The final idea would be to have something that is zero dependencies and fully tree-shakable, but for now, it's just a concept idea - I've got some kind of pipeline compiling the library to a IIFE version and appending it with the app code, which is also IIFE and it works fine - but yes it's pulling 10K for that file.
I'm trying for the library being ESM/UMD which means it's importable and tree-shakable, and the output code being UMD with bundled dependencies but it seems a pain right now. It's something I might come back to.
(As it is if I made that select component more compact would it be useful in the core? It's an alternative to a menu but allowing a user prompt)
-
Hi, I've had a look and couldn't find anything on getting a screen dump of the current view on the watch - I tried a few of the things from the Graphics library like fromBPM but that gives me:
Uncaught Error: asBMP/asURL only works on 1bpp/24bpp Graphics
And if I try
getImage
with an object or string I get:Interpreter error: [ "LOW_MEMORY", "MEMORY" ] New interpreter error: LOW_MEMORY,MEMORY
g.buffer
seems to be undefined - I was trying to see if I could convert it to a UInt8Array and then to string.Does anyone have any suggestions?
-
Option 2 would be nice here - it seems a bit of a waste of cycles to have to read an entire file just to get the latest entry. The solution I've come up with is to read the file into an array, unshift with the latest row then re-write the file. With this case, I can make each line a valid JSON separated by a line break and it works reasonably efficiently, and I can just get the first line for the latest data.
-
Hey everyone. So I've had my Bangle for a few days and I've been diving into discovering what it takes to make an app for the device.
My output so far is WatchmakerJS - https://github.com/tanepiper/watchmaker-js (with demo "Moods" app)
This is very very alpha - there are two parts included in it:
The library itself - https://github.com/tanepiper/watchmaker-js/tree/main/packages/watchmaker/watchmaker/src/lib
A basic app using it: https://github.com/tanepiper/watchmaker-js/blob/main/packages/apps/wmaker/src/main.ts
The library includes a few wrapper functions around
E
methods, using some additional library code to take strings and turn them into pages of content. There is also a new UI component I called a "Scroll Prompt" that is a cross between a Prompt and a Menu: https://github.com/tanepiper/watchmaker-js/blob/main/packages/watchmaker/watchmaker/src/lib/ui.ts#L117Here is only shows two options - but like a menu it supports as many options as provided
The biggest part of the library is
lug
- A small application framework that allows routable applications to be created and handles some additional stuff:- A router configuration and
.goTo
method that allows you to define your application flow - A global state (that should be used sparingly!) that allows for some shared state across the app
- Methods for loading/saving from an app.settings.json file, and loading global settings
- Methods for loading from an application text file (for storing strings rather than hard-coding in memory)
- Methods for saving data as a JSON file in storage, with each line a separate JSON object (recommended with using an array of data and .unshift to make sure the latest data is at the top, not the end) - so it's easily parsable in the app, and also easy to parse with some additional changes on the interface.html
- Methods for loading data to a specified number of lines
- Some basic state for storing images that are regularly used.
- Also has three callbacks passed as options -
init
for setting app state,first
for the first transition after app state loaded andonChange
when each route change happens.
So far these are the things I've found I needed to make a fast, memory-efficient app. Since implementing these new techniques my initial app - which ran out of memory - now barely pushes total memory usage over 60%
I've written an initial app for it - The Moods App - https://github.com/tanepiper/watchmaker-js/blob/main/packages/apps/wmaker/src/main.ts
- Loads some initial data and state (https://github.com/tanepiper/watchmaker-js/blob/main/packages/apps/wmaker/src/main.ts#L531)
- If the first run, shows the help steps, otherwise goes to the home page
- Sets up listeners for GPS, HRM and LCD Power, and a debug function with debug data (only available when Debug Info is on in the global settings - can be viewed in the debug menu) (https://github.com/tanepiper/watchmaker-js/blob/main/packages/apps/wmaker/src/main.ts#L62)
- Handles the flow of data through sync and async pages, and includes some new UI like the Scroll Prompt page (https://github.com/tanepiper/watchmaker-js/blob/main/packages/apps/wmaker/src/main.ts#L258)
- Some basic drawing of image and text (using image from the app state) https://github.com/tanepiper/watchmaker-js/blob/main/packages/apps/wmaker/src/main.ts#L44
Data is saved each time a new mood is added - which can include HRM and Geolocation data - it's also saved by reading the current file, appending the new record to the beginning and resaving - this means re-reading data the latest is always at the top. This makes re-reading data much more efficient than having to read the whole file to get the latest data.
There are instructions to build the library and the app - currently, the app requires the library and I'm still figuring out the tooling to bundle correctly - otherwise, the library needs to be included in the BangleApps module folder and as it's still early release I'd prefer not to add the app just now.
The overall size of apps is still on the large size - there's also an issue with the Terser plugin causing code to fail when uploaded to the Bangle, but that works perfectly fine unminified. However once on the device the app is quick and efficient with data.
Would love to get some feedback on this in terms of usefulness and also potential features (also on anything anyone sees as a nono!)
-
Hi,
I've been working on a little framework around my application - so far it's actually worked out pretty well, but I've hit an issue when I publish it and try to use it remotely.
The code is here: https://github.com/tanepiper/watchmaker-js - I've tried to configure the nx tooling as best I can, although I'm using their
umd/esm
builder it's configured with rollup to output for node.The published file is here: https://unpkg.com/watchmaker-js@0.0.5/watchmaker-js.umd.js
Now when I try load this with require, I get an error - but if I take this file and put it in my modules directory it works fine can call it watchmaker-js.min.js it works fine!
The error is:
espruinotools.js:2872 Uncaught (in promise) SyntaxError: Unexpected character 'ยง'
I was wondering if anyone had any experience with this, or might know what is causing this?
(And if you want to see how it's used - the app code is here https://github.com/tanepiper/BangleApps/blob/master/apps/moods/moods.js)
-
Brilliant stuff! This really helps get a deeper understanding of what's available and not - and love the remote modules! That'll really help to just throw some code on Github and use it as my own standard lib stuff.
Regarding scrolling, I suppose I mean more scrollbars, but since it's not really touch scrolling but button event-based I suppose I can just re-render the message using something similar to the page technique I have.
Thanks for your help
-
Hi there,
So my BangleJS arrived today after an adventure in stuck in Dutch customs (yay B*exit) for over a week and then sent to a depot 40min drive away from me!
I've had a good play with it already today and had a few questions - I've been working on my Moods app and some things have come up already.
Is there a way to add a custom "standard library" - for example, I figured out that the maximum number of characters per line is 20, with 4 lines so I've written a custom function I'd like to potentially re-use, but certainly removed from the main JS file of my app (also some preferred date functions - I tried moving it to a file to require in my project but this didn't seem to work
With the above I discovered the best ratio of characters/screen - is there more info like this such as best-practices for UI and UX design for the watch? Is there any concept of scrolling on the device?
Are there any details on what version of ECMAScript is the closest? For example, I see the device has support for const/let and has TypedArrays, but no support for deestructuring or default values? Has anyone set up any toolchains to allow compiling from higher-level code?
OK @Gordon I understand the concept, but I'm missing some details (I was never good at graphics programming)
First off, before I did try to create an 8bpp image I usually get LOW_MEMORY warnings - so I gave up and stuck to the doublebuffer and drawing.
I looked at the animated clock example - I see they have a pre-computed palette file that is some binary data? For the Uint16Array I don't quite understand what needs to go in it?
At the moment I'm using RGB values, and when drawing converting them to the correct 0...1 value.
I assume from what I'm reading the array maps to each individual pixel? Instead of shifting the data, I'd just move the palette X pixels to the left to right? In that case, do I need to draw a background, or am I just palette shifting at this point to get the same desired effect?
Then I assume here it's draw image and flip? (or is clear better?)