Move an object with SVG - I'm confused

Hi there,

I'm confused by a big amount of tutorials and tipps.
How to move an object with SVG with messages as input?

This is the SVG code of my node:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" height="100%" viewBox="0 0 100 100" width="100%" preserveAspectRatio="xMinYMin meet"><defs id="svgEditorDefs"><symbol xmlns="http://www.w3.org/2000/svg" id="f5de" preserveAspectRatio="xMidYMid meet" viewBox="0 0 480 512"><path d="M438.66 212.33l-11.24-28.1-19.93-49.83C390.38 91.63 349.57 64 303.5 64h-127c-46.06 0-86.88 27.63-103.99 70.4l-19.93 49.83-11.24 28.1C17.22 221.5 0 244.66 0 272v48c0 16.12 6.16 30.67 16 41.93V416c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-32h256v32c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-54.07c9.84-11.25 16-25.8 16-41.93v-48c0-27.34-17.22-50.5-41.34-59.67zm-306.73-54.16c7.29-18.22 24.94-30.17 44.57-30.17h127c19.63 0 37.28 11.95 44.57 30.17L368 208H112l19.93-49.83zM80 319.8c-19.2 0-32-12.76-32-31.9S60.8 256 80 256s48 28.71 48 47.85-28.8 15.95-48 15.95zm320 0c-19.2 0-48 3.19-48-15.95S380.8 256 400 256s32 12.76 32 31.9-12.8 31.9-32 31.9z"/></symbol></defs><rect id="svgEditorBackground" x="0" y="0" width="100" height="100" style="fill:none;stroke:none"/>
<!-- Add here your SVG shapes (circles, rectangles, ...) -->
<!-- Or remove everything, if you want to paste an entire drawing (<svg...>...</svg>).-->
<rect x="0.427" y="0.570" style="fill:#132330;stroke:black;stroke-width:1px" id="e1_rectangle" width="229.629" height="98.7175"/><use xlink:href="#f5de" x="76.781" y="37.607" width="7.479" height="7.977" id="car" style="fill:red" /></svg>

I got the node from node-red-contrib-ui-svg.

i want to move the "car" around by sending a message that sends the x- and y-chords to the node.
How to do that?

Thanks for all help. I'll answer questions if you have some.
Greetings,
beg1nner

@beg1nner,
I am sorry that the documentation wasn't of any help to you, because it took a huge amount of free time to write it...

The payload of your input message simply needs to be an array of two commands, to update both the x and y attribute value:

[
    {
        "command": "update_attribute",
        "selector": "#car",
        "attributeName": "x",
        "attributeValue": "10"
    },
    {
        "command": "update_attribute",
        "selector": "#car",
        "attributeName": "y",
        "attributeValue": "10"
    }
]

Here is an example flow:

[{"id":"e9e14e2fc5adef6f","type":"ui_svg_graphics","z":"5623aa0bb38bbf0e","group":"a90d6a68.8dc3b8","order":1,"width":0,"height":0,"svgString":"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0\" y=\"0\" height=\"100%\" viewBox=\"0 0 100 100\" width=\"100%\" preserveAspectRatio=\"xMinYMin meet\">\n  <defs id=\"svgEditorDefs\">\n    <symbol xmlns=\"http://www.w3.org/2000/svg\" id=\"f5de\" preserveAspectRatio=\"xMidYMid meet\" viewBox=\"0 0 480 512\">\n      <path d=\"M438.66 212.33l-11.24-28.1-19.93-49.83C390.38 91.63 349.57 64 303.5 64h-127c-46.06 0-86.88 27.63-103.99 70.4l-19.93 49.83-11.24 28.1C17.22 221.5 0 244.66 0 272v48c0 16.12 6.16 30.67 16 41.93V416c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-32h256v32c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-54.07c9.84-11.25 16-25.8 16-41.93v-48c0-27.34-17.22-50.5-41.34-59.67zm-306.73-54.16c7.29-18.22 24.94-30.17 44.57-30.17h127c19.63 0 37.28 11.95 44.57 30.17L368 208H112l19.93-49.83zM80 319.8c-19.2 0-32-12.76-32-31.9S60.8 256 80 256s48 28.71 48 47.85-28.8 15.95-48 15.95zm320 0c-19.2 0-48 3.19-48-15.95S380.8 256 400 256s32 12.76 32 31.9-12.8 31.9-32 31.9z\" />\n    </symbol>\n  </defs>\n  <rect id=\"svgEditorBackground\" x=\"0\" y=\"0\" width=\"100\" height=\"100\" style=\"fill:none;stroke:none\" />\n  <!-- Add here your SVG shapes (circles, rectangles, ...) -->\n  <!-- Or remove everything, if you want to paste an entire drawing (<svg...>...</svg>).-->\n  <rect x=\"0.427\" y=\"0.570\" style=\"fill:#132330;stroke:black;stroke-width:1px\" id=\"e1_rectangle\" width=\"229.629\" height=\"98.7175\" />\n  <use xlink:href=\"#f5de\" x=\"76.781\" y=\"37.607\" width=\"7.479\" height=\"7.977\" id=\"car\" style=\"fill:red\" />\n</svg>","clickableShapes":[],"javascriptHandlers":[],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":false,"showBrowserEvents":false,"enableJsDebugging":false,"sendMsgWhenLoaded":false,"noClickWhenDblClick":false,"outputField":"payload","editorUrl":"//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":"","_mcu":{"mcu":false},"x":820,"y":2900,"wires":[[]]},{"id":"700bc2d29d2fb74a","type":"inject","z":"5623aa0bb38bbf0e","name":"Move car to (10, 10)","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"command\":\"update_attribute\",\"selector\":\"#car\",\"attributeName\":\"x\",\"attributeValue\":\"10\"},{\"command\":\"update_attribute\",\"selector\":\"#car\",\"attributeName\":\"y\",\"attributeValue\":\"10\"}]","payloadType":"json","_mcu":{"mcu":false},"x":610,"y":2900,"wires":[["e9e14e2fc5adef6f"]]},{"id":"a90d6a68.8dc3b8","type":"ui_group","name":"videoTest","tab":"250de740.57ee78","order":1,"disp":true,"width":"14","collapse":true,"className":""},{"id":"250de740.57ee78","type":"ui_tab","name":"Dashboard","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

That works like this:

move_car

Bart

2 Likes

Thank you for the help, Bart.

at the moment it says: A msg.payload is required . How to fix this?
image

Thanks for all!
beg1nner

Happy :cake: day @BartButenaers

I'm just stepping in to make clear the definitions. Move an object and change the position of object may sound similar but may be different things, often misunderstood or not properly defined...

1 Like

By specifying a payload :wink:
Please export this part of your flow and share it here. Then I will have a look at it.

Alright. Here we go:

[
    {
        "id": "ccae928469893ab0",
        "type": "ui_svg_graphics",
        "z": "bae072850af32144",
        "group": "43a89985386cfe78",
        "order": 7,
        "width": 30,
        "height": "13",
        "svgString": "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0\" y=\"0\" height=\"100%\" viewBox=\"0 0 100 100\" width=\"100%\" preserveAspectRatio=\"xMinYMin meet\">\n  <defs id=\"svgEditorDefs\">\n    <symbol xmlns=\"http://www.w3.org/2000/svg\" id=\"f5de\" preserveAspectRatio=\"xMidYMid meet\" viewBox=\"0 0 480 512\">\n      <path d=\"M438.66 212.33l-11.24-28.1-19.93-49.83C390.38 91.63 349.57 64 303.5 64h-127c-46.06 0-86.88 27.63-103.99 70.4l-19.93 49.83-11.24 28.1C17.22 221.5 0 244.66 0 272v48c0 16.12 6.16 30.67 16 41.93V416c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-32h256v32c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-54.07c9.84-11.25 16-25.8 16-41.93v-48c0-27.34-17.22-50.5-41.34-59.67zm-306.73-54.16c7.29-18.22 24.94-30.17 44.57-30.17h127c19.63 0 37.28 11.95 44.57 30.17L368 208H112l19.93-49.83zM80 319.8c-19.2 0-32-12.76-32-31.9S60.8 256 80 256s48 28.71 48 47.85-28.8 15.95-48 15.95zm320 0c-19.2 0-48 3.19-48-15.95S380.8 256 400 256s32 12.76 32 31.9-12.8 31.9-32 31.9z\" />\n    </symbol>\n  </defs>\n  <rect id=\"svgEditorBackground\" x=\"0\" y=\"0\" width=\"100\" height=\"100\" style=\"fill:none;stroke:none\" />\n  <rect x=\"0.427\" y=\"0.570\" style=\"fill:#132330;stroke:black;stroke-width:1px\" id=\"e1_rectangle\" width=\"229.629\" height=\"98.7175\" />\n  <use xlink:href=\"#f5de\" x=\"76.781\" y=\"37.607\" width=\"7.479\" height=\"7.977\" id=\"car\" style=\"fill:red\" />\n</svg>",
        "clickableShapes": [],
        "javascriptHandlers": [],
        "smilAnimations": [
            {
                "id": "carmoving",
                "targetId": "#car",
                "classValue": "",
                "attributeName": "x",
                "transformType": "skewX",
                "fromValue": "10",
                "toValue": "100",
                "trigger": "msg",
                "duration": "10",
                "durationUnit": "s",
                "repeatCount": "0",
                "end": "restore",
                "delay": "1",
                "delayUnit": "s",
                "custom": ""
            }
        ],
        "bindings": [],
        "showCoordinates": false,
        "autoFormatAfterEdit": false,
        "showBrowserErrors": false,
        "showBrowserEvents": false,
        "enableJsDebugging": false,
        "sendMsgWhenLoaded": false,
        "noClickWhenDblClick": false,
        "outputField": "payload",
        "editorUrl": "//drawsvg.org/drawsvg.html",
        "directory": "",
        "panning": "both",
        "zooming": "enabled",
        "panOnlyWhenZoomed": false,
        "doubleClickZoomEnabled": true,
        "mouseWheelZoomEnabled": true,
        "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": "Verkehrsplan",
        "x": 670,
        "y": 380,
        "wires": [
            []
        ]
    },
    {
        "id": "02f0868fa3cc36a7",
        "type": "inject",
        "z": "bae072850af32144",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 320,
        "y": 380,
        "wires": [
            [
                "138ae10d0a73d133"
            ]
        ]
    },
    {
        "id": "138ae10d0a73d133",
        "type": "function",
        "z": "bae072850af32144",
        "name": "function 2",
        "func": "return [\n    {\n        \"command\": \"update_attribute\",\n        \"selector\": \"#car\",\n        \"attributeName\": \"x\",\n        \"attributeValue\": \"10\"\n    },\n    {\n        \"command\": \"update_attribute\",\n        \"selector\": \"#car\",\n        \"attributeName\": \"y\",\n        \"attributeValue\": \"10\"\n    }\n];",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 500,
        "y": 380,
        "wires": [
            [
                "ccae928469893ab0"
            ]
        ]
    },
    {
        "id": "43a89985386cfe78",
        "type": "ui_group",
        "name": "Verkehrsplan",
        "tab": "9839f4c9dc30de28",
        "order": 2,
        "disp": true,
        "width": "30",
        "collapse": false,
        "className": ""
    },
    {
        "id": "9839f4c9dc30de28",
        "type": "ui_tab",
        "name": "CarControl",
        "icon": "check",
        "order": 1,
        "disabled": false,
        "hidden": false
    }
]

Thanks for help and happy birthday :slight_smile:

Thanks!!

In your function node you do this:

return [
    {
        "command": "update_attribute",
        "selector": "#car",
        "attributeName": "x",
        "attributeValue": "10"
    },
    {
        "command": "update_attribute",
        "selector": "#car",
        "attributeName": "y",
        "attributeValue": "10"
    }
];

So you send an array (of two objects) through the wire into the svg node. Instead Node-RED is about passing message objects.

That is why the svg node tells you that the message needs a payload...

So you could do this if you want to create a new message object from scratch:

return {
    "payload": [
        {
            "command": "update_attribute",
            "selector": "#car",
            "attributeName": "x",
            "attributeValue": "10"
        },
        {
            "command": "update_attribute",
            "selector": "#car",
            "attributeName": "y",
            "attributeValue": "10"
        }
    ]
};

Or you can put your data into the existing input message (that is injected via the Inject node):

msg.payload = [
    {
        "command": "update_attribute",
        "selector": "#car",
        "attributeName": "x",
        "attributeValue": "10"
    },
    {
        "command": "update_attribute",
        "selector": "#car",
        "attributeName": "y",
        "attributeValue": "10"
    }
];

return msg;

It might be useful to watch the Node-RED essentials video on youtube (e.g. this one about messages). The videos are very short and will save you a lot of time afterwards.

1 Like

Thank you alot BartButenaers,

I've tried it now and it works perfectly.
Thanks for the help!

Best regards
beg1nner

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.