Having fun with SVG - playing with light sources

Hi folks,

A HAPPY NEW YEAR to the entire community!! :champagne: :champagne: :champagne:

While the wife and kids were still sleeping, I sneaked downstairs to experiment with light sources in SVG. Not sure whether this is called dedication, or just me being pathetic :rofl:

With this simple flow:

image

[{"id":"4a7aaca8.bd6084","type":"ui_svg_graphics","z":"7f1827bd.8acfe8","group":"7185c2fb.c66bbc","order":0,"width":"12","height":"12","svgString":"<div class=\"contain-demo\">  \n  <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 250 250\" enable-background=\"new 0 0 250 250\">\n    <defs>\n      <!--The default filter region is x=-10% y=-10% width=120% height=120%-->\n      <!--Which need to be shrinked to clip the filter at the room boundaries-->\n      <filter id=\"green_light\" x=\"0%\" y=\"0%\" width=\"100%\" height=\"100%\">\n        <feGaussianBlur in = \"SourceAlpha\" stdDeviation=\"1\" result=\"blur1\" />\n        <feSpecularLighting result=\"specOut\" in=\"blur1\" specularExponent=\"30\"  lighting-color=\"#00cc00\" >\n            <fePointLight x=\"141\" y=\"73\" z=\"80\" />\n        </feSpecularLighting>\n      </filter>\n    </defs>\n    \n    <image width=\"100%\" height=\"100%\" id=\"background\" xlink:href=\"https://www.roomsketcher.com/wp-content/uploads/2016/10/1-Bedroom-Floor-Plans.jpg\" />\n\n    <rect id=\"rect_living\" x=\"80\" y=\"30\" width=\"123\" height=\"86\" fill=\"black\" fill-opacity=\"0.1\" filter=\"\"/>\n    <text id=\"light_living\" x=\"141\" y=\"73\" font-family=\"FontAwesome\" fill=\"green\" stroke=\"darkgreen\" font-size=\"25\" text-anchor=\"middle\" alignment-baseline=\"middle\" stroke-width=\"1\">fa-lightbulb-o</text>\n  </svg>\n</div>","clickableShapes":[{"targetId":"#light_living","action":"click","payload":"light_living","payloadType":"str","topic":"light_living"}],"javascriptHandlers":[],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":true,"showBrowserEvents":false,"enableJsDebugging":false,"sendMsgWhenLoaded":false,"outputField":"payload","editorUrl":"//drawsvg.org/drawsvg.html","directory":"","panning":"disabled","zooming":"disabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"dblClickZoomPercentage":150,"name":"","x":680,"y":2400,"wires":[["e4f8bd1d.95b4a"]]},{"id":"e4f8bd1d.95b4a","type":"link out","z":"7f1827bd.8acfe8","name":"SVG output msg","links":["b5e846dd.ae7e88"],"x":815,"y":2400,"wires":[]},{"id":"b5e846dd.ae7e88","type":"link in","z":"7f1827bd.8acfe8","name":"","links":["e4f8bd1d.95b4a"],"x":95,"y":2400,"wires":[["9327a30d.6d2f2"]]},{"id":"6000cdf2.42d564","type":"change","z":"7f1827bd.8acfe8","name":"Update filter attribute","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t\"command\": \"set_attribute\",\t\"selector\": \"#rect_living\",\t\"attributeName\": \"filter\",\t\"attributeValue\": payload\t}   ","tot":"jsonata"},{"t":"delete","p":"topic","pt":"msg"},{"t":"delete","p":"event","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":2400,"wires":[["4a7aaca8.bd6084"]]},{"id":"9327a30d.6d2f2","type":"function","z":"7f1827bd.8acfe8","name":"Toggle light state","func":"if (msg.topic === \"light_living\") {\n    var state = flow.get(\"state_light\");\n    \n    node.error(\"old state = \" + state );\n    \n    if (state === \"ON\") {\n        state = \"OFF\";\n        msg.payload = \"\";\n    }\n    else {\n        state = \"ON\";\n        msg.payload = \"url(#green_light)\";\n    }\n    \n    node.error(\"new state = \" + state );\n    \n    flow.set(\"state_light\", state);\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":230,"y":2400,"wires":[["6000cdf2.42d564"]]},{"id":"7185c2fb.c66bbc","type":"ui_group","z":"","name":"SVG light demo","tab":"35f53152.449cde","order":2,"disp":true,"width":"12","collapse":false},{"id":"35f53152.449cde","type":"ui_tab","z":"","name":"Lights","icon":"dashboard","disabled":false,"hidden":false}]

I can show visually which light is ON on my floorplan. I this demo I have used a green LED light:

svg_light_demo

I'm not an SVG expert at all, but would like to spread some basic ideas of the SVG possibilities...
If anybody has a better implementation, please share it with us!!!

In SVG you can define a light source element of different types:

  • feDistantLight defines a distant light source, similar to how the sun lights everything during the day.
  • fePointLight defines a light source that radiates from a single point, similar to how a light bulb lights a room.
  • feSpotLight defines a light source similar to a spot light that shines intensely over a small area.

So I think that for my home automation the fePointLight seems to be the best match to simulate a light bulb.

Then we need to create a filter chain, where the result of a filter will be the input of the next filter.
This is my chain after a bit of trial and error:

<filter id="green_light" x="0%" y="0%" width="100%" height="100%">
   <feGaussianBlur in = "SourceAlpha" stdDeviation="1" result="blur1" />
      <feSpecularLighting result="specOut" in="blur1" specularExponent="30"  lighting-color="#00cc00" >
         <fePointLight x="141" y="73" z="80" />
      </feSpecularLighting>
   </filter>
</defs>

Some details about this:

  • I positioned the light in the middle of my room. Don't know if I can make this relative to the room, because now it is relative to the origin of the SVG, which causes the definition not being reusable for my other rooms...

  • I used feSpecularLighting to apply a colour to my light. In this case I have specified GREEN ("#00cc00").

  • The feGaussianBlur applies some blur.

  • It is important to specify a filter region (x="0%" y="0%" width="100%" height="100%") because the default region (x="-10%" y="-10%" width="120%" height="120%") would cause the filter to be applied also around our room (rectangle):

    image

Since the demo floorplan is a simple image of a floorplan, the light would shine across multiple rooms (not taking into account the walls). To solve that we draw a rectangle above the room contour, and apply the light filter only to that rectangle:

<image width="100%" height="100%" id="background" xlink:href="https://www.roomsketcher.com/wp-content/uploads/2016/10/1-Bedroom-Floor-Plans.jpg" />
<rect id="rect_living" x="80" y="30" width="123" height="86" fill="black" fill-opacity="0.1" filter=""/>

Some details about this:

  • By default I apply an empty filter (i.e. no filter) to this rectangle, because the light is OFF when we start.
  • I set the color to black and opacity to 0.1 to make the room a bit darker (since the light is off by default):

And then in the flow I apply the filter to the rectangle when the light bulb is being clicked.

I hope you like it,
Bart

10 Likes

Happy new year Bart. You literally bring the light to us in these dark times. :grinning: Thanks

3 Likes

Yes, I also make the world again a bit greener :wink:

BTW you can play with the specularExponent to adjust the range of the bulb:

3 Likes

Happy New Year to all the people that hang-out on the Forum.

Bart, there seems to be no limit to your creativity???

Thanks for all your contributions - I'm looking forward to seeing what else you "invent" in 2021.

1 Like

Oh yes, there is: a time limit ...

2 Likes

Bart

Thanks for all your dedication and hard work, it is difficult to keep up with your innovation :grinning:

2 Likes

In my own experiments for Vue/uibuilder, I think that I just stuck with a simple blur around the icon image. This does appear to be going above and beyond the call of duty!

Good stuff though. Just don't let your wife catch you playing with this SVG "p*rn" :rofl:

1 Like

Happy New Year everyone!

Bart, you never cease to amaze me with your ideas and the encouragement of others, including myself. Thank you!!

1 Like

Got a private message of somebody wondering whether it is possible to adjust the "brightness" of the light. From the SVG docs I assume this should be done by adding the following filter to the chain (like e.g. in this tutorial), which plays with the R,G,B channels:

<feComponentTransfer id="brightness" in="specOut">
   <feFuncR type="linear" slope="2"/>
   <feFuncG type="linear" slope="2"/>
   <feFuncB type="linear" slope="2"/>
</feComponentTransfer>

However I don't see any difference :roll_eyes:
Like I said above, I'm not an SVG expert, so most probably I did something wrong ...

Anyway I found somewhere else that it is also possbile to play with the specularConstant, so I added that to my existing filter:

<feSpecularLighting result="specOut" in="blur1" specularConstant="2" specularExponent="50"  lighting-color="#00cc00" >

By default the value is 1, but below you can see the result for some different values:

If anybody can improve this, please be my guest!!!

4 Likes

You did a good job, and I thank you for that. This was just what I needed for my project.

1 Like

@Zipular,
You are welcome! Nice to hear that my experiments have been useful for you.
BTW I have now added this now as a new tutorial to the wiki, to have it nicely together with all other tutorials.
Bart

I'm using your node and example to make a visual representation of room temperatures. the problem i'm having is with the preview of the SvG file
I attached two pictures.
The good one is from a SVG viewer and the vierd one is the same file but on the dashboard, displayed with your node


Hi @TadyTheFish,
Do you see any errors in your browser console log?
Or any other useful information perhaps?
By looking at that image, nobody will be able to determine what is going wrong...

@TadyTheFish What did you use to draw the image ?

I use Inkscape, it's a bit of a learning curve but very good and works with SVG natively.

Try opening your file with that and see if anything needs changing, then re-save

I used and online software called planningWizz. I will try to import with inkscape

Yeah something is fishy with this export. I opened the SVG with inkscape and it had wall dimensions that don't show up in Nodered or SVG viewer. I removed the dimensions but the result is still the same. Can anyone else try out my file?

snapshot_2-11-2022.pdf (54.5 KB)

JUST RENAME PDF TO SVG! I had to change because this formu does not allow SVG extensions to be uploaded

It is quite difficult to have a look at your svg, because that planningWizz tool seems to have generate LOTs of stuff.

When I do right-click in Chrome on your floorplan, and I choose "inspect" in the popup menu then I see this:

Is that "dropshadow" the filter for your light source?
Otherwise you will need to give some more pointers to guide us in your svg source.

I really have no idea for what is that used :slight_smile: I will try to remove most of the junk :slight_smile:

1 Like

I used an iine software to draw and then export the svg of the plan. I never played around with svd files so I really don't know things are done. I deleted most of tge junk out of the image with inkscape but still the view in nodered is wierd. Those doors and windows are much thicker in nodered than it it in inkscape or any other viewer😁

This is how your svg looks in my Node-RED dashboard:

Of course you have not shared anything of your flow, so I have no clue what you do with your drawing (e.g. injecting messages) to get it like that...