Built with blockbuilder.org
forked from GitNoise's block: force sim. along one axis w. bounds
license: mit |
Built with blockbuilder.org
forked from GitNoise's block: force sim. along one axis w. bounds
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
body { padding: 50px} | |
svg { border: 1px solid #ff3333;} | |
</style> | |
</head> | |
<body> | |
<script> | |
const height = 350, | |
width = 300, | |
dotradius = 20; | |
// Feel free to change or delete any of the code you see in this editor! | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height) | |
const data = [ | |
{ y: 30, x: width/2}, | |
{ y: 30, x: width/2}, | |
{ y: 30, x: width/2}, | |
{ y: 30, x: width/2}, | |
{ y: 30, x: width/2}, | |
{ y: 30, x: width/2}, | |
{ y: 30, x: width/2}, | |
]; | |
svg.append("g").classed("pre", true).selectAll("circle") | |
.data(data) | |
.enter() | |
.append("circle") | |
.attr("cx", d => d.x) | |
.attr("cy", d => d.y) | |
.attr("r", dotradius) | |
.style("fill", "black") | |
.style("fill-opacity",0.2) | |
.style("stroke", "black") | |
.style("stroke-opacity",0.5) | |
const force = d3.forceSimulation() | |
.nodes(data) | |
.force('forceManyBody', d3.forceManyBody().strength(-1000)) | |
//.force('collide', d3.forceCollide(dotradius).strength(1)) | |
//.force('x', d3.forceX().strength(0.1)) | |
.force('axis', box_force) | |
.stop(); | |
function box_force() { | |
for (var i = 0, n = data.length; i < n; ++i) { | |
let curr_node = data[i]; | |
curr_node.x = width/2; | |
curr_node.y = Math.max(dotradius, Math.min(height - dotradius, curr_node.y)); | |
} | |
} | |
for(let i=0; i<100; i++) force.tick(); | |
svg.append("g").classed("post", true).selectAll("circle") | |
.data(data) | |
.enter() | |
.append("circle") | |
.attr("cx", d => d.x + dotradius * 5) | |
.attr("cy", d => d.y) | |
.attr("r", dotradius) | |
.style("fill", "red") | |
.style("stroke", "red") | |
.style("stroke-opacity", 0.5) | |
.style("fill-opacity", 0.5) | |
</script> | |
</body> |