Published
Edited
Jun 7, 2022
1 star
Insert cell
Insert cell
{
// simulation
const sim = new AA.Simulation({
width: 700,
height: 400,
gridStep: 25,
afterTick: () => sim.state.trap = sim.tickIndex % 600 < 360
}).vis({baseColor: 0xeeeeee,});
invalidation.then(() => sim.end());

// speed of all circles
const speed = 1.2;

// big circles
const bigCircles = sim.populate({
n: 6,
padding:100,
radius: 50,
setup: (ac, i) => {
ac.maxSpeed = speed;
ac.vel = AA.Vector.randomAngle(speed);
ac.contains = () => sim.state.trap ? ac.enclosing('actor') : null
ac.label('kind', i < 3 ? 'calm' : 'busy');
ac.vis({
tint: AV.colors[i < 3 ? 'pink' : 'kiwi'],
alpha: ac => sim.state.trap ? 1 : 0.2
});
}
});

// small circles
const smallCircles = sim.populate({
n: 300,
random: true,
exclude: bigCircles,
radius: 3,
setup: ac => {
ac.maxSpeed = speed;
ac.vel = AA.Vector.randomAngle(speed);
ac.vis({tint: AV.colors.blue})
}
});

// all circles bounce off simulation boundary
sim.interaction.set('boundary-bounce', {
group1: sim,
group2: sim.actors,
behavior: 'bounce',
});

// big circles bounce off each other
sim.interaction.set('big-big-bounce', {
group1: bigCircles,
behavior: 'bounce',
speed
});

// small circles bounce off each other
sim.interaction.set('small-small-bounce', {
group1: smallCircles,
behavior: 'bounce',
speed
});

// big circles have an inward repel force to trap small circles
sim.interaction.set('big-small-trap', {
group1: bigCircles,
group2: smallCircles,
behavior: 'repel',
inward: true,
off: 3,
disabled: () => !sim.state.trap
});

// small circles inside 'calm' circles repel each other
// (convert set to array so index of forEach works)
[...sim.withLabel('kind', 'calm')].forEach((ac, i) => {
sim.interaction.set(`calm-repel-${i}`, {
group1: () => ac.containsCurrent || [],
behavior: 'repel',
strength: 0.5,
off: 10
});
});

// also add a drag force inside calm circles
sim.interaction.set('calm-drag', {
group1: sim.withLabel('kind', 'calm'),
group2: smallCircles,
behavior: 'drag',
strength: 0.2,
disabled: () => !sim.state.trap
});

// vis
return AV.visObs(sim);
}
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more