Fill a shape with a pattern (to create shutter effect) - bartbutenaers/node-red-contrib-ui-svg GitHub Wiki
SVG offers patterns, which are shapes that will be repeated in X and y directions. Such patterns can be used to fill the area of other shapes.
We will show the steps to display a roller shutter for a house:
-
A typical roller shuttor consists out of long narrow rectangles, which are repeated a number of times:
-
One way to simulate such an effect, is by creating a pattern that consists out of a lightgrey rectangle followed by a black line:
<defs> <pattern id="shutter_pattern" width="6" height="6" patternUnits="userSpaceOnUse"> <rect x="0" y="0" width="6" height="6" fill="lightgrey" stroke="none"/> <line x1="0" y1="2" x2="6" y2="2" stroke="black" stroke-width="2"/> </pattern> </defs>
This pattern has very small dimensions (i.e. 6 x 6), but can be repeated by the browser in both X and Y directions.
-
We can now draw a rectangle that represents the window itself:
<rect id="imagebackground" x="0" y="0" width="50" height="80" stroke="none" fill="url(#shutter_pattern)"/>
The pattern is applied to the window rectangle, by specifying the pattern id via a fill url.
-
The browser will repeat the pattern in both directions to fill the entire window rectangle, resulting in a closed roller shutter:
As shown above, the browser will fill the entire window rectangle. However most of the time the roller shutter will be open completely or partially. I didn't find a simple way to achieve this, so we will solve this by using two separate rectangles:
-
Use the same pattern as in the above example.
-
Create two separate rectangles:
<rect x="0" y="0" width="50" height="80" stroke="none" fill="white"/> <rect x="0" y="0" width="50" height="40" stroke="none" fill="url(#shutter_pattern)" id="roller_shutter"/>
We draw a large white rectangle that represents the entire window. On top of that we draw a rectangle of half the height, which gets the roller shutter pattern.
-
This will result in the roller shutter being half open:
-
Since the roller shutter rectangle has an id (i.e. "roller_shutter"), we can inject a message to change the rectangle height:
payload = { command: "set_attribute", selector: "#roller_shutter", attributeName: "height", attributeValue: msg.payload }
The following example flow shows how this works:
[{"id":"98d8ef2e2cd646d7","type":"ui_svg_graphics","z":"8fee6c7e9e28fe94","group":"f014eb03.a3c618","order":1,"width":"14","height":"10","svgString":"<svg version=\"1.1\" id=\"Capa_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" width=\"100%\" height=\"100%\" viewBox=\"0 0 463 463\" style=\"enable-background:new 0 0 463 463;\" xml:space=\"preserve\">\n <defs>\n <pattern id=\"shutter_pattern\" width=\"6\" height=\"6\" patternUnits=\"userSpaceOnUse\">\n <rect x=\"0\" y=\"0\" width=\"6\" height=\"6\" fill=\"lightgrey\" stroke=\"none\" />\n <line x1=\"0\" y1=\"2\" x2=\"6\" y2=\"2\" stroke=\"black\" stroke-width=\"2\" />\n </pattern>\n </defs>\n <rect x=\"0\" y=\"0\" width=\"50\" height=\"80\" stroke=\"none\" fill=\"white\" />\n <rect x=\"0\" y=\"0\" width=\"50\" height=\"40\" stroke=\"none\" fill=\"url(#shutter_pattern)\" id=\"roller_shutter\"/>\n</svg>","clickableShapes":[{"targetId":"#temp_living","action":"change","payload":"temperature_living","payloadType":"str","topic":"temperature_living"}],"javascriptHandlers":[{"selector":"#temp_living","action":"change","sourceCode":"if(evt.target.valueAsNumber < 10) {\n $(\"#temp_living_label\")[0].style.color=\"blue\";\n}\nelse if(evt.target.valueAsNumber > 20) {\n $(\"#temp_living_label\")[0].style.color=\"red\";\n}\nelse {\n $(\"#temp_living_label\")[0].style.color=\"orange\";\n}"}],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":true,"showBrowserEvents":true,"enableJsDebugging":true,"sendMsgWhenLoaded":false,"noClickWhenDblClick":false,"outputField":"","editorUrl":"http://drawsvg.org/drawsvg.html","directory":"","panning":"disabled","zooming":"disabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"dblClickZoomPercentage":"150","cssString":"div.ui-svg svg{\n color: var(--nr-dashboard-widgetColor);\n fill: currentColor !important;\n}\ndiv.ui-svg path {\n fill: inherit;\n}","name":"","x":720,"y":320,"wires":[[]]},{"id":"3b736443b32a9749","type":"inject","z":"8fee6c7e9e28fe94","name":"Value 0","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"0","payloadType":"num","x":250,"y":320,"wires":[["b2ae01c2ad154562"]]},{"id":"b2ae01c2ad154562","type":"function","z":"8fee6c7e9e28fe94","name":"Change rectangle height","func":"msg.payload = {\n command: \"set_attribute\",\n selector: \"#roller_shutter\",\n attributeName: \"height\",\n attributeValue: msg.payload\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":320,"wires":[["98d8ef2e2cd646d7"]]},{"id":"2b9ecbd548389816","type":"inject","z":"8fee6c7e9e28fe94","name":"Value 20","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"20","payloadType":"num","x":260,"y":360,"wires":[["b2ae01c2ad154562"]]},{"id":"41b7ebbd718019ab","type":"inject","z":"8fee6c7e9e28fe94","name":"Value 40","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"40","payloadType":"num","x":260,"y":400,"wires":[["b2ae01c2ad154562"]]},{"id":"aea6bf6a34253e3c","type":"inject","z":"8fee6c7e9e28fe94","name":"Value 60","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"60","payloadType":"num","x":260,"y":440,"wires":[["b2ae01c2ad154562"]]},{"id":"54e2adbe3704e9c3","type":"inject","z":"8fee6c7e9e28fe94","name":"Value 80","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"80","payloadType":"num","x":260,"y":480,"wires":[["b2ae01c2ad154562"]]},{"id":"f014eb03.a3c618","type":"ui_group","name":"Pattern fill demo","tab":"80068970.6e2868","order":1,"disp":true,"width":"18","collapse":false,"className":""},{"id":"80068970.6e2868","type":"ui_tab","name":"SVG","icon":"dashboard","order":14,"disabled":false,"hidden":false}]
Which works like this: