Questions on node-red-contrib-ui-svg

Hi @smcgann99,

I have implemented some changes on Github (not on NPM yet). This version can be installed when being inside the .node-red folder:

npm install bartbutenaers/node-red-contrib-ui-svg
  • A new section about reset-panzoom-via-msg has been added to the readme page.

  • The double click bug should be fixed. That was a tough one to debug :nauseated_face:. Note that I have change the behaviour a bit when using a mouse: first doubleclick is zoom-in, second doubleclick is zoom-out, and so on... Previously the behaviour was: zoom in on every double click, and zoom-out on every shift-double click.

    Reason: then the double mouse click behaviour is identical to the double tap behaviour (on a touch screen)....

  • It is indeed possible to manipulate the viewbox. Here is a demo that demonstrates how to implement panning/zooming via the viewport (see the viewbox dimensions in the status of the function node!):

    [{"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 ...

    P.S. Don't confuse this viewbox panning/zooming with the CSS panning/zooming (which can be enabled in the "Settings" tabsheet).