Skip to content

Instantly share code, notes, and snippets.

@shengyuan
Last active April 2, 2018 03:46
Show Gist options
  • Save shengyuan/1b53a7b1cf05c474b743821060bbbd5d to your computer and use it in GitHub Desktop.
Save shengyuan/1b53a7b1cf05c474b743821060bbbd5d to your computer and use it in GitHub Desktop.
Moving a Circle Outside a Circle
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body {
margin: 0 auto;
position: fixed;
}
#circle-box {
margin: 0 auto;
}
</style>
</head>
<p>
<label for="nDegrees"
style="display: inline-block; width: 240px; text-align: right; position">
<span id="nDegrees-value">180</span>°
</label>
<input type="range" min="0" max="360" id="nDegrees">
</p>
<body>
<div id="circle-box"></div>
<script>
// How we achieve this circle drawn with respect to the inner circle is covered
// in the previous block (found in the ReadMe.md)
var margin = {top: 20, right: 10, bottom: 20, left: 10};
var width = 600 - margin.left - margin.right;
var height = 400 - margin.top - margin.bottom;
var innerR = width/6;
var innerCY = height/2;
var innerCX = width/2;
var bufferR = width/4
var orbitR = width/50;
var svg = d3.select("#circle-box").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
svg.append("circle")
.attr("r", innerR)
.attr("cy", innerCY)
.attr("cx", innerCX)
.attr("class","innerCircle")
.attr("stroke-width", 5)
.attr("stroke-style","solid")
.attr("fill", "#bdc3c7");
svg.append('circle')
.attr('r', bufferR)
.attr('cy', innerCY)
.attr('cx', innerCX)
.attr('class', 'bufferCircle')
.attr('stroke', '#9b59b6')
.attr('stroke-dasharray', '5, 10')
.attr('fill', 'none');
// Here's our new work:
//
// Let's make a function to return the orbiting object's XY given an input.
// Input represents degrees in this case. And the expected return is an array
// of two values.
function orbitalXY(input) {
// input = input + 45;
var orbitalX = innerCX + (Math.cos( (input * Math.PI/180) ) * (bufferR));
var orbitalY = innerCY + (Math.sin( (input * Math.PI/180) ) * (bufferR));
console.log(orbitalX, orbitalY);
return [orbitalX, orbitalY];
};
svg.append('circle')
.attr('r', orbitR)
.attr('cx', orbitalXY(0)[0])
.attr('cy', orbitalXY(0)[1])
.attr('fill', '#8e44ad')
.attr('class', 'orbitalObject');
// Now we select our slider and chain an .on method with an input function.
// Anytime the range slider changes, it'll run update() with that new value.
d3.select("#nDegrees").on("input", function() {
update(+this.value);
});
// Our update function that updates the elements
function update(nDegrees) {
// This adjust the text of the range slider
d3.select("#nDegrees-value").text(nDegrees);
d3.select("#nDegrees").property("value", nDegrees);
// Now we can update the orbital object's location in degrees!
svg.select('.orbitalObject')
.attr('cx', orbitalXY(nDegrees)[0])
.attr('cy', orbitalXY(nDegrees)[1]);
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment