Skip to content
This repository has been archived by the owner on Aug 10, 2024. It is now read-only.

Create electronic switch (by toggling the visibility of two separate groups)

bartbutenaers edited this page Dec 29, 2021 · 1 revision

This tutorial explains how to implement a switch, by toggling the visibility of two SVG groups. One group contains the shapes for switch ON, and the other group contains the shapes for switch OFF:

<svg ...viewBox="0 0 100 100" ...">
   ...
  <g id="switch_off">
        <g id="shadow_off">
   </g>
  <g id="switch_on">
        <g id="shadow_on">
   </g>
</svg>

Now we only have to set the visibility (style) attribute of those groups (with id "switch__on" or "switch_off") to "visible" or "hidden". Which means that only one of the two groups will be displayed at any time.

By default we set the "switch_on" group as hidden, so the switch will be OFF by default:

<g id="switch_on" visibility="hidden">

Only when the "dark blue" area of the switch is clicked, an output message should be send (to inform the server that the button has been clicked). Which means that only on this dark-blue area of the switch, the mouse cursor needs to get a 'hand' shape:

demo_button_hand

Such an effect can be achieved, by adding a standard click event handler to the both "dark" element id:

image

As soon as the button is clicked with the mouse, the button will need to get another look (to show visually the button going down). That can be achieved by toggling the visibility of both groups, which can be implemented in two ways:

  • Use a normal click event handler, which results in an output message (containing the new switch state) in the flow on the server. That message needs to be converted, and injected as an input message that changes the visibility of both groups. However this would require an entire roundtrip to the server and back to your dashboard, which will be slow and feel very inresponsive.

  • Use a JS event click handler, that toggles the visibility of both groups in a client side Javascript:

    image

    This way the click event will immediately result in a visual switch change.

Below you can find the complete example flow. Note that both Inject nodes are optional. I only added them to demonstrate how to inject a message to change the state:

image

