Project - Message Clock

Every self-respecting 'hobby' language starts with the obligatory "Hello world" example, so we'll do likewise... but we'll deliver our message via a wormhole (websocket) so it can be instantly changed in time without disturbing surrounding space.

So tighten your seatbelts, because we have a long way to go, and need to travel fast and light.
You will be flashing past many valuable gems which you may not even notice or recognise yet - but this is not a story book, so you don't need to remember it all... just mentally bookmark things for future reference to keep coming back to when needed.
To speed things up and make it easier, I will quickly explain a bunch of useful stuff, then we can load them all at the same time and I'll point out what to look for, rather than keep tediously copying and pasting code for every individual point to be made.

TIP: HTML and CSS lack a specific command to centre (center) a div and its contents on the screen, but what if you don't know the width of the div with its contents, or the width of the screen, how then can you center things ?

You can trick the div into centering itself by adding the following style code into the div declaration...
style='display:table; margin-right:auto; margin-left:auto;' 

You can try it now if you wish by copying the following div declaration over the existing one, then Save, Run, and view Output.
a$ = a$ + |<div class='analog-clock' style='display:table; margin-right: auto; margin-left: auto;' >|

So that's how to center the div on screen, but the contents of the div will still default to the left of the div container unless told otherwise, which we can do by adding "text-align:center;" into the div style string (or "text-align:right;" to align right).

Our div line would now be...
a$ = a$ + |<div class='analog-clock' style='display:table; margin-right: auto; margin-left: auto; text-align:center; '>|

That will centre the textbox component in the div, but the textbox contents will still default to the left of the textbox unless told otherwise. Annex-Wifi Basic web components have an option to specify an ID for them, so we can give the textbox on ID of "tb1" for example, then we can use the Basic CSSID$ function - using the textbox ID name as the first parameter followed by our 'style' string we wish to style it with as the second... in this instance to add "text-align:center;" to centre the textbox contents.

That was 3 different quickfire centering tips worth taking note of for future reference - one inside another inside another...
 How to centre text in a textbox component.
 How to centre contents such as a textbox component inside a div.
 How to centre a div on the screen.

You can use the same CSSID$ method of assigning ID's to other web components and then similarly assign chosen styles to their ID.

The second CSSID parameter can be a 'literal' "string list of your styles", but if it gets too long for comfort you can use a string variable instead.
So rather than CSSID$("IDname","text-align:center; colour: red;") you could define styles in a var, eg: mycss$ = "text-align:center;", then on another line append subsequent style using mycss$ = mycss$ + " colour: red;", and just keep appending more styles as needed, until the var contents eventually all get sent to browser using CSSID$("IDname", mycss$).
 
Do similar within any lines that grow longer than your editors screen width, simply split them up into more manageable chunks and assign them to an accumulating variable which re-joins them back together by appending new to old.

Don't forget to empty the variable (= "") before you start adding to it (and it's also a good idea to empty it again after you are finished with it).

The Basic button$ component includes a 'label' parameter which specifies what branch name the program jumps to when clicked.

IMPORTANT TIP: most non-Basic web components (such as our div) can also be made to jump to a subroutine branch when clicked.
The trick to make ordinary html web components interact with minibasic is to include "data-var='myclick'  onclick='cmdButton(this)'", where the data-var value ('myclick' in this instance) specifies the name of a subroutine to branch to.

Adding that directly into our div declaration could make it much longer than the editor screen width, so we can treat it as a long line as mentioned above, by snipping off the 'closing bits' from the original line, appending our new text to the old, then add back the closing bits again.

To better explain:
most tags - including the <div> tag - can be opened out to accomodate a space plus additional info inserted between the tag name and its closing chevron (arrow). The additional info could be id='name' or style="color:red;" etc, essentially causing the original div declaration to be split into its beginning part "<div ", then the newly inserted "id='name'" contents, followed by its closing ">" part, eg:
 a$ = "<div "
 a$ = a$ + " id='name' "
 a$ = a$ + " >"

So the appended a$'s would still result in a$ = "<div id='name'>" after being split up over 3 lines (the browser strips out unnecessary spaces).

Notice that many html data values need to be encapsulated within single or double quotes, which can become very confusing when chopping bits up and joining them back together. Obviously you can only use single quotes inside of double quotes else the first single quote would be interpreted as a comment (REM) for the remainder of the line. You can also encapsulate text using vertical bar | chrs.

