Rotated characters with transparency

Posted on
  • I'm trying to make a circular watch face with the numbers angled towards the centre. To do this I draw each number in turn into an array buffer and save them as individual images so they can subsequently be drawn with appropriate rotation.

    The images are created using drawString with the "solid" parameter set to 0, which I hoped means empty pixels would remain transparent. They are saved with asImage("object") but the resulting image has no transparency information and the rotated numbers appear on an opaque background. To clear that I have add a "transparent" field and replace the buffer with a copy stored in a Uint8array.

    This works but it seems a really clunky process. Is there a better way to rotate text characters with a transparent background? Thanks.

  • Look in the espruino hardware reference, ctrl+f 'rotation' or similar. There is a way to rotate character.

  • Thanks for your reply. I know you can rotate the whole display or individual text items by 90/180/270 degrees but I want to rotate the hours by 30 degrees (or even 15 for a 24 hour clock) and possibly to rotate a smaller amount if I update it every second or minute. This is why I'm using drawImage() - if there's anything else I can't find it so I'd be really grateful for a pointer!

  • Ah, I see now! If you look at 'Icon Launcher' app.js-file it contains the E.showScroller function with slight custom modifications. Maybe you could do something similar with g.setFontAlign in your clock app? Or do a PR for adding the any-degree-rotation functionality to g.setFontAlign?

  • Many thanks, @Ganblejs, I'll take a look at that.

  • Hi - right now I think that's your only option. The code itself isn't that bad though. For example:

    var gr = Graphics.createArrayBuffer(24,16,1,{msb:­true});
    var grimg = gr.asImage();
    grimg.transparent = 0;
    
    g.clear();
    for (var i=1;i<=12;i++) {
      var ang = Math.PI*i/6;
      gr.clear().setFont("6x8:2").setFontAlign­(0,0).drawString(i,12,8);
      
      g.drawImage(grimg,
        88+Math.sin(ang)*70,
        88-Math.cos(ang)*70,
                  {rotate:ang});
    }
    

    Actually just drawing a bitmap font at an angle is kind of painful to do, so I don't think modifying Espruino would be significantly better that what's done here. There are other possibilities:

    • Vector fonts could be rendered at an angle - but again it requires Espruino mods and vector fonts don't look good small
    • You could store each of the 10 digits as a polyline, and could then use g.transFormVertices and g.drawPoly to draw the lines at the correct angle...

    1 Attachment

    • clock-rotate.png
  • Thanks, Gordon, that's good to know. It hadn't occurred to me to set transparency before drawing the image - saves faffing around afterwards and much appreciated!

    I'm actually using a custom font with symbols so vectors and polylines would be difficult but I'm happy with this approach now. many thanks.

  • I'm wondering if this method would work for a watch face I'm working on.
    Video here on my Pleroma: https://masto.amosamos.net/notice/ASVJZT­V9ouZ50SgisC )
    Code: https://github.com/lightnin/BangleApps/b­lob/master/apps/rinku2/app.js

    When the watch is unlocked, the outermost ring descends to show the day of the month, but to make that clearer I'd like to wrap a "February" inside the outermost ring preceding the date, followed by 2023 after. Each of the letters and numbers need to be oriented towards the center, similar to the description above.
    This is getting far beyond my ability - but I guess I should put the months in an array, and then create a loop similar to what Gordon showed above to rotate and print each letter in the ring after the date. I'm doing 12 frames of animation for the ring expansion / contraction, so worried I might be eating all my battery rendering all these numbers. Any suggestions?

  • I would have thought that was ok? As you say, it might be a bit faster/more efficient to have 3 images, one for each of the rings - then you just use 'g.drawImage' for each entry.

    I'd just have a play around - there's not that much code there so I'd have thought you would be able to get something working quite quickly!

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Rotated characters with transparency

Posted by Avatar for BillV @BillV

Actions