Few tricks:
d3.xml()
to load the external SVG, simply including it as an image hides it from the DOM and d3. For an example of this, take a look here.d3.select()
can then be used to query and modify its attributesThe height|width are relative to the svg viewbox. Not related to the width and height of it on the page. This is important because any transforms or animations you do will all reference these coordinates.
Movement should be calculated according to your will, potentially via mathematical formula.
z-level is done by moving the object from upper to lower group. Svgs do not have a z-index
(if you know css).
<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>d3.js and external SVGs</title>
<meta name="viewport" content="width=device-width">
<body>
<svg></svg>
<div class="post">
<div id="atom"></div>
<style type="text/css">
#atom svg {
height: 380px;
width: 280px;
margin: 0 auto;
display: block;
}
</style>
</div>
<script type="text/javascript" src="d3.v3.min.js"></script>
<script type="text/javascript" src="atom.js"></script>
</body></html>
var redElectron = {
theta: 0,
draw: function() {
if (redElectron.theta > Math.PI*2) { // reset theta
redElectron.theta = 0;
}
if (redElectron.theta > Math.PI) {
var removed = d3.selectAll('.red-electron').remove(); // remove close, add far
d3.selectAll('.red-far').append(function() {
return removed.node();
});
}
else {
var removed = d3.selectAll('.red-electron').remove(); // remove far, add close
d3.selectAll('.red-close').append(function() {
return removed.node();
});
}
// transform formula
var additional = "translate("+100*Math.cos(redElectron.theta)+","+5*Math.sin(redElectron.theta)+")";
d3.selectAll('.red-electron').attr("transform", "rotate(35,250,250) translate(-95,75) "+additional);
redElectron.theta += 0.05; // increment theta
}
}
var purpleElectron = {
theta: 0,
draw: function() {
if (purpleElectron.theta > Math.PI*2) { // reset theta
purpleElectron.theta = 0;
}
if (purpleElectron.theta > Math.PI) {
var removed = d3.selectAll('.purple-electron').remove(); // remove close, add far
d3.selectAll('.purple-far').append(function() {
return removed.node();
});
}
else {
var removed = d3.selectAll('.purple-electron').remove(); // remove far, add close
d3.selectAll('.purple-close').append(function() {
return removed.node();
});
}
// transform formula
var additional = "translate("+85*Math.cos(purpleElectron.theta)+","+5*Math.sin(purpleElectron.theta)+")";
d3.selectAll('.purple-electron').attr("transform", "translate(10,-60) rotate(120,94,90) "+additional);
purpleElectron.theta += 0.05; // increment theta
}
}
var dash = {
offset: 0,
draw: function() {
if (dash.offset > 4.8) dash.offset = 0;
d3.selectAll('.electron-line').attr('stroke-dashoffset',dash.offset);
dash.offset += 0.1;
}
}
d3.xml("./atom.svg", "image/svg+xml", function(xml) {
document.getElementById('atom').appendChild(xml.documentElement);
window.setInterval(redElectron.draw,50);
window.setInterval(purpleElectron.draw,45);
window.setInterval(dash.draw,45);
});
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 188.7 180.3" enable-background="new 0 0 188.7 180.3" xml:space="preserve">
<g class="red-far"></g>
<g class="purple-far"></g>
<g>
<g>
<path fill="none" stroke="#000000" stroke-width="0.7196" stroke-linecap="round" stroke-miterlimit="10" d="M0.8,177.7
c-0.2-0.2-0.3-0.4-0.4-0.6"/>
<path class="electron-line" fill="none" stroke="#000000" stroke-width="0.7196" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="1.4397,2.8793" d="
M0.4,174.3c1.5-6.4,10.9-19.8,25.6-37.2c14.2-16.8,33.5-37.2,55.4-58.5c28.1-27.2,54.7-50.1,73.7-63.9
c12.4-9.1,21.6-14.3,25.9-14.3"/>
<path class="electron-line" fill="none" stroke="#000000" stroke-width="0.7196" stroke-linecap="round" stroke-miterlimit="10" d="M182.3,0.6
c0.2,0.1,0.4,0.2,0.6,0.4"/>
</g>
</g>
<circle fill="#2FCC71" cx="96" cy="95.1" r="65.1"/>
<g class="dotted-ellipse">
<path class="electron-line" fill="none" stroke="#000000" stroke-width="0.7196" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="1.4414,2.8829" d="
M187.7,178.9c-5.8,5.6-49.1-29.6-96.7-78.7C43.4,51.1,9.5,6.7,15.3,1.1c3.3-3.2,18.5,6.6,39.6,24.6C71.3,39.6,91.2,58.4,112,79.8
c26.6,27.4,48.9,53.4,62.4,71.9C185.1,166.4,190.3,176.4,187.7,178.9z"/>
</g>
<path class="electron-line" fill="#2FCC71" d="M51.2,49c25.3-25.3,66.2-25.3,91.4-0.1c25.2,25.2,25.2,66.2-0.1,91.4"/>
<g class="red-close">
<g class="red-electron">
<circle opacity="0.2" fill="#4D4D4D" cx="115.2" cy="132.3" r="8.9"/>
<circle fill="#C1392B" cx="118" cy="128.1" r="8.9"/>
</g>
</g>
<g>
<g>
<path fill="none" stroke="#000000" stroke-width="0.7196" stroke-linecap="round" stroke-miterlimit="10" d="M184.9,2.6
c0.2,0.2,0.3,0.4,0.4,0.6"/>
<path fill="none" class="electron-line" stroke="#000000" stroke-width="0.7196" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="1.4397,2.8793" d="
M185.3,6.1c-1.5,6.4-10.9,19.8-25.6,37.2c-14.2,16.8-33.5,37.2-55.4,58.5c-28.1,27.2-54.7,50.1-73.7,63.9
C18.1,174.7,8.9,179.9,4.7,180"/>
<path fill="none" stroke="#000000" stroke-width="0.7196" stroke-linecap="round" stroke-miterlimit="10" d="M3.3,179.7
c-0.2-0.1-0.4-0.2-0.6-0.4"/>
</g>
</g>
<g class="purple-close">
<g class="purple-electron">
<circle opacity="0.2" fill="#4D4D4D" cx="146.8" cy="58.9" r="8.9"/>
<circle fill="#8F44AD" cx="149.7" cy="54.7" r="8.9"/>
</g>
</g>
</svg>