D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
tonyhschu
Full window
Github gist
Generating hex grid positions
Built with
blockbuilder.org
<!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; } </style> </head> <body> <script> console.clear() var SQRT_3_2 = Math.sqrt(3)/2 var SCALE = 10 var toScreen = function(cube) { var q = cube[0] var r = cube[1] var s = cube[2] return { x: SCALE * (r-q) * SQRT_3_2, y: SCALE * (0.5*(r+q) - s) } } // Feel free to change or delete any of the code you see in this editor! var svg = d3.select("body").append("svg") .attr("width", 960) .attr("height", 500) var g = svg.append('g') .attr('transform', 'translate(480, 250)') var hexPositionFactory = function() { let i = 0 let ring = 0 let currentPosition = [0, 0, 0] let currentDirection = 0 let stepsInCurrentDirection = 0 let directions = [ [+1, -1, 0], [+1, 0, -1], [0, +1, -1], [-1, +1, 0], [-1, 0, +1], [0, -1, +1] ] let move = function(cur, dir) { return [cur[0] + dir[0], cur[1] + dir[1], cur[2] + dir[2]] } return function() { if (i === 0) { i += 1 ring = 1 currentPosition = [0, 0, 0] return currentPosition } let absoluteSum = currentPosition.reduce((c, p) => { return Math.abs(p) + Math.abs(c) }, 0) if (absoluteSum / 2 < ring) { stepsInCurrentDirection = 1 currentPosition = [-ring, 0, ring] } else { currentPosition = move(currentPosition, directions[currentDirection]) if (stepsInCurrentDirection >= ring) { currentDirection = currentDirection + 1 if (currentDirection > directions.length - 1) { ring += 1 currentDirection = 0 currentPosition = [-ring, 0, ring] } stepsInCurrentDirection = 1 } else { stepsInCurrentDirection += 1 } } i += 1 return currentPosition.slice(0) } } let mouseDistance = 0 svg .on("mousemove", function(e) { let m = d3.mouse(this) let dx = 480 - m[0] let dy = 250 - m[1] mouseDistance = Math.sqrt(dx * dx + dy * dy) }) let paint = function() { let hexPosition = hexPositionFactory() let numberOfCircles = Math.floor(mouseDistance) let coordinates = d3.range(numberOfCircles).map((i) => { return hexPosition() }).map((cube, i) => { return { key: i, cube: cube, screen: toScreen(cube) } }) let points = g.selectAll('circle') .data(coordinates, function(d) { return d.key }) points .enter() .append('circle') .attr('r', 6) .merge(points) .attr('fill', function(d) { let r = d.cube[0] * 5 + 150 let g = d.cube[1] * 5 + 150 let b = d.cube[2] * 5 + 150 return 'rgb(' + r + ', ' + g + ', ' + b + ')' }) .attr('cx', function(d) { return d.screen.x }) .attr('cy', function(d) { return d.screen.y }) points.exit().remove() window.requestAnimationFrame(paint) } window.requestAnimationFrame(paint) </script> </body>
https://d3js.org/d3.v4.min.js