Skip to content

Instantly share code, notes, and snippets.

@mforando
Last active November 15, 2019 02:03
Show Gist options
  • Save mforando/8edee96991c75b3669d17729cb359f9f to your computer and use it in GitHub Desktop.
Save mforando/8edee96991c75b3669d17729cb359f9f to your computer and use it in GitHub Desktop.
D3 Banner Replication
license: mit
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.hexagon:hover {
fill: pink;
}
.hexagon {
fill: rgb(220,220,220);
}
.mesh {
fill: none;
stroke: #000;
stroke-opacity: .2;
pointer-events: none;
}
.border {
fill: none;
stroke: #000;
stroke-width: 2px;
pointer-events: none;
}
#svgcont{
width:720px;
height:220px;
overflow:hidden;
}
#svgcont svg{
margin:-40px;
}
</style>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<div id="svgcont">
</div>
<script>
var width = 800,
height = 300,
radius = 40;
var topology = hexTopology(radius, width, height);
var projection = hexProjection(radius);
var path = d3.geoPath()
.projection(projection);
var svg = d3.select("#svgcont")
.append("svg")
.attr("width", width)
.attr("height", height)
.attr("transform","translate(0,0)");
svg.append("g")
.selectAll("path")
.data(topology.objects.hexagons.geometries)
.enter().append("path")
.attr("class", "hexagon")
.attr("d", function(d) { return path(topojson.feature(topology, d)); })
.style("stroke","white");
var zoom = d3.zoom()
.on("zoom", zoom)
var xPosStart, yPosStart;
var minTransform = [-40,-40]
var maxTransform = [40,40]
svg.call(zoom)
.on("mouseover", setInitPos)
.on("mousemove",pan);
function setInitPos(){
xPosStart = d3.mouse(svg.node())[0];
yPosStart = d3.mouse(svg.node())[1];
}
function pan() {
var current_translate = getTranslation(svg.attr("transform"));
var deltaX = -(d3.mouse(svg.node())[0] - xPosStart)/50 + current_translate[0];
var deltaY = -(d3.mouse(svg.node())[1] - yPosStart)/30 + current_translate[1];
deltaX = Math.max(Math.min(deltaX, maxTransform[0]),minTransform[0])
deltaY = Math.max(Math.min(deltaY, maxTransform[1]),minTransform[1])
svg.attr("transform", "translate(" + [deltaX,deltaY] + ")");
d3.event.stopPropagation();
}
var mousing = 0;
function getTranslation(transform) {
var g = document.createElementNS("http://www.w3.org/2000/svg", "g");
g.setAttributeNS(null, "transform", transform);
var matrix = g.transform.baseVal.consolidate().matrix;
return [matrix.e, matrix.f];
}
function hexTopology(radius, width, height) {
var dx = radius * 2 * Math.sin(Math.PI / 3),
dy = radius * 1.5,
m = Math.ceil((height + radius) / dy) + 1,
n = Math.ceil(width / dx) + 1,
geometries = [],
arcs = [];
for (var j = -1; j <= m; ++j) {
for (var i = -1; i <= n; ++i) {
var y = j * 2, x = (i + (j & 1) / 2) * 2;
arcs.push([[x, y - 1], [1, 1]], [[x + 1, y], [0, 1]], [[x + 1, y + 1], [-1, 1]]);
}
}
for (var j = 0, q = 3; j < m; ++j, q += 6) {
for (var i = 0; i < n; ++i, q += 3) {
geometries.push({
type: "Polygon",
arcs: [[q, q + 1, q + 2, ~(q + (n + 2 - (j & 1)) * 3), ~(q - 2), ~(q - (n + 2 + (j & 1)) * 3 + 2)]],
fill: Math.random() > i / n * 2
});
}
}
return {
transform: {translate: [0, 0], scale: [1, 1]},
objects: {hexagons: {type: "GeometryCollection", geometries: geometries}},
arcs: arcs
};
}
function hexProjection(radius) {
var dx = radius * 2 * Math.sin(Math.PI / 3),
dy = radius * 1.5;
return {
stream: function(stream) {
return {
point: function(x, y) { stream.point(x * dx / 2, (y - (2 - (y & 1)) / 3) * dy / 2); },
lineStart: function() { stream.lineStart(); },
lineEnd: function() { stream.lineEnd(); },
polygonStart: function() { stream.polygonStart(); },
polygonEnd: function() { stream.polygonEnd(); }
};
}
};
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment