bartbutenaers / node-red-contrib-ui-svg

A Node-RED widget node to show interactive SVG (vector graphics) in the dashboard
Apache License 2.0
94 stars 27 forks source link

Implement layers #4

Closed bartbutenaers closed 5 years ago

bartbutenaers commented 5 years ago

Would like to support layers, however this is not part of the SVG standard. Suppose a third-party SVG editor is being used, and the resulting SVG string is being copied into this node's config screen. Then the user adds some extra elements. Some time afterwards he uses the third-party editor again to update something in his original drawing. As soon as he copies the SVG string into the config screen, the extra elements will be lost!

Tools like SVG-Edit workaround this by putting layers into SVG groups:

<svg>
   <g>
      ... elements layer X ...
   </g>
   <g>
      ... elements layer Y ...
   </g>
</svg>

This way the elements of layer X are drawn first, and the elements of layer Y are drawn afterwards (so on top of the elements of layer Y).

I think something similar could be achieved using nested SVG's (which can also each have their own viewport):

<svg>
   <svg>
      ... elements layer X ...
   </svg>
   <svg>
      ... elements layer Y ...
   </svg>
</svg>

But I'm not sure how this should work:

bartbutenaers commented 5 years ago

Hi @Steve-Mcl, Would like to implement this feature as soon as possble.

This is my proposal to have a quick and easy implementation:

  1. The node.svgString currently is a string, but it would be better if this becomes a node.svgMap (i.e. key/value pairs with key the layer name and value the svg string).

  2. On the 'settings' tab we add an EditableList where the users can easily add/remove layers:

    image

    In fact we are just managing the keys on the node.svgMap. Add some warning that by deleting a layer, all corresponding content will be lost... Not sure how to 'rename' a layer?

  3. On the 'settings' tab we add a dropdown, so the user can select one of those layers. As soon as another layer is selected, the corresponding svg string will be displayed in the editor.

    image

  4. As soon as we generate the html string for the dashboard we will generate a root svg and multiple nested-svgs (i.e. one sub-svg for every 'visible' layer).

    <svg viewBox="0 0 50 20">
      <svg x="0" y="0">
          First layer content...
      </svg>
      <svg x="0" y="0">
          Second layer content...
      </svg>
    </svg>

    We could automatically set the viewbox on the root svg (see other Github issue), e.g. to support zooming and panning ...

If you like we can convert existing nodes automatically, by copying the svgString to the svgMap as 'default layer' record?

[EDIT] We could also add an extra checkbox to the 'settings' tab, named "allow layers to be message controlled". When that checkbox is enabled, ALL nested svg's will be send to the dashboard (but only the visible ones will be rendered). But when a message changes the visibility of a layer, the client side code will show/hide the corresponding nested SVG. Then users can show/hide layers at runtime somehow ...

Steve-Mcl commented 5 years ago

In principle, I have no issue and can see the benefit. however...

Could we slate that for V2 or is it something you wish to get out there Bart?

Steve-Mcl commented 5 years ago

Some additional thoughts.

If you play with "layers" feature on SVG-Edit, it adds <g> elements like this...

 <g display="inline">
  <title>Layer 1</title>
   ...
 </g>

If we do implement layers, then this could be how we integrate seamlessly with an editor.

bartbutenaers commented 5 years ago

@Steve-Mcl ,

The main reason why I would like to have this in the current release, is too make sure that we never have backwards compatibility issues. Perhaps there isn’t a problem, but just to make sure...

Do we agree that we won’t add any layer-related stuff on our config screen, which means the user needs to implement the grouping by adding group-elements inside the SVG editor.

But we do add a section on our readme page about “using layers”: there we explain that layers can be created by manually (or via tools like svg-edit) using groups. And that the visibility of the groups can be dynamically changed (like they can change any other attribute value).

Is that ok for you?

Than we can indeed easily integrate svg-edit with our node, and have also layering become possible in svg-edit. And indeed there won’t be any complications when user accidentally sets different viewboxes on the different nested svg elements …

Steve-Mcl commented 5 years ago

Hi Bart,

I agree we dont add specific layering capabilties - at least in the initial release.

The way svg-edit handles layers works (see my HMI demo I sent you in PM)

Than we can indeed easily integrate svg-edit with our node, and have also layering become possible in svg-edit. And indeed there won’t be any complications when user accidentally sets different viewboxes on the different nested svg elements …

Definitely the way to go. Keeps it easier for us and easier for the user while permitting this type of functionality. Win win.