Dreamdealer
Dreamdealer

Reputation: 188

How to style/manipulate contents of SVG USE element

I have three SVG images on a page. One is an "image editor" where you can enter some text, an icon, drag and scale it around, etc.

The other two SVG's use the content from the top SVG through a USE element and displays a preview of the end result.

Screenshot of the editor

When I edit something in the editor, the two preview automatically update. Perfect. But I don't want to show the bounding box, transform tools, guides, etc in the bottom two preview SVG's.

Is there a way to style (CSS) or manipulate (JS) the (shadow)DOM of those SVG's to not display these extra elements?

Upvotes: 2

Views: 1014

Answers (2)

Persijn
Persijn

Reputation: 14990

Just like @paulLeBeau answer i suggest putting it outside a group of elements.
The javascript code here will put the handles on all the corners of the group element. (edit-group in this example).
If you have a group that you allready draw to you can simply put that group into this code and it should make the handles.

function setAttributes(elem, attrs) {
  for (var key in attrs) {
    elem.setAttribute(key, attrs[key]);
  }
}

document.addEventListener("DOMContentLoaded", function(event) {
  var svgns = "http://www.w3.org/2000/svg"
  var svgdoc = document.getElementById("edit-svg");

  var editgroup = svgdoc.getElementById("edit-group");
  var grouprect = editgroup.getBBox();

  var handle = document.createElementNS(svgns, "rect");
  setAttributes(handle, {
    "transform": "translate(-1.5 -1.5)",
    "fill": "none",
    "stroke": "black",
    "stroke-width": "0.5",
    "width": "3",
    "height": "3",
    "x": grouprect.x,
    "y": grouprect.y
  });
  svgdoc.appendChild(handle);
  
  var handle2 = document.createElementNS(svgns, "rect");
  setAttributes(handle2, {
    "transform": "translate(-1.5 -1.5)",
    "fill": "none",
    "stroke": "black",
    "stroke-width": "0.5",
    "width": "3",
    "height": "3",
    "x": grouprect.x + grouprect.width,
    "y": grouprect.y
  });
  svgdoc.appendChild(handle2);
  
  var handle3 = document.createElementNS(svgns, "rect");
  setAttributes(handle3, {
    "transform": "translate(-1.5 -1.5)",
    "fill": "none",
    "stroke": "black",
    "stroke-width": "0.5",
    "width": "3",
    "height": "3",
    "x": grouprect.x,
    "y": grouprect.y + grouprect.height
  });
  svgdoc.appendChild(handle3);
  
  var handle4 = document.createElementNS(svgns, "rect");
  setAttributes(handle4, {
    "transform": "translate(-1.5 -1.5)",
    "fill": "none",
    "stroke": "black",
    "stroke-width": "0.5",
    "width": "3",
    "height": "3",
    "x": grouprect.x + grouprect.width,
    "y": grouprect.y + grouprect.height,
  });
  svgdoc.appendChild(handle4);
  
  var dotted = document.createElementNS(svgns, "rect");
  setAttributes(dotted, {
    "fill": "none",
    "stroke": "black",
    "stroke-width": "0.5",
    "stroke-dasharray": "5",
    "width": grouprect.width,
    "height": grouprect.height,
    "x": grouprect.x,
    "y": grouprect.y
  });
  svgdoc.appendChild(dotted);

});
.main {
  border: 1px solid black;
}
#edit-svg {
  width: 500px;
}
.preview svg {
  border: 1px solid black;
}
<div class="main">
  <svg id="edit-svg" viewbox="0 0 110 50" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <g id="edit-group">
      <text x=5 y=40 font-size="10" stroke="firebrick">Ask us almost anything</text>
    </g>
  </svg>
</div>
<div class="preview">
  <h2>Preview</h2>
  <svg width="500px" viewBox="0 0 110 50">
    <use x="0" y="0" xlink:href="#edit-group" />
  </svg>
</div>

Upvotes: 1

Paul LeBeau
Paul LeBeau

Reputation: 101820

Alter your editor code so that the drawing elements go into one group and the handle elements go into another group. Then in your clone SVGs have your <use> elements reference the first group.

svg {
  border: solid 1px black;
}
<svg width="500" height="300" viewBox="0 0 500 300">
  
  <g id="drawing">
    <ellipse cx="250" cy="150" rx="200" ry="100" fill="orange"/>
  </g>
  
  <g id="handles">
    <rect x="50" y="50" width="400" height="200" fill="none" stroke="blue" stroke-dasharray="10"/>
  </g>
  
</svg>


<br/>


<svg width="250" height="150" viewBox="0 0 500 300">
  <use xlink:href="#drawing"/>
</svg>

Upvotes: 1

Related Questions