[{"id":"46e1a56491a6574c","type":"ui_svg_graphics","z":"dd961d75822d1f62","group":"5286eab45a5fb268","order":6,"width":7,"height":2,"svgString":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" id=\"Layer_1\" x=\"0px\" y=\"0px\" viewBox=\"0 0 100 100\" xml:space=\"preserve\" width=\"100%\" height=\"100%\" preserveAspectRatio=\"xMidYMid meet\">\n  <rect id=\"svgEditorBackground\" x=\"0\" y=\"0\" width=\"100\" height=\"100\" style=\"fill:none; stroke: none;\" />\n  <desc>Copyright Opto 22</desc>\n  <defs id=\"svgEditorDefs\">\n    <style type=\"text/css\">\n      #state_switch{fill:black;font-family:Georgia;font-size:12.999988084915614px;}\n    </style>\n  </defs>\n  <g id=\"switch_off\">\n    <g id=\"shape_off\">\n      <rect x=\"1\" y=\"20.664\" fill=\"#009cff\" width=\"98\" height=\"58.173\" />\n    </g>\n    <g id=\"shadow_off\">\n      <rect x=\"5.092\" y=\"24.892\" fill=\"#003e66\" width=\"89.816\" height=\"49.716\" />\n      <polygon opacity=\"0.5\" fill=\"#003e66\" enable-background=\"new    \" points=\"94.908,74.608 5.092,74.608 1,78.836 99,78.836   \" />\n    </g>\n    <g id=\"dark_off\">\n      <polygon fill=\"#0071ba\" points=\"79.564,22.3 79.564,70.811 48.875,72.835 48.875,26.188   \" />\n      <polygon fill=\"#0071ba\" points=\"79.564,70.811 91.839,72.835 91.839,26.188 79.564,22.3   \" />\n    </g>\n    <g id=\"light_off\">\n      <rect x=\"7.956\" y=\"26.188\" fill=\"#3bbeff\" stroke=\"#000000\" stroke-miterlimit=\"10\" width=\"40.919\" height=\"46.647\" />\n    </g>\n    <g id=\"hlight_off\">\n      <path fill=\"#a3daff\" d=\"M79.473,70.311h-1V23.367L49.146,27.09l-0.126,-0.992l29.89,-3.794c0.143,-0.016,0.285,0.026,0.393,0.121c0.108,0.095,0.17,0.231,0.17,0.375V70.311Z\" />\n      <rect x=\"63.675\" y=\"56.192\" transform=\"matrix(0.0646 0.9979 -0.9979 0.0646 130.9192 2.8788)\" fill=\"#a3daff\" width=\"0.499\" height=\"30.159\" />\n      <rect x=\"46.374\" y=\"29.461\" fill=\"#a3daff\" width=\"0.5\" height=\"39.282\" />\n      <rect x=\"10.161\" y=\"29.461\" fill=\"#a3daff\" width=\"0.5\" height=\"39.282\" />\n      <rect x=\"12.866\" y=\"70.13\" fill=\"#a3daff\" width=\"31.303\" height=\"0.5\" />\n      <rect x=\"12.866\" y=\"28.393\" fill=\"#a3daff\" width=\"31.303\" height=\"0.5\" />\n    </g>\n  </g>\n  <g id=\"switch_on\" visibility=\"hidden\">\n    <g id=\"shape_on\">\n      <rect x=\"1\" y=\"20.664\" fill=\"#009cff\" width=\"98\" height=\"58.173\" />\n    </g>\n    <g id=\"shadow_on\">\n      <rect x=\"5.092\" y=\"24.892\" fill=\"#003e66\" width=\"89.816\" height=\"49.716\" />\n      <polygon opacity=\"0.5\" fill=\"#003e66\" enable-background=\"new    \" points=\"94.908,74.608 5.092,74.608 1,78.836 99,78.836   \" />\n    </g>\n    <g id=\"dark_on\">\n      <polygon fill=\"#0071ba\" points=\"20.436,71.13 20.436,21.209 51.125,26.529 51.125,73.176   \" />\n      <polygon fill=\"#0071ba\" points=\"20.436,21.209 8.161,26.529 8.161,73.176 20.436,71.13   \" />\n    </g>\n    <g id=\"light_on\">\n      <rect x=\"51.125\" y=\"26.529\" fill=\"#3bbeff\" stroke=\"#000000\" stroke-miterlimit=\"10\" width=\"40.919\" height=\"46.647\" />\n    </g>\n    <g id=\"hlight_on\">\n      <polygon fill=\"#a3daff\" points=\"20.118,70.107 19.118,70.107 19.118,22.873 8.957,27.496 8.543,26.586 20.118,21.319   \" />\n      <rect x=\"14.264\" y=\"66.284\" transform=\"matrix(0.1638 0.9865 -0.9865 0.1638 82.6304 45.4365)\" fill=\"#a3daff\" width=\"0.501\" height=\"10.348\" />\n      <rect x=\"53.126\" y=\"30.621\" fill=\"#a3daff\" width=\"0.5\" height=\"39.281\" />\n      <rect x=\"89.339\" y=\"30.621\" fill=\"#a3daff\" width=\"0.5\" height=\"39.281\" />\n      <rect x=\"55.831\" y=\"28.734\" fill=\"#a3daff\" width=\"31.303\" height=\"0.5\" />\n      <rect x=\"55.831\" y=\"70.471\" fill=\"#a3daff\" width=\"31.303\" height=\"0.5\" />\n    </g>\n  </g>\n  <text x=\"35.6782\" y=\"16.4152\" id=\"state_switch\" />\n</svg>","clickableShapes":[{"targetId":"#dark_on","action":"click","payload":"Switch on","payloadType":"str","topic":"SWITCH_ON"},{"targetId":"#dark_off","action":"click","payload":"Switch off","payloadType":"str","topic":"SWITCH_OFF"}],"javascriptHandlers":[{"selector":"#dark_on","action":"click","sourceCode":"document.getElementById(\"switch_on\").style.visibility = \"hidden\";\ndocument.getElementById(\"switch_off\").style.visibility = \"visible\";"},{"selector":"#dark_off","action":"click","sourceCode":"document.getElementById(\"switch_on\").style.visibility = \"visible\";\ndocument.getElementById(\"switch_off\").style.visibility = \"hidden\";"}],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":false,"showBrowserEvents":false,"enableJsDebugging":true,"sendMsgWhenLoaded":false,"noClickWhenDblClick":false,"outputField":"payload","editorUrl":"//drawsvg.org/drawsvg.html","directory":"","panning":"disabled","zooming":"disabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"dblClickZoomPercentage":150,"name":"ON/OFF switch","x":1800,"y":160,"wires":[["fe79529085bc6afe"]]},{"id":"fe79529085bc6afe","type":"debug","z":"dd961d75822d1f62","name":"Switch state","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1990,"y":160,"wires":[]},{"id":"13804813e4463aad","type":"inject","z":"dd961d75822d1f62","name":"Switch off","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"command\":\"update_style\",\"selector\":\"#switch_off\",\"attributeName\":\"visibility\",\"attributeValue\":\"visible\"},{\"command\":\"update_style\",\"selector\":\"#switch_on\",\"attributeName\":\"visibility\",\"attributeValue\":\"hidden\"}]","payloadType":"json","x":1600,"y":160,"wires":[["46e1a56491a6574c"]]},{"id":"d7c277cef617a78a","type":"inject","z":"dd961d75822d1f62","name":"Switch on","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"command\":\"update_style\",\"selector\":\"#switch_off\",\"attributeName\":\"visibility\",\"attributeValue\":\"hidden\"},{\"command\":\"update_style\",\"selector\":\"#switch_on\",\"attributeName\":\"visibility\",\"attributeValue\":\"visible\"}]","payloadType":"json","x":1600,"y":220,"wires":[["46e1a56491a6574c"]]},{"id":"5286eab45a5fb268","type":"ui_group","name":"Bomba","tab":"8bbab1b47b8e87c8","order":1,"disp":true,"width":14,"collapse":false},{"id":"8bbab1b47b8e87c8","type":"ui_tab","name":"SVG","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

Below you can see the flow in action:

demo_svg_switch