Reputation: 592
I want to make a fairly large diagram using SVG (I have been using Snap.svg in JavaScript). I'd like to display a zoomable portion of the diagram in an element, and also a smaller version of the whole thing in a different element, in which the user can navigate.
One strategy is this:
Make two identical SVGs, except that they have different viewBox
es, and every time I change one of the svg elements, make an identical change to the other copy. The viewBox
attributes cause each view to show the right part of the diagram.
Is that a good strategy? Seems fragile and wasteful to me. Is there some other, smarter approach? Do I really have to draw everything twice?
Hoping for "D'oh!"
Upvotes: 3
Views: 1044
Reputation: 101868
Yes it's possible to have a master SVG and then "thumbnail" and/or "zoomed" versions of the same image that update automatically.
document.getElementById("but").addEventListener("click", function() {
var svg = document.getElementById("mainsvg");
var c = document.createElementNS("http://www.w3.org/2000/svg", "circle");
c.setAttribute("cx", 1000*Math.random());
c.setAttribute("cy", 1000*Math.random());
c.setAttribute("r", 50);
c.setAttribute("fill", "red");
svg.appendChild(c);
});
#main {
width: 400px;
height: 400px;
}
#thumb,
#zoom {
display: inline-block;
width: 80px;
height: 80px;
}
svg {
border: solid 1px grey;
}
<div id="main">
<svg id="mainsvg" viewBox="0 0 1000 1000">
<rect x="100" y="100" width="500" height="500" fill="green"
transform="rotate(10,350,350)"/>
<rect x="400" y="400" width="500" height="500" fill="orange"
transform="rotate(-10,650,650)"/>
</svg>
</div>
<div id="thumb">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1000 1000">
<use xlink:href="#mainsvg" />
</svg>
</div>
<div id="zoom">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1000 1000">
<use xlink:href="#mainsvg"
x="-500" y="-1200"
width="3000" height="3000" />
<!-- control the zoom and position with x, y, width and height -->
</svg>
</div>
<div>
<button id="but">Click me</button>
</div>
Upvotes: 5