TIP: Don't encapsulate lines with double quotes, use the vertical bar "|" character instead (like the conversion utility does).
 
Returning to our long div declaration, and putting all of the above together, our div can be neatly and easily done like so...
 a$ = |<div |
 a$ = a$ + | class='analog-clock' style='display:table; margin-right: auto; margin-left: auto; text-align: center;' |
 a$ = a$ + | id='clock' data-var='clicked' onclick='cmdButton(this)' |
 a$ = a$ + | >|

In this instance we are making the div clickable, including all of its contents, which will cause a jump to the 'clicked' branch.

You can make your own 'click event handler' (branch) do whatever you choose, in our case we send a different message through the wormhole.
A word about that...
The textbox$ component displays the specified variable using a websocket connection to avoid having to re-write the rest of the display. So we define the variable, then create a textbox$ component to use it... but we only do this once.
If the variable contents are subsequently changed, issuing the REFRESH command causes the textbox to display the new var contents.


Our demo does some other trivial effects, which serve to illustrate the potential for more useful tasks if wished.
A 1 second timer is constantly toggling a flipflop 'flag'. When clicked, a different message is displayed, a countdown is started, and the clock flashes alternate colours (making use of the CSS command) for the duration of the countdown.
If clicked again during the countdown, a different message is displayed, and the following line is invoked...
 css "<style>  .analog-clock {transform:rotate("   +   str$(rnd(360))   +   "deg); }</style>"
...which causes the div contents to be rotated by a random amount.

The flashing colours and image transform are 'undone' when the countdown timer reaches zero.

NOTE: to insert variables into an html line requires chopping the line at the desired point and terminating its quotes, appending the required variable (converted to text if numeric), then appending opening quotes and rejoining the remainder of the line.
That is not expected to make much sense yet... but at least you will know where to start digging when a hacking urge comes along.
  
The script below is the same as you converted from html, plus the additions mentioned above.
It still uses your original STYLE.CSS stylesheet, including any style changes you saved.
However, some of the stylesheet styles are being purposely over-ridden by these following CSS commands (to show how its done)...
 css "<style>  #clock-face{ fill:white ;} </style>"              'white clock face
 css "<style>  #s-hand{ stroke:darkred} </style>"                'dark red second-hand
 css "<style>  #s-tail{ opacity:0;} </style>"                    'hide the second-hand tail

All that remains now is to copy and paste the following code into your editor, Save it to a chosen name in a chosen folder, switch to your Ouput window, then click Run, and see what tricks Annex-Wifi Basic can make your converted html clock perform.

Basic:
cls
a$ = ""
a$ = a$ + |<!DOCTYPE html>|
a$ = a$ + |<html>|
a$ = a$ + |  <head>|
a$ = a$ + |    <title>Analog Clock</title>|
a$ = a$ + |    <link type="text/css" rel="stylesheet" href="/html/style.css">|
a$ = a$ + |  </head>|
a$ = a$ + |  <body>|
a$ = a$ + "    <div id='clock' class='analog-clock' data-var='clicked' onclick='cmdButton(this)' style='text-align: center;display: table; margin-right: auto; margin-left: auto; bottom:300px;'>"
a$ = a$ + |      <br><br>|
a$ = a$ + |      <svg width="140" height="140">|
a$ = a$ + |        <circle id="clock-face" cx="70" cy="70" r="65" />|
a$ = a$ + |        <line id="h-hand" x1="70" y1="70" x2="70" y2="38" />|
a$ = a$ + |        <line id="m-hand" x1="70" y1="70" x2="70" y2="20" />|
a$ = a$ + |        <line id="s-hand" x1="70" y1="70" x2="70" y2="12" />|
a$ = a$ + |        <line id="s-tail" x1="70" y1="70" x2="70" y2="56" />|
a$ = a$ + |        <text x="62" y="18">12</text>|
a$ = a$ + |        <text x="126" y="76">3</text>|
a$ = a$ + |        <text x="66" y="130">6</text>|
a$ = a$ + |        <text x="7" y="76">9</text>|
a$ = a$ + |      </svg>|
a$ = a$ + |      <div class="time-text">|
a$ = a$ + |        <span id="hr">00</span>|
a$ = a$ + |        <span>:</span>|
a$ = a$ + |        <span id="min">00</span>|
a$ = a$ + |        <span>:</span>|
a$ = a$ + |        <span id="sec">00</span>|
a$ = a$ + |        <span id="suffix">--</span>|
a$ = a$ + |      </div>|
a$ = a$ + |      <br><br>|
message$ = "Hello world"
a$ = a$ + textbox$(message$,"textboxcss")
a$ = a$ + cssid$("textboxcss", "text-align: center; ")
a$ = a$ + |    </div>|
a$ = a$ + |  </body>|
a$ = a$ + |</html>|
html a$
jsexternal "/html/script.js"
jscall "clock()"
css "<style>  #clock-face{ fill:white ;} </style>"
css "<style>  #s-hand{ stroke:darkred} </style>"
css "<style>  #s-tail{ opacity:0; stroke:black;} </style>"
flash = 0
countdown = 5
flipflop = 0
gone = 0
timer0 1000,tick
wait

