A simple implementation of fog of war using hexbinning. Mouseover the darkened region to reveal the data (or lack of data) underneath. If you mouse over a region with no data, it will reveal any hexes nearby that also don't have data underneath.
xxxxxxxxxx
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Fog of War with Hexbin</title>
<style>
</style>
</head>
<body>
<svg width="500" height="500" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.min.js" charset="utf-8" type="text/javascript"></script>
<script src="d3.hexbin.js" charset="utf-8" type="text/javascript"></script>
<script type="text/javascript">
vertices = [[162, 332], [182, 299], [141, 292], [158, 264], [141, 408], [160, 400], [177, 430], [151, 442], [155, 425], [134, 430], [126, 447], [139, 466], [160, 471], [167, 447], [182, 466], [192, 442], [187, 413], [173, 403], [168, 425], [153, 413], [179, 275], [163, 292], [134, 270], [143, 315], [177, 320], [163, 311], [162, 281], [182, 255], [141, 226], [156, 235], [173, 207], [187, 230], [204, 194], [165, 189], [145, 201], [158, 167], [190, 165], [206, 145], [179, 153], [204, 114], [221, 138], [243, 112], [248, 139], [177, 122], [179, 99], [196, 82], [219, 90], [240, 75], [218, 61], [228, 53], [211, 34], [197, 51], [179, 65], [155, 70], [165, 85], [134, 80], [124, 58], [153, 44], [173, 34], [192, 27], [156, 19], [119, 32], [128, 17], [138, 36], [100, 58], [112, 73], [100, 92], [78, 100], [83, 78], [61, 63], [80, 44], [100, 26], [60, 39], [43, 71], [34, 54], [32, 90], [53, 104], [60, 82], [66, 99], [247, 94], [187, 180], [221, 168]];
hexbin = d3.hexbin()
.size([500,500])
.radius(25)
.x(function (d) {return d.x})
.y(function (d) {return d.y})
fullpoints = [];
vertices.forEach(function (d) {
fullpoints.push({x: d[0], y: d[1], type: "data"})
})
d3.range(20).forEach(function (d) {
d3.range(20).forEach(function (p) {
fullpoints.push({x: d * 25, y: p * 25, type: "hex"})
})
})
hexdata = hexbin(fullpoints);
d3.select("svg").selectAll("circle")
.data(fullpoints.filter(function (d) {return d.type === "data"}))
.enter()
.append("circle")
.attr("cx", function (d) {return d.x})
.attr("cy", function (d) {return d.y})
.style("fill", "#001276")
.attr("r", 2);
d3.select("svg").selectAll("path")
.data(hexdata)
.enter()
.append("path")
.attr("d", function (d) {return hexbin.hexagon(25); })
.attr("transform", function(d) { console.log(d); return "translate(" + d.x + "," + d.y + ")"; })
.style("fill", "#001276")
.style("stroke", "#001276")
.on("mouseover", defog)
function defog(d) {
d3.select(this)
.transition()
.duration(1000)
.style("opacity", 0);
d3.selectAll("path")
.filter(function (p) {
return Math.abs(p.x - d.x) < 65 && Math.abs(p.y - d.y) < 65 && d.filter(function (d) {return d.type === "data"}).length === 0 && p.filter(function (p) {return p.type === "data"}).length === 0;
})
.transition()
.duration(1000)
.style("opacity", 0);
}
</script>
</body>
</html>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.min.js