Ellipse/Circle implementation will not affect my ui code. Because of the low resolution and relative small size of the shapes - and the performance(?) I use only vertices - and that is 'plenty good' enough (if fill rendering would work as 'expected'/not overshoot):
8 corners for check boxes and very small buttons
12 corners fort buttons
8..16 'corners' for small to larger radio buttons / circles
This is the code segment (part of uiExt.js module):
- exports = // ui (generic) ext(ension/utils: vertices(circle,...) find elt/idx in arr,...)
{ mn: "uiExt" // module 'clazz' name - globally unique (used to remove code from cache)
, cvn: [[92,38,38,92,-38,92,-92,38,-92,-38,-38,-92,38,-92,92,-38]
,[98,20,83,56,56,83,20,98,-20,98,-56,83,-83,56,-98,20
,-98,-20,-83,-56,-56,-83,-20,-98,20,-98,56,-83,83,-56,98,-20]]
, cvs: function(x,y,w) { // circle from vertices by bounding box w/ left, top and width
var r=w/2,c=[x+r,y+r],z=r/100; return this.cvn[(w<12)?0:1].map((v,i) => c[i&1]+v*z); }
, vs2: function(x,y,x2,y2,p) { // vertices for for chk like shapes ('beveled') corners
// 4 'beveled corners' = 8 corners defined by 0 and p insetting combinations for x, y
return [x,y+p, x+p,y, x2-p,y, x2,y+p, x2,y2-p, x2-p,y2, x+p,y2, x,y2-p]; }
, vs3: function(x,y,x2,y2,p,q) { // return vertices for btn like shapes ('round' corners)
// 12 'round corners' (4x3) defined by 0, p and q insetting combinations for x and y
return [ x,y+p, x+q,y+q, x+p,y, x2-p,y, x2-q,y+q, x2,y+p,
x2,y2-p, x2-q,y2-q, x2-p,y2, x+p,y2, x+q,y2-q, x,y2-p]; }
As said earlier: Drawing the polygons with the vertices does just fine... filling messes them up.
(Working on the maze rendering a +-1 in the coordinates has major impact when working with low resolution like Pixle.js.)
`Espruino --- Draw/Fill test w/ Small/low resolution Polygons w/ Vertices`;
`Notices the rendering difference between draw and fill from`;
` left and right and *EVEN DEPENDING ON POSITION on display`;
var vs2 = function(x,y,x2,y2,p) { // vertices for beveled, chk box like shape
// 4 'beveled corners' = 8 corners by 0|p inset combinations for x/y corners
return [x,y+p, x+p,y, x2-p,y, x2,y+p, x2,y2-p, x2-p,y2, x+p,y2, x,y2-p]; };
var c0, c1; // colors
if ("undefined" != typeof Pixl ) { c0=0 ; c1=1; }
else { c0="#000000"; c1="#FFFFFF"; }
function onInit() {
`prep display`
g.clear(); setTimeout(()=>{
g.setColor(c0);
g.fillRect(0,0,127,63); c=// canvas (color 0)
`beveled squares and rectangles drawn and filled with polygon (color 0)`
g.setColor(c1);
g.fillRect(8,8,40,53); // frame filled (color 1)
g.setColor(c0);
g.drawPoly(vs2(10,10,18,18,1),1); // 9x 9 draw beveled [1] for x and y
g.drawPoly(vs2(21,10,38,18,1),1); // 9x19 draw beveled [1] for x and y
g.fillPoly(vs2(10,21,18,29,1),1); // 9x 9 fill beveled [1] for x and y
g.fillPoly(vs2(21,21,38,29,1),1); // 9x19 fill beveled [1] for x and y
g.drawPoly(vs2(10,32,18,40,2),1); // 9x 9 draw beveled [2] for x and y
g.drawPoly(vs2(21,32,38,40,2),1); // 9x19 draw beveled [2] for x and y
g.fillPoly(vs2(10,43,18,51,2),1); // 9x 9 fill beveled [2] for x and y
g.fillPoly(vs2(21,43,38,51,2),1); // 9x19 fill beveled [2] for x and y
`scalable beveled squares w/ borders done with two stacked, filled polygons`
g.setColor(c1);
g.fillRect(45,8,57,53); // frame filled (color 1)
g.setColor(c0);
g.fillPoly(vs2(47,21,55,29,1),1); // bot bev'd [1] square separate (color 0)
g.fillPoly(vs2(47,43,55,51,1),2); // bot bev'd [2] square separate (color 0)
g.setColor(c1);
g.drawRect(62,8,74,53); // frame hallow (0 from canvas)
g.setColor(c1);
g.fillPoly(vs2(65,22,71,28,1),1); // top bev'd [1] square separate (color 1)
g.fillPoly(vs2(65,44,71,50,1),2); // top bev'd [2] square separate (color 1)
g.setColor(c1);
g.fillRect(79,8,91,53); // frame filled (color 1)
g.setColor(c0);
g.fillPoly(vs2(81,21,89,29,1),1); // bot bev'd [1] square combined (color 0)
g.fillPoly(vs2(81,43,89,51,1),2); // bot bev'd [2] square combined (color 0)
g.setColor(c1);
g.fillPoly(vs2(82,22,88,28,1),1); // top bev'd [1] square combined (color 1)
g.fillPoly(vs2(82,44,88,50,1),2); // top bev'd [2] square combined (color 1)
if (c1===1) g.flip(); // for pixle (does bangle need it too?)
},999);
}
setTimeout(onInit,999); // for dev'n, remove for upload before save()
Most stunning is that even position on display matters... I know that for some displays the dot pattern is not squares but rectangles: 30 vs 36 units - such as Pixl.js' one - and that may play into it... I though think that on so low resolutions / small screens, this should not be taken into account, because this messes heavily with rendering. I know circles are then slightly ellipses... but guess, these displays are not used for CAD / making pictures of it and then noticing that the circle is not exactly a circle... With so low resolution / small shapes, one pixel off is worse than the fraction the pixel to pixel difference in x-axis direction vs y-axis direction:
On Pixle.js, where a button checkbox is as small as 9 pixel in x and y direction and corner happening in space of 2x2 pixels, one pixel off in the corner by rounding (because of considering the 30 vs 36 pixels x vs y size) is 50%... where as the 30 vs 36 is 20% (max 25%, depending from which side you look). The human eye/brain is able to see a circle and a 45 degree bevel, even though it may not exactly by that... but 50% makes the difference between 'seeing' a square with straight vs beveled corners and a circle or a potato (Nothing wrong with potatoes, ...I mean for a food).
NB: I stack / overlay to scale shapes, filled - solid - and 'empty' - borders. I intend same render code for very low resolutions - like 128 vs 240 pixels in width... about very close the same absolute physical size of Pixle.js and 2.8" 240x320 TFT... But I had already to deviate and make the size pick different sets of vertices... and vertices are not exactly cheap in space... (even though there may be some enhancements I could do).
Attached is screen shot from Pixl.js (2) and Bangle.js emulation (1). Results are though exactly the same... (why???? - not same display driver).
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
@MaBe ( and @Gordon )
Ellipse/Circle implementation will not affect my ui code. Because of the low resolution and relative small size of the shapes - and the performance(?) I use only vertices - and that is 'plenty good' enough (if fill rendering would work as 'expected'/not overshoot):
This is the code segment (part of uiExt.js module):
The example is ui_...zip file I sent you a bit ago (.../_sbx/projects/uiExampleAllPixl.js) expecting Espruino Web IDE sandbox folder pointing to
.../_sbx
where ever you unpack(ed) it). - You can find the zip also here - and with a slightly different (previous version) on http:// http://www.espruino.com/modules/uiExt.js - and http://www.espruino.com/ui | http://www.espruino.com/uiExampleAllPixlAs said earlier: Drawing the polygons with the vertices does just fine... filling messes them up.
(Working on the maze rendering a +-1 in the coordinates has major impact when working with low resolution like Pixle.js.)
Most stunning is that even position on display matters... I know that for some displays the dot pattern is not squares but rectangles: 30 vs 36 units - such as Pixl.js' one - and that may play into it... I though think that on so low resolutions / small screens, this should not be taken into account, because this messes heavily with rendering. I know circles are then slightly ellipses... but guess, these displays are not used for CAD / making pictures of it and then noticing that the circle is not exactly a circle... With so low resolution / small shapes, one pixel off is worse than the fraction the pixel to pixel difference in x-axis direction vs y-axis direction:
On Pixle.js, where a button checkbox is as small as 9 pixel in x and y direction and corner happening in space of 2x2 pixels, one pixel off in the corner by rounding (because of considering the 30 vs 36 pixels x vs y size) is 50%... where as the 30 vs 36 is 20% (max 25%, depending from which side you look). The human eye/brain is able to see a circle and a 45 degree bevel, even though it may not exactly by that... but 50% makes the difference between 'seeing' a square with straight vs beveled corners and a circle or a potato (Nothing wrong with potatoes, ...I mean for a food).
NB: I stack / overlay to scale shapes, filled - solid - and 'empty' - borders. I intend same render code for very low resolutions - like 128 vs 240 pixels in width... about very close the same absolute physical size of Pixle.js and 2.8" 240x320 TFT... But I had already to deviate and make the size pick different sets of vertices... and vertices are not exactly cheap in space... (even though there may be some enhancements I could do).
Attached is screen shot from Pixl.js (2) and Bangle.js emulation (1). Results are though exactly the same... (why???? - not same display driver).
3 Attachments