tick:
if flipflop = 0 then flipflop = 1 else flipflop = 0
if flash = 1 then
 countdown = countdown - 1
 if flipflop = 0 then css "<style>  #clock-face{ fill:yellow;} </style>" else css "<style>  #clock-face{ fill:red;} </style>"
else
 css "<style>  #clock-face{ fill:white ;} </style>"
 css "<style>  .analog-clock {transform: rotate(0deg);} </style>"
endif
if countdown = 0 then
 countdown = 8
 flash = 0
 gone = 0
 if flipflop = 0 then  message$ = "take it easy" else message$ = "be gentle"
 refresh
endif
return

clicked:
if flipflop = 0 then  message$ = "ouch!" else message$ = "that hurt!"
refresh
if flash = 1 then
 if flipflop = 0 then  message$ = "goodbye cruel world" else message$ = "get me outa here"
 refresh
 if gone = 1 then
  css "<style>  #clock-face{ fill:magenta;} </style>"
  message$ = "stop doing that"
  refresh
  css "<style>  .analog-clock {-webkit-transform: translate(" + str$(rnd(200)-100) + "px," + str$(rnd(300)+ 100) + "px) rotate(" + str$(rnd(360)) + "deg); }</style>"
  pause 4000
  else
   css "<style>  .analog-clock {-webkit-transform: translate(" + str$(rnd(200)-100) + "px," + str$(rnd(300)+ 100) + "px) rotate(" + str$(rnd(360)) + "deg); }</style>"
  gone = 1
  pause 3000
 endif
 if flipflop = 0 then  message$ = "a new beginning" else message$ = "let's start again"
 refresh
endif
if flash = 0 then flash = 1 else flash = 0
return


When you get bored with it, lean back, and ponder what you have achieved. Here's a reminder...

 You have used the editor to create an analog clock web page, plus its external cascading stylesheet and javascript files.
 You have seen how to serve up and connect to your hosted web content.
 You have seen how to modify the style and position of your content by editing the css and html.
 You have converted your web page into a
Basic script.
 You have modified the converted web clock to make it become "intelligently" interactive and responsive to input.
 
 
Hey, that's not bad for a first lesson!
 

One last bit of Annex-Wifi Basic magic before you move on...
We have the Basic script loaded in the editor, which reads styles from the external style.css stylesheet.
Although we have chosen to over-ride a few styles in our script, most are being defined in the external stylesheet.

Earlier you edited styles in the stylesheet, but you don't want to be loading the stylesheet into the editor, changing colours, saving the stylesheet, then loading the Basic clock script back again ... that would quickly get tedious.
So listen carefully to the secret!

If you click the 'Advanced' checkbox to the right of the 'File to Run' window, it will allow you to load a different file into the editor, while still leaving your minibasic script 'loaded'.
It is easier to do than explain, so click Stop to ensure the script is not running, then tick the Advanced checkbox, then click the Open button and load  /html/style.css  into the editor.

Now you can go down to where it defines all three hands, and change the 'black' into 'blue' (as shown below) then click Save.
#h-hand, #m-hand, #s-hand, #s-tail{
    stroke:blue;

Now for the magic ... still with the stylesheet loaded in the editor, switch to the Output page, and click Run.
No difference yet of course, because we still need to refresh the browser page after editing the stylesheet (just making that point as a reminder).
Click Stop, press F5, then click Run...  you should now see your re-styled minute and hour hands coloured blue.

How cool is that ? ... you can keep changing styles in the editor then testing the results by starting and stopping your script which stays loaded in the background, avoiding the need to keep reloading files.
Make sure to un-tick the Advanced checkbox when done, which unfortunately does not reload your background script back into the editor, so you will need to Open and reload the Basic script back into the editor again if you wish to work on it.