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

Manipulate the viewbox

bartbutenaers edited this page Dec 6, 2020 · 1 revision

The SVG element has a viewbox attribute (with value ) which defines which part of the SVG drawing needs to be displayed in the viewport. The viewport defines how much you can see on your screen, via the width and height attributes of the SVG element.

For example:

<svg x="0" y="0" width="100" height="100" viewBox="0 0 50 50">
  ...
</svg>

Some remarks:

  • The x and y attributes are only used when this SVG is nested into another SVG.
  • A width/height value of "100" means "100px", which means that our SVG will be displayed as 100px x 100px.
  • The viewbox indicates that a smaller area of the drawing will be zoomed to be displayed in the available 100px x 100px.

By manipulating the viewbox, it is possible e.g. to pan and zoom the drawing. See the demo below, where the viewbox dimensions will be displayed in the function node's status text:

svg viewbox demo

[{"id":"c30ba0d2.944f5","type":"ui_svg_graphics","z":"42b7b639.325dd8","group":"9f79dbed.57aad8","order":1,"width":"5","height":"5","svgString":"<svg id=\"my_svg\" width=\"200\" height=\"200\">\n  <ellipse cx=\"100\" cy=\"100\" rx=\"20\" ry=\"20\"></ellipse>\n</svg>","clickableShapes":[],"javascriptHandlers":[],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":false,"showBrowserEvents":false,"enableJsDebugging":false,"sendMsgWhenLoaded":false,"outputField":"","editorUrl":"http://drawsvg.org/drawsvg.html","directory":"","panning":"disabled","zooming":"enabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":true,"mouseWheelZoomEnabled":false,"name":"","x":720,"y":1220,"wires":[[]]},{"id":"efa982c7.dfa0b","type":"inject","z":"42b7b639.325dd8","name":"Right","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"right","payloadType":"str","x":270,"y":1340,"wires":[["59cf5ca9.21d7e4"]]},{"id":"8fba0775.167218","type":"inject","z":"42b7b639.325dd8","name":"Zoom in","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"zoom_in","payloadType":"str","x":270,"y":1380,"wires":[["59cf5ca9.21d7e4"]]},{"id":"be5bacc0.05272","type":"inject","z":"42b7b639.325dd8","name":"Zoom out","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"zoom_out","payloadType":"str","x":280,"y":1420,"wires":[["59cf5ca9.21d7e4"]]},{"id":"5c162723.a82398","type":"inject","z":"42b7b639.325dd8","name":"Left","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"left","payloadType":"str","x":270,"y":1300,"wires":[["59cf5ca9.21d7e4"]]},{"id":"30b30e0d.8cdde2","type":"inject","z":"42b7b639.325dd8","name":"Down","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"down","payloadType":"str","x":270,"y":1260,"wires":[["59cf5ca9.21d7e4"]]},{"id":"14f1686a.480fe8","type":"inject","z":"42b7b639.325dd8","name":"Up","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"up","payloadType":"str","x":270,"y":1220,"wires":[["59cf5ca9.21d7e4"]]},{"id":"59cf5ca9.21d7e4","type":"function","z":"42b7b639.325dd8","name":"Calculate viewbox","func":"// Get the previous viewbox settings from context memory\nvar x = context.get(\"viewbox_x\") || 0;\nvar y = context.get(\"viewbox_y\") || 0;\nvar width = context.get(\"viewbox_width\") || 200;\nvar height = context.get(\"viewbox_height\") || 200;\n\n// Manipulate the viewbox dimensions, based on the command in the msg.payload\nswitch(msg.payload) {\n    case \"right\":\n        // By moving the viewbox to the left, the drawing seems to go to the right\n        x -= 10;        \n        break;\n    case \"left\":\n        // By moving the viewbox to the right, the drawing seems to go to the left\n        x += 10;\n        break;\n    case \"down\":\n        // By moving the viewbox up, the drawing seems to go down\n        y -= 10;\n        break;\n    case \"up\":\n        // By moving the viewbox down, the drawing seems to go up\n        y += 10;        \n        break;\n    case \"zoom_in\":\n        // By making the viewbox larger, the drawing seems to become smaller\n        width -= 10;\n        height -= 10;\n        // Make sure the drawing doesn't move to the lower right corner\n        x += 5;\n        y += 5;\n        break;\n    case \"zoom_out\":\n        // By making the viewbox smaller, the drawing seems to become larger\n        width += 10;\n        height += 10; \n        // Make sure the drawing doesn't move to the upper left corner\n        x -= 5;\n        y -= 5;\n        break;\n    default:\n        console.log(\"Unsupported viewbox command\");\n}\n\n// Store the new viewbox dimensions on context memory\ncontext.set(\"viewbox_x\", x);\ncontext.set(\"viewbox_y\", y);\ncontext.set(\"viewbox_width\", width);\ncontext.set(\"viewbox_height\", height);\n\n// Show the viewbox in the node status\nvar viewbox = x + \" \" + y + \" \" + width + \" \" + height;\nnode.status({fill:\"green\", shape:\"dot\", text:\"viewbox: \" + viewbox});\n\n// Send a command to the SVG node, to update the viewbox dimensions\nmsg.payload = {\n     \"command\": \"set_attribute\",\n     \"selector\": \"#my_svg\", \n     \"attributeName\": \"viewBox\",\n     \"attributeValue\": viewbox\n  } \n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":510,"y":1220,"wires":[["c30ba0d2.944f5"]]},{"id":"9f79dbed.57aad8","type":"ui_group","z":"","name":"Viewbox demo","tab":"d81e78f0.ebcac8","order":2,"disp":true,"width":"5","collapse":false},{"id":"d81e78f0.ebcac8","type":"ui_tab","z":"42b7b639.325dd8","name":"Home","icon":"home","order":1,"disabled":false,"hidden":false}]

Note that all viewbox manipulations need to be the inverse of what you want to achieve! For example when you want to move the drawing to the left, you need to move the viewbox to the right ...

⚠️ Don't confuse this viewbox panning/zooming with the CSS panning/zooming (which can be enabled in the "Settings" tabsheet)!