Simulation of the interleaving effect resulting of two different groups of particles colliding. The red group follows the mouse cursor, while the blue group is focused on the canvas center.
Uses d3.forceX, d3.forceY, and d3.forceCollide as forces, and d3ForcePod for the simulation scaffolding.
xxxxxxxxxx
<head>
<style>body { margin: 0; }</style>
<script src="//unpkg.com/d3-force-pod"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/5.5.0/d3.min.js"></script>
</head>
<body>
<script>
const NODE_R = 6;
const pod = d3ForcePod()(document.body)
.genNodes({
density: 5e-4,
radiusRange: [NODE_R, NODE_R],
velocityRange: [0, 0]
});
pod.simulation().velocityDecay(0.2)
// split into two groups
const numNodes = pod.nodes().length;
pod.nodes().forEach((d, i) => d.group = i < numNodes / 2 ? 0 : 1);
pod.nodeColor(({ group }) => group ? 'midnightblue' : 'crimson');
// Set x/y attraction forces
const center = { x: window.innerWidth / 2, y: window.innerHeight / 2 };
const forceX = d3.forceX().strength(0.01).x(center.x);
const forceY = d3.forceY().strength(0.01).y(center.y);
pod.addForce(forceX);
pod.addForce(forceY);
// Have one of the groups follow cursor
d3.select('body').on('mousemove', function () {
const [x, y] = d3.mouse(this);
forceX.x(d => d.group ? center.x : x);
forceY.y(d => d.group ? center.y : y);
});
// Add collision force
pod.addForce(d3.forceCollide()
.radius(NODE_R + 2)
.strength(0.9)
);
</script>
</body>
https://unpkg.com/d3-force-pod
https://cdnjs.cloudflare.com/ajax/libs/d3/5.5.0/d3.min.js