D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
miketahani
Full window
Github gist
flocking example
<!doctype html> <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