Use d3's path generator to draw a circle. Over time, add jitter to the x and y coordinates of the circle to make it squirm.
Last active
September 26, 2019 02:16
-
-
Save jameshenegan/c7a2272ae8b7205e941778fbdceeff0d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | |
<title>Document</title> | |
<script src="https://d3js.org/d3.v5.min.js"></script> | |
</head> | |
<p></p> | |
<script> | |
// Create Canvas | |
const width = 400 | |
const height = 400 | |
const margin = 100 | |
const sd = 15 | |
const svgContainer = d3.select("p").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
const xScale = d3.scaleLinear().domain([-1, 1]).range([margin, width - margin]) | |
const yScale = d3.scaleLinear().domain([-1, 1]).range([height - margin, margin]) | |
const lineFunction = d3.line() | |
.x(d => xScale(d.x)) | |
.y(d => yScale(d.y)) | |
.curve(d3.curveBasisClosed) | |
// Generate Initial Data | |
// Create a linear space from 0 to 2pi containing 50 points | |
const domain = [] | |
const start = 0 | |
const stop = 2 * Math.PI | |
const num_points = 20 | |
const scaleFactor = (stop - start) / num_points | |
for (var i = 0; i <= num_points; i++) { | |
domain.push(scaleFactor * i) | |
} | |
const points = [] | |
for (var i = 0; i <= num_points; i++) { | |
points.push({ "x": Math.cos(domain[i]), "y": Math.sin(domain[i]) }) | |
} | |
// Draw First Circle | |
var lineGraph = svgContainer.append("path") | |
.attr("d", lineFunction(points)) | |
.attr("stroke", "blue") | |
.attr("stroke-width", 2) | |
.attr("fill", "blue") | |
.attr("stroke", "gray") | |
.attr("stroke-width", 5); | |
// Make the circle wiggle | |
// Standard Normal variate using Box-Muller transform. | |
function randn_bm() { | |
var u = 0, v = 0; | |
while (u === 0) u = Math.random(); //Converting [0,1) to (0,1) | |
while (v === 0) v = Math.random(); | |
return ( | |
{ | |
"x_jitter": Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v) / sd, | |
"y_jitter": Math.sqrt(-2.0 * Math.log(u)) * Math.sin(2.0 * Math.PI * v) / sd | |
}) | |
; | |
} | |
d3.interval(() => { | |
const jitter = [] | |
const new_points = [] | |
for (var i = 0; i <= num_points; i++) { | |
const output = randn_bm() | |
jitter.push( | |
{ | |
"x_jitter": output.x_jitter, | |
"y_jitter": output.y_jitter | |
}) | |
new_points.push( | |
{ | |
"x": points[i].x + jitter[i].x_jitter, | |
"y": points[i].y + jitter[i].y_jitter | |
} | |
) | |
} | |
svgContainer.selectAll("path").data(new_points).transition().duration(4000) | |
.attr("d", lineFunction(new_points)) | |
}, 1500) | |
</script> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment