How to move an object outside a smaller circle with d3.
Useful for drawing orbits... but mainly step 2 in figuring out a way to visualize differential drag in orbiting satellites. (Step 1)
Input slider courtesy of @adry34160
Built with blockbuilder.org
forked from sadbumblebee's block: Drawing a Circle Outside a Circle
forked from sadbumblebee's block: Moving a Circle Outside a Circle
xxxxxxxxxx
<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;
}
#timer {
margin-left: 48%;
padding-top: 2%;
}
</style>
</head>
<div id="timer">
<p></p>
</div>
<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)
const margin = {top: 20, right: 10, bottom: 20, left: 10};
const width = 600 - margin.left - margin.right;
const height = 400 - margin.top - margin.bottom;
const innerR = width/6;
const innerCY = height/2;
const innerCX = width/2;
const bufferR = width/4
const orbitR = width/50;
// Interval variable for adjusting the speed of our animation
// as with a lot of time in the browser, this is in milliseconds (1000ms == 1s)
var interval = 100;
// We also need to keep track of the orbiting circle's state, but without a global
// variable state cannot be tracked within the scope of our update() function.
var state = 0;
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');
svg.append('circle')
.attr('r', orbitR)
.attr('fill', '#8e44ad')
.attr('cx', orbitalXY(0)[0])
.attr('cy', orbitalXY(0)[1])
.attr('class', 'orbitalObject');
function orbitalXY(input) {
var orbitalX = innerCX - (Math.sin( (input * Math.PI/180) ) * (bufferR));
var orbitalY = innerCY - (Math.cos( (input * Math.PI/180) ) * (bufferR));
return [orbitalX, orbitalY];
};
// This time around, we need to set an interval to run the animation
setInterval(function(){
update();
}, interval)
// Our update function that updates the element based on time (established by
// our setInterval function above).
function update() {
svg.select('.orbitalObject')
.transition(99)
.attr('cx', orbitalXY(state)[0])
.attr('cy', orbitalXY(state)[1]);
// Just so we can keep track of our circle in degrees, we'll update the
// div with the id of timer with the current state.
d3.selectAll('p').remove();
d3.select('#timer')
.append('p')
.text(state + '°');
// This is a shorthand for adding to state in conditional ternary operator
// unless it's 360, which we might as well resolve back to 0 (though our
// orbitalXY() function can handle that math still).
state < 360 ? state++ : state = 0;
};
</script>
</body>
https://d3js.org/d3.v4.min.js