UI-SVG-Graphics no event-object for touch events

Hi folks,

currently I try to use the panning inside a svg-graphics node to move a spot light.
Attached simple flow shows what I did so far:

[{"id":"a03bd3cf.177578","type":"tab","label":"svg-panning-test","disabled":false,"info":""},{"id":"100d8947.43b66f","type":"ui_svg_graphics","z":"a03bd3cf.177578","group":"1e71a25b.2d361e","order":0,"width":"3","height":"3","svgString":"<svg x=\"0\" y=\"0\" width=\"144\" height=\"144\" viewBox=\"0 0 144 144\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n    <circle id=\"myCircle\" cx=\"72\" cy=\"72\" r=\"20\" color=\"red\" outline=\"black\"/>\n</svg>","clickableShapes":[{"targetId":"#myCircle","action":"click","payload":"mouse click","payloadType":"str","topic":"#myCircle"},{"targetId":"#myCircle","action":"touchstart","payload":"touch start","payloadType":"str","topic":"#myCircle"},{"targetId":"#myCircle","action":"touchend","payload":"touch end","payloadType":"str","topic":"#myCircle"}],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":false,"outputField":"payload","editorUrl":"//drawsvg.org/drawsvg.html","directory":"","panning":"both","zooming":"disabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"name":"svg-graphics","x":290,"y":180,"wires":[["2b67b3da.0a10cc"]]},{"id":"2b67b3da.0a10cc","type":"debug","z":"a03bd3cf.177578","name":"log events","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":500,"y":180,"wires":[]},{"id":"1e71a25b.2d361e","type":"ui_group","z":"","name":"svg-panning-test","tab":"d81e78f0.ebcac8","order":4,"disp":true,"width":"3","collapse":false},{"id":"d81e78f0.ebcac8","type":"ui_tab","z":"","name":"Home","icon":"home","order":1,"disabled":false,"hidden":false}]

I created a red circle and activated panning for both directions (x and y).
Additionally I registered the circle to receive following events:

  • Mouse clicked

  • Touch start

  • Touch end

When I try this on my desktop, i.e. press Mouse on circle -> pan circle -> release mouse, svg-node delivers this msg object, containing the event including the positions for the mouse release:

{"topic":"#myCircle","elementId":"myCircle","selector":"#myCircle","event":{"type":"click","svgX":72.5,"svgY":77,"pageX":1612,"pageY":214,"screenX":1661,"screenY":349,"clientX":1612,"clientY":214,"bbox":[1591.5,229,1631.5,189]},"payload":"mouse click","socketid":"_jzbtXVRt2MRmM3BAABA","_msgid":"8d0c3fa3.a445b"}

Now, when I do the same on my mobile, i.e. tap circle -> pan circle -> release circle, svg-node comes with two messages (as expected):

{"topic":"#myCircle","elementId":"myCircle","selector":"#myCircle","payload":"touch start","socketid":"c-oJNdTcIs682LPcAABE","_msgid":"e2b5a0cb.a1e48"}

and

{"topic":"#myCircle","elementId":"myCircle","selector":"#myCircle","payload":"touch end","socketid":"c-oJNdTcIs682LPcAABE","_msgid":"46243e3c.ab013"}

Opposed to the mouse events, both messages do not contain the event object, which gives me no opportunity to move the spot light from my mobile ...
In addition, the click-event seems to be suppressed too.

Is there a specific reason why touch events do not deliver position events?
I wonder how I could work around this for my mobile device.

Help very much appreciated!

Best regards,
janosch

Hi @janosch,
No. Seems I have overlooked it, and you are the first one to report it.

A normal click event object contains all the required coordinates (to compose an output message):

However it seems that a touch event doesn't contain any coordinates:

Not easy to solve, without remote debugging via USB a mobile device ...
I assume I have to calculate everything from the targetTouches properties (like in this StackOverflow discussion), but I'm not sure at the moment.
And my (free) time is up for today.
Bart

@janosch,

I have added a fix for the touch events on Github. Would be nice if you could test it and give me feedback, before I publish it on NPM. You can install it directly from Github using this command (from within your .node-red folder):

npm install bartbutenaers/node-red-contrib-ui-svg

In this example flow:

image

[{"id":"16a953b2.21beec","type":"ui_svg_graphics","z":"5598090d.febad8","group":"925439b0.2863c8","order":0,"width":"3","height":"3","svgString":"<svg x=\"0\" y=\"0\" width=\"144\" height=\"144\" viewBox=\"0 0 144 144\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n<circle id=\"myCircle\" cx=\"73\" cy=\"72\" r=\"20\" color=\"red\" outline=\"black\"/>\n</svg>","clickableShapes":[{"targetId":"#myCircle","action":"touchstart","payload":"touch start","payloadType":"str","topic":"#myCircle"},{"targetId":"#myCircle","action":"touchend","payload":"touch end","payloadType":"str","topic":"#myCircle"}],"smilAnimations":[],"bindings":[],"showCoordinates":false,"autoFormatAfterEdit":false,"showBrowserErrors":true,"outputField":"payload","editorUrl":"//drawsvg.org/drawsvg.html","directory":"","panning":"both","zooming":"disabled","panOnlyWhenZoomed":false,"doubleClickZoomEnabled":false,"mouseWheelZoomEnabled":false,"name":"svg-graphics","x":290,"y":180,"wires":[["4672821a.2f296c","84cd10ea.04c1"]]},{"id":"4672821a.2f296c","type":"debug","z":"5598090d.febad8","name":"log events","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":490,"y":180,"wires":[]},{"id":"84cd10ea.04c1","type":"ui_context_menu","z":"5598090d.febad8","group":"925439b0.2863c8","order":1,"width":0,"height":-1,"fontSize":16,"inputPositionXField":"event.clientX","inputPositionXType":"msg","inputPositionYField":"event.clientY","inputPositionYType":"msg","outputField":"payload","inputMenuField":"menu","inputMenuType":"fixed","menuItems":[{"id":"item1","icon":"fa-star","label":"item-1","topic":"","payload":"","payloadType":"str","visible":true,"enabled":true},{"id":"item2","icon":"fa-heart","label":"item-2","topic":"","payload":"","payloadType":"str","visible":true,"enabled":true}],"colors":"native","textColor":"#000000","backgroundColor":"#ffffff","borderColor":"#626262","intervalLength":"1","intervalUnit":"secs","startTimerAtOpen":true,"startTimerAtLeave":true,"stopTimerAtEnter":true,"name":"popup","x":470,"y":240,"wires":[[]]},{"id":"925439b0.2863c8","type":"ui_group","z":"","name":"svg-panning-test","tab":"5c613937.fe7368","order":4,"disp":true,"width":"3","collapse":false},{"id":"5c613937.fe7368","type":"ui_tab","z":"","name":"Home","icon":"home","order":1,"disabled":false,"hidden":false}]

I now get 'almost' identical coordinates as in the clicked event:

image

Bart

1 Like

Hi @BartButenaers,
yes I get the event object containing positions for the touch start event now.
Values seem to be plausible.
But no touch end event at all anymore.
Did you somehow suppress it? :thinking:

By the way, I'm just thinking whether panning is what I need.
Eventually I need to move that circle (or whatever) and not panning the complete svg (which is ever entirely shown on screen). Maybe it's a better idea to use the positions from touch end event and feed that back as a message to set new x/y positions for my particular graphics object?
For that case clearly the circle wouldn't move during (pseudo-)panning. I wonder whether a touch end event would occur at all (because I'm out of the circle when I end panning)?

Regards,
jan

Hi Jan (@janosch),

I had used the touch event's targetTouches property to implement your feature request, which contains information where you touch the surface with your fingers. So at touchStart this will contain coordinates, but not at touchEnd because then you don't touch the surface anymore.

By using the changedTouches property instead, it works much better. This contains at touchStart the same information, but at touchEnd it contains the coordinates of the touch points that have been removed ...

When you install the Github version again, it is hopefully solved now.

1 Like

Great work so far Bart (@BartButenaers)!

I just tried it, and it works for the touch on my mobile phone. :clap:
For safety I will give it a try on a tablet later.
Delivered Positions again seem to be correct (I have to dig a bit more in to your docu to find out what coordinate system the numbers are for ...)

So, that works for me, great!
What I figured out when I cross checked all this on my desktop is as follows:
To have the same behavior there (as on the mobile) I also registered for the mouse down and the mouse up events (I assume those are meant to react on left mouse button being pressed and released?) to track the panning movement. Both events don't show up.

Am I still something missing?

Regards,
jan

I had hoped that the documentation was clear enough to understand this:

image

Let me know how you would explain this in the documentation then.
Because when you find this isn't clear enough, then I'm running out of creativity (and free time ...)

For completeness all of these events have been added to the node.
I have no clue at all for which purpose they are used by the Node-RED users ...

On my Windows 10 portable it works fine:

image

Please share your flow, so I can try to reproduce it.
And let me know which system you are running on.

Hi Bart (@BartButenaers),
thank you again for your help (and sorry for my late reply).

Regarding your documentation:

No reason to improve it, it's all fine and very clear. :+1:
I just wanted to say, I have to read it carefully to figure out, which of the coordinate systems is the right one for me, as I have to transform the pixel coordinates into metric positions to move a spot light.

About the mouse events:
For testing I used the simple flow that I had in my first post. For development I use the official node-red docker image (which is based on Linux). In addition I installed the node-red-dashboard and some of the extra nodes. All this running in Ubuntu 18.04 LTS on my desktop.

I did some tests of the dashboard on my Windows 10 notebook too, using edge and firefox.
In deed it works as you have shown in your previous reply. Also for my Ubuntu desktop.

I realized, when I have either Panning or Zooming enabled, the mouse down and mouse up events are not emitted.

But: This is nevertheless all fine for me, as for production I will use a touch device and you solved the initial problem regarding the touch events.

So I propose to close this thread and set it to solved if you agree.
All other could be handed-off to a different thread (if someone needs it)?

Let me know what you think.

Best regards,
Jan

Good catch! Seems indeed that the panzoom library (which I'm using behind the scenes) swallows those events. I assume that might be a problem for some folks... Will need to have a look at that. Thanks for reporting! Will have a look this evening. Think I have to play with this:

image

I have added that custom event handler to the PanZoom library, to skip calling the event.preventDefault because that default handler was my SVG node's event handler (which is responsible for sending an output message for each specified event).

Now it seems to work (both for mouse and touch).
In the following example the mousedown msg is triggered when I start panning, and the mouseup msg is triggered when I stop panning:

svg_event_bubbling

It is on Github. Would be nice if you could test it.

Hi Bart,
I just tested your recent fix on my desktop and mobile.
Works fine for both, get all registered events now, regardless whether I have Panning enabled or not.
Great! :clap:

Regards,
Jan

1 Like

Hi Bart (@BartButenaers),
are you planning to put your recent fix into an official npm package?

Best regards,
Jan

Hey Jan,
Yes but I'm waiting for somebody else to test another feature request (to inject an entire SVG source into the SVG node). Hopefully he has time soon to test it. Then I will merge that with the fixes I made for you, and publish it on npm. Just to avoid having too much administration work for all my nodes.