xxxxxxxxxx
<html>
<head>
<meta charset='utf-8'>
<style>
* {
box-sizing: border-box;
}
body,
svg,
canvas {
margin: 0;
padding: 0;
}
#container,
svg,
canvas,
#overlay {
position: fixed;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div id='container'></div>
<div id='overlay'></div>
<script src='https://d3js.org/d3.v3.min.js' charset='utf-8'></script>
<script>
let w = window.innerWidth,
h = window.innerHeight
let canvas = d3.select('#container').append('canvas').attr({width: w, height: h}),
ctx = canvas.node().getContext('2d')
ctx.strokeStyle = '#000'
</script>
<script>
class Agent {
constructor () {
this._x = Math.random()
this._y = Math.random()
this._angle = Math.random()
}
pos (x, y) {
if (!arguments.length) {
return [this._x, this._y]
}
[this._x, this._y] = [x, y]
return this
}
dxy (x, y) {
return [x - this._x, y - this._y]
}
dist (x, y) {
let [dx, dy] = this.dxy(x, y)
return Math.sqrt(dx*dx + dy*dy)
}
getAngle (x, y) {
if (!arguments.length) return this._angle
let [dx, dy] = this.dxy(x, y)
return Math.atan2(dy, dx)
}
setAngle (angle) {
this._angle = angle
}
}
</script>
<script>
let qs = window.location.search.substr(1).split('&'),
args = qs.reduce((argz, arg) => {
arg = arg.split('=')
argz[arg[0]] = +arg[1]
return argz
}, {})
const SPEED = args.speed || 0.007,
INFLUENCE = args.infl || 0.00005,
INFL_EXP = args.infl_exp || 2.0,
INFL_MAX_ANGLE = args.max_angle || 0.5,
circleDefaults = [10, 0, 2 * Math.PI]
const n = 20,
agents = d3.range(n).map(d => new Agent())
function render () {
requestAnimationFrame(render)
let i = n || agents.length
while (i--) {
let a1 = agents[i],
a1Pos = a1.pos(),
j = n || agents.length,
angle = a1.getAngle()
while (j--) {
if (i !== j) {
let a2 = agents[j],
a2Pos = a2.pos(),
dist = a1.dist(...a2Pos),
deltaAngle = a1.getAngle(...a2Pos),
weight = INFLUENCE / Math.pow(dist, INFL_EXP)
angle += Math.max(-INFL_MAX_ANGLE, Math.min(INFL_MAX_ANGLE, deltaAngle * weight))
}
}
a1.setAngle(angle)
let [x, y] = [a1Pos[0] + Math.cos(angle) * SPEED, a1Pos[1] + Math.sin(angle) * SPEED]
if (x < 0) x += 1
if (x > 1) x -= 1
if (y < 0) y += 1
if (y > 1) y -= 1
a1.pos(x, y)
// console.log(x, y)
}
update(agents)
}
render()
function update (agents) {
ctx.clearRect(0, 0, w, h)
let i = n || agents.length
while (i--) {
let pos = agents[i].pos()
ctx.beginPath()
ctx.arc(pos[0] * w, pos[1] * h, ...circleDefaults)
ctx.stroke()
}
}
</script>
</body>
</html>
https://d3js.org/d3.v3.min.js