Built with blockbuilder.org
forked from tonyhschu's block: Generating hex grid positions
license: mit |
Built with blockbuilder.org
forked from tonyhschu's block: Generating hex grid positions
<!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> |