Project - Wall Switch

Here is another stylish switch  (a link to the original article is included in the comments).
Also an overview of how to modify html checkbox switches to be functional in Basic:
They will have at least 2 styles, a 'before' and an 'after' the checkbox state is ticked.
You don't interface directly with those styles, you just disable the original web checkbox component then add your own Basic checkbox$ alternative which you can toggle according to the state of your specified variable, so the before and after styles will take care of themselves when your checkbox$ changes state. You just need to branch to change the state of your variable whenever the checkbox state is toggled when clicked.

The top and bottom red coloured code are the functional additions needed,
plus swapping the web checkbox out for a Basic checkbox$ component as shown.
Basic:
pinA = 12                          'gpio pin for switch A
stateA = 0                         'used to specify the switch state according to the checkbox state
pin.mode pinA, output      'configures the pin for output
pin(pinA) = stateA             'sets pin to default state
onHtmlChange change     'jump when switch is clicked
cls
a$ = ""
a$ = a$ + |<style>|
'a$ = a$ + |/* https://tympanus.net/codrops/2012/09/13/button-switches-with-checkboxes-and-css3-fanciness/ */|
a$ = a$ + |body {|
a$ = a$ + |    background-color: lightblue;|
a$ = a$ + |}|
a$ = a$ + |.switch input {|
a$ = a$ + |    /* First, we make it as wide as the container */|
a$ = a$ + |    position: absolute;|
a$ = a$ + |    width: 100%;|
a$ = a$ + |    height: 100%;|
a$ = a$ + |    /* Then, we put it on top of everything else */|
a$ = a$ + |    z-index: 100;|
a$ = a$ + |    /* Last, we make it invisible */|
a$ = a$ + |    opacity: 0;|
a$ = a$ + |    /* This one is just for ergonomy */|
a$ = a$ + |    cursor: pointer;|
a$ = a$ + |}|
a$ = a$ + |.switch {|
a$ = a$ + |    width: 50px;|
a$ = a$ + |    height: 100px;|
a$ = a$ + |    position: relative;|
a$ = a$ + |}|
a$ = a$ + |.switch label {|
a$ = a$ + |    display: block;|
a$ = a$ + |    width: 100%;|
a$ = a$ + |    height: 100%;|
a$ = a$ + |    position: relative;|
a$ = a$ + |    background: #cbc7bc;|
a$ = a$ + |    border-radius: 5px;|
a$ = a$ + |    box-shadow:|
a$ = a$ + |        inset 0 1px 0 white,|
a$ = a$ + |        0 0 0 1px #999,|
a$ = a$ + |        0 0 5px 1px rgba(0,0,0,0.2),|
a$ = a$ + |        0 2px 0 rgba(255,255,255,0.6),|
a$ = a$ + |        inset 0 10px 1px #e5e5e5,|
a$ = a$ + |        inset 0 11px 0 rgba(255,255,255,0.5),|
a$ = a$ + |        inset 0 -45px 3px #ddd;|
a$ = a$ + |}|
a$ = a$ + |.switch label:after {|
a$ = a$ + |    content: "";|
a$ = a$ + |    position: absolute;|
a$ = a$ + |    z-index: -1;|
a$ = a$ + |    top: -20px;|
a$ = a$ + |    left: -25px;|
a$ = a$ + |    bottom: -20px;|
a$ = a$ + |    right: -25px;|
a$ = a$ + |    background: #ccc; /* Fallback */|
a$ = a$ + |    background: linear-gradient(#ddd, #bbb);|
a$ = a$ + |    border-radius: inherit;|
a$ = a$ + |    border: 1px solid #bbb;|
a$ = a$ + |    box-shadow:|
a$ = a$ + |        0 0 5px 1px rgba(0,0,0,0.15),|
a$ = a$ + |        0 3px 3px rgba(0,0,0,0.3),|
a$ = a$ + |        inset 0 1px 0 rgba(255,255,255,0.5);|
a$ = a$ + |}|
a$ = a$ + |.switch label:before {|
a$ = a$ + |    content: "";|
a$ = a$ + |    position: absolute;|
a$ = a$ + |    width: 8px;|
a$ = a$ + |    height: 8px;|
a$ = a$ + |    top: -13px;|
a$ = a$ + |    left: 20px;|
a$ = a$ + |    background: #666;|
a$ = a$ + |    border-radius: 50%;|
a$ = a$ + |    box-shadow:|
a$ = a$ + |        0 1px 0 white, /* Subtle reflection on the bottom of the hole */|
a$ = a$ + |        0 120px 0 #666, /* Faking a second screw hole... */|
a$ = a$ + |        0 121px 0 white; /* And its reflection */|
a$ = a$ + |}|
a$ = a$ + |.switch input:checked ~ label { /* Button */|
a$ = a$ + |    background: #d2cbc3;|
a$ = a$ + |    box-shadow:|
a$ = a$ + |        inset 0 1px 0 white,|
a$ = a$ + |        0 0 0 1px #999,|
a$ = a$ + |        0 0 5px 1px rgba(0,0,0,0.2),|
a$ = a$ + |        inset 0 -10px 0 #aaa,|
a$ = a$ + |        0 2px 0 rgba(255,255,255,0.1),|
a$ = a$ + |        inset 0 45px 3px #e0e0E0,|
a$ = a$ + |        0 8px 6px rgba(0,0,0,0.18);|
a$ = a$ + |}|
a$ = a$ + |</style>|
a$ = a$ + |<body>|
a$ = a$ + |<div class="switch" style="margin-right: auto; margin-left: auto; margin-top:9em;" >|

'a$ = a$ + | <input type="checkbox">|        'disable the original web checkbox component which was set by being ticked
a$ = a$ + checkbox$(stateA)                      'add our Basic checkbox$ replacement component which gets set according to our stateA variable
a$ = a$ + | <label></label>|
a$ = a$ + |</div> |
a$ = a$ + |</body>|
html a$
a$ = ""
wait

change:
print stateA                                       'for debugging purposes
pin(pinA) = stateA                             'set pin according to the checkbox$ state
refresh
return






This next version gives a row of 5 functional switches, each with an illuminated panel indicator...



Basic:
cls
pinA = 12                        'gpio pin assignment for the 5 switches
pinB = 15
pinC = 13
pinD = 16
pinE = 14
indA$ = "Entrance"          'panel indicator
indB$ = "Cabin"           
indC$ = "Galley"
indD$ = "Bathroom"
indE$ = "Bedroom"
indOn$ = "width:47%;height:90%;font-size:20px; margin:auto;border-radius:.3em;text-align:center; background-color:Yellow;color:black;"
indOff$ = "width:47%;height:90%;font-size:20px; border-radius:.3em;text-align:center; background-color:AliceBlue ;color:darkgrey;"
stateA = 1                        'used to specify the switch state according to the checkbox state
stateB = 1
stateC = 1
stateD = 1
stateE = 1
pin.mode pinA, output       'configures the pin for output
pin.mode pinB, output
pin.mode pinC, output
pin.mode pinD, output
pin.mode pinE, output
pin(pinA) = stateA              'sets pin to default state
pin(pinB) = stateB
pin(pinC) = stateC
pin(pinD) = stateD
pin(pinE) = stateE

onHtmlChange change

a$ = ""
a$ = a$ + |<style>|
a$ = a$ + |body {background-color: lightblue;}|
a$ = a$ + |body {background: url("/img/w0.jpg");}|     'Loads a background image if available, else defaults to the above colour
a$ = a$ + |.switch input {|
a$ = a$ + |    position: absolute;|
a$ = a$ + |    width: 100%;|
a$ = a$ + |    height: 100%;|
a$ = a$ + |    z-index: 100;|
a$ = a$ + |    opacity: 0;|
a$ = a$ + |    cursor: pointer;|
a$ = a$ + |}|
a$ = a$ + |.switch {|
a$ = a$ + |    width: 50px;|
a$ = a$ + |    height: 100px;|
a$ = a$ + |    position: relative;|
a$ = a$ + |}|
a$ = a$ + |.switch label {|
a$ = a$ + |    display: block;|
a$ = a$ + |    width: 100%;|
a$ = a$ + |    height: 100%;|
a$ = a$ + |    position: relative;|
a$ = a$ + |    background: #cbc7bc;|
a$ = a$ + |    border-radius: 5px;|
a$ = a$ + |    box-shadow:|
a$ = a$ + |        inset 0 1px 0 white,|
a$ = a$ + |        0 0 0 1px #999,|
a$ = a$ + |        0 0 5px 1px rgba(0,0,0,0.2),|
a$ = a$ + |        0 2px 0 rgba(255,255,255,0.6),|
a$ = a$ + |        inset 0 10px 1px #e5e5e5,|
a$ = a$ + |        inset 0 11px 0 rgba(255,255,255,0.5),|
a$ = a$ + |        inset 0 -45px 3px #ddd;|
a$ = a$ + |}|
a$ = a$ + |.switch label:after {|
a$ = a$ + |    content: "";|
a$ = a$ + |    position: absolute;|
a$ = a$ + |    z-index: -1;|
a$ = a$ + |    top: -20px;|
a$ = a$ + |    left: -25px;|
a$ = a$ + |    bottom: -20px;|
a$ = a$ + |    right: -25px;|
a$ = a$ + |    background: #ccc; /* Fallback */|
a$ = a$ + |    background: linear-gradient(#ddd, #bbb);|
a$ = a$ + |    border-radius: inherit;|
a$ = a$ + |    border: 1px solid #bbb;|
a$ = a$ + |    box-shadow:|
a$ = a$ + |        0 0 5px 1px rgba(0,0,0,0.15),|
a$ = a$ + |        0 3px 3px rgba(0,0,0,0.3),|
a$ = a$ + |        inset 0 1px 0 rgba(255,255,255,0.5);|
a$ = a$ + |}|
a$ = a$ + |.switch label:before {|
a$ = a$ + |    content: "";|
a$ = a$ + |    position: absolute;|
a$ = a$ + |    width: 8px;|
a$ = a$ + |    height: 8px;|
a$ = a$ + |    top: -13px;|
a$ = a$ + |    left: 20px;|
a$ = a$ + |    background: #666;|
a$ = a$ + |    border-radius: 50%;|
a$ = a$ + |    box-shadow:|
a$ = a$ + |        0 1px 0 white, /* Subtle reflection on the bottom of the hole */|
a$ = a$ + |        0 120px 0 #666, /* Faking a second screw hole... */|
a$ = a$ + |        0 121px 0 white; /* And its reflection */|
a$ = a$ + |}|
a$ = a$ + |.switch input:checked ~ label { /* Button */|
a$ = a$ + |    background: #d2cbc3;|
a$ = a$ + |    box-shadow:|
a$ = a$ + |        inset 0 1px 0 white,|
a$ = a$ + |        0 0 0 1px #999,|
a$ = a$ + |        0 0 5px 1px rgba(0,0,0,0.2),|
a$ = a$ + |        inset 0 -10px 0 #aaa,|
a$ = a$ + |        0 2px 0 rgba(255,255,255,0.1),|
a$ = a$ + |        inset 0 45px 3px #e0e0E0,|
a$ = a$ + |        0 8px 6px rgba(0,0,0,0.18);|
a$ = a$ + |}|
a$ = a$ + |</style>|

a$ = a$ + |<body>|
a$ = a$ + |<br><br><br><br><br>|

a$ = a$ + |<table align="center" height="170"><tr align="center" style="text-align:center;">|

a$ = a$ + |<td>| + textbox$(indA$, "indA") + |</td>|
a$ = a$ + |<td>| + textbox$(indB$, "indB") + |</td>|
a$ = a$ + |<td>| + textbox$(indC$, "indC") + |</td>|
a$ = a$ + |<td>| + textbox$(indD$, "indD") + |</td>|
a$ = a$ + |<td>| + textbox$(indE$, "indE") + |</td>|
a$ = a$ + cssid$("indA", indOff$)
a$ = a$ + cssid$("indB", indOff$)
a$ = a$ + cssid$("indC", indOff$)
a$ = a$ + cssid$("indD", indOff$)
a$ = a$ + cssid$("indE", indOff$)
a$ = a$ + |</tr>|

a$ = a$ + |<tr><td colspan=4 ><br> </td></tr><tr>|

a$ = a$ + |<td><div class="switch" style="padding-left:30px; padding-right:30px;margin:auto;">|
a$ = a$ + checkbox$(stateA)
a$ = a$ + |<label><br><br><br><br><br><br><br>|
a$ = a$ + |</label></div></td>|

a$ = a$ + |<td><div class="switch" style="padding-left:30px; padding-right:30px;margin:auto;">|
a$ = a$ + checkbox$(stateB)
a$ = a$ + |<label><br><br><br><br><br><br><br>|
a$ = a$ + |</label></div></td>|

a$ = a$ + |<td><div class="switch" style="padding-left:30px; padding-right:30px;margin:auto;">|
a$ = a$ + checkbox$(stateC)
a$ = a$ + |<label><br><br><br><br><br><br><br>|
a$ = a$ + |</label></div></td> |

a$ = a$ + |<td><div class="switch" style="padding-left:30px; padding-right:30px;margin:auto;">|
a$ = a$ + checkbox$(stateD)
a$ = a$ + |<label><br><br><br><br><br><br><br>|
a$ = a$ + |</label></div></td>|

a$ = a$ + |<td><div class="switch" style="padding-left:30px; padding-right:30px;margin:auto;">|
a$ = a$ + checkbox$(stateE)
a$ = a$ + |<label><br><br><br><br><br><br><br>|
a$ = a$ + |</label></div></td>|

a$ = a$ + |</tr></table>|
a$ = a$ + |</body>|
html a$
a$ = ""
wait

change:
print stateA, stateB, stateC, stateD
pin(pinA) = stateA
pin(pinB) = stateB
pin(pinC) = stateC
pin(pinD) = stateD
pin(pinE) = stateE
if stateA <> 0 then css cssid$("indA", indOff$) else css cssid$("indA", indOn$)
if stateB <> 0 then css cssid$("indB", indOff$) else css cssid$("indB", indOn$)
if stateC <> 0 then css cssid$("indC", indOff$) else css cssid$("indC", indOn$)
if stateD <> 0 then css cssid$("indD", indOff$) else css cssid$("indD", indOn$)
if stateE <> 0 then css cssid$("indE", indOff$) else css cssid$("indE", indOn$)
refresh
return

'------------- End -----------------



NOTE:  Backgrounds
There is a line in the script which will load a background image if it is available, else it will default to the colour specified in the line before it:
Here is the same line prefixed with HTML and wrapped in style tags to make it easier to include in other scripts:
HTML  |<style>body {background: url("/img/w0.jpg");}</style>|   

The above code will tile a smaller image to fill the screen, as shown in the bottom 3 wood panel screenshots.
If you wish the image to be enlarged so the shortest side fits the screen as below, insert no-repeat center fixed; background-size: cover as shown:
HTML  |<style>body {background: url("/img/imagefilename.jpg")  no-repeat center fixed; background-size: cover  ;}</style>|

Look at the following screenshot, and pause to consider just how amazing is Annex-Wifi Basic - that it can give 5 realistic functional switches to actually control equipment, with corresponding back-lit panel indicators, all mounted on a photo-realistic oak panel... and all running on a tiny ESP8266. It is certainly not a toy, but nor is it a super-computer, so treat it with sympathy rather than take it fore-granted. Background images can add 'wow' factor, but they take up memory and take time to load, so use common-sense rather than big extravagant hi-res images. If you have any out of memory type messages you can offer the system an opportunity to function at it's best by rebooting the device, opening the script from fresh, and displaying in a new Output window.
 
You can find all 4 of the background images used below attached at the bottom of this page - upload them into the /img/ folder of the device.
Any other projects showing a background screenshot will include the image at the page bottom and would have temporarily used the above code.

a$ = a$ + |body {background: url("/img/w11.jpg") no-repeat center fixed; background-size: cover ;}|


a$ = a$ + |body {background: url("/img/w0.jpg");}|


a$ = a$ + |body {background: url("/img/w2.jpg");}|


a$ = a$ + |body {background: url("/img/w3.jpg");}|

All these free backgrounds were downloaded from:  https://pixabay.com/

FEATURE: The firmware has the ability to load a compressed .gz version of a file, as explained here by Ciccio...
...you should refer to the gz file with its regular name, omitting the final .gz.
Example: if the original file is named picture.jpg the compressed gz version should be namedpicture.jpg.gz  BUT  it must always be called in the program using its original name without the .gz extension.
If the original file is present it will be loaded, but if the original filename is not found then the server will automatically try to send the corresponding compressed .gz version ... so in practice you can
replace any file with the correspondeing compressed .gz version without any change in the code.

TIP:  Search for "7-zip portable" for a free archive utility which does not need to be installed and can even be run from a USB flash drive.






w0.jpg
(59k)
Margaret Baker,
Dec 23, 2017, 4:19 PM
v.1
w11.jpg
(30k)
Margaret Baker,
Dec 29, 2017, 12:13 PM
v.1
w2.jpg
(16k)
Margaret Baker,
Dec 23, 2017, 4:00 PM
v.1
w3.jpg
(12k)
Margaret Baker,
Dec 23, 2017, 4:01 PM
v.1