Built with blockbuilder.org
Last active
November 15, 2019 02:03
-
-
Save mforando/8edee96991c75b3669d17729cb359f9f to your computer and use it in GitHub Desktop.
D3 Banner Replication
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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