Good Day,
First of all thanks for the nice libraries you have shared and sorry if the question is basic.
I was playing a bit with the library in an attempt to make a small diagram editor.
I am aware of the alternative libraries that offer a diagram editor out of the box, but none I saw worked natively with SVG and I thought it would be fun to try it.
I started with: svg.js + svg.select.js + svg.resize.js + svg.draggable plugins + svg.draw.js plugins
as they already offered already many functionalities a user would need to manipulate shapes at runtime.
I believe the "svg.select.js" does not have the ability to select multiple shapes so I thought that I could instead add elements into a group and select the group to move / resize or rotate multiple shapes (from the documentation I understood that was the purpose of the group).
I am able to add multiple shapes to a group and use a function similar to the below:
function groupAddElement(el, g)
{
//deactivate individual elements "selectable", "draggable" and "resize" runtime features
el.selectize(false);
el.draggable(false);
el.resize(false);
//add the element to the group and enable "selectable", "draggable" on the group.
g.add(el);
g.draggable(true,{});
// every time a new element is added need to re-initialize the selectize.
g.selectize(false);
g.selectize({deepSelect:false});
}
I can now move shapes at runtime by moving the group but then, how do you move the elements back into the parent without losing their new position after they have been dragged somewhere else?
If I do something like this:
function groupDeselectAll(g, parentSVG)
{
g.draggable(false,{});
g.selectize(false);
//loops through the group shapes to add them back to the main SVG
g.each(function(i, children) {
// each SVG element in the diagram that can be moved has a class associated
// added on creation specifically to allow easier selection.
if (this.hasClass("drawingShapeElement")) {
this.draggable(true,{});
//move back the elements into the main SVG
parentSVG.add(this);
}
});
// clean group just in case (is it necessary?)
g.remove();
}
it will add the elements back into the main SVG object but they will reset their position to their initial state.
Thank you.
I believe you want to try the flatten() feature of svg.js which takes a parent node (e.g. a group) and adds its element to another parent (e.g. the root svg) without changing its visual representation. So instead of looping through all children you might as well call theGroup.flatten(newParent). newParent is optional and defaults to the root svg.
That was an incredibly fast answer.
Thank you.
Your suggestion works beautifully.
Hello Again and sorry for re-opening the issue.
Although the flatten (or Ungroup) worked initially, it raised another issue on the svg.select.js module.
The first time the group is created and flattened all is working fine with the function changed along those lines as x your previous suggestion:
function groupDeselectAll(g)
{
g.draggable(false,{});
g.selectize(false);
g.ungroup(drawSeat);
g.flatten();
g.remove();
}
Now the issue comes with the function that adds elements to groups.
function groupAddElement(el, g)
{
//deactivate individual elements "selectable", "draggable" and "resize" runtime features
el.selectize(false);
el.draggable(false);
el.resize(false);
//add the element to the group and enable "selectable", "draggable" on the group.
g.add(el);
g.draggable(true,{});
// every time a new element is added need to re-initialize the selectize.
g.selectize(false);
g.selectize({deepSelect:false});
}
I have 2 elements that I am selecting.
The first element is added back to the group normally but for some reason the second element
crashes at:
line 28 of svg.select.js:
this.nested = (this.nested || this.parent.group());
With the Error:
TypeError: Cannot read property 'group' of null
The same functions were working normally before I change the loop with the flatten (with the initial issue of losing their position when moved to the main drawing).
Do I have to take particular care after i have flatten the Group? Can I not use the same Group variable once I have flattened it?
Thank you.
First of all flatten() is an alias of ungroup(). Only use one.
For reusing the group I would say: you removed the group from the Dom. Did you add it back before reusing it? Furthermore flatten() does remove the group, too so you don't have to do that manually.
When you really want to reuse the group you have to add it back to the Dom AND remove all transformations on it.
Seriously - just create a new group. It's less fuss and more readable anyway.
I have adjusted to create a new Group for every "flatten" and now it works again.
Thank you for your help, I am having fun with the library.
Most helpful comment
I believe you want to try the
flatten()feature of svg.js which takes a parent node (e.g. a group) and adds its element to another parent (e.g. the root svg) without changing its visual representation. So instead of looping through all children you might as well calltheGroup.flatten(newParent).newParentis optional and defaults to the root svg.