D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
headwinds
Full window
Github gist
hexagon achievements
Built with
blockbuilder.org
<!DOCTYPE html> <head> <meta charset="utf-8"> <script src="https://d3js.org/d3.v5.min.js"></script> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <script> const topMargin = 35, hexR = 40, nLevels = 2, // map size - draw 7 hexagon planeColor = "white", // sea blue #c7efff70 total = 1; function getTerrain(label,color){ return { label, color, } } /* #ffbd00 - gold #0e1a36 - royal #008281 - teal #fafafa #c1c1c1 - line #f2f2f2; */ const terrain = [getTerrain('teal','#008281'), getTerrain('gold','#ffbd00'), getTerrain('royal','#0e1a36'), getTerrain('teal','#008281'), getTerrain('teal','#008281'), getTerrain('gold','#ffbd00'), getTerrain('teal','#008281'), getTerrain('teal','#008281'), getTerrain('gold','#ffbd00'), getTerrain('teal','#008281'), getTerrain('gold','#ffbd00'), getTerrain('royal','#0e1a36')]; //const noteScale = d3.scaleOrdinal(d3.schemeCategory20c) //.domain(terrain) function getSelectedIntervals() { return { hor: 4, diag: 3 } } var svg = d3.select("body").append("svg") .attr('id','svg') .attr("width", window.innerWidth) .attr("height", window.innerHeight) const world = svg.append('g') .attr('id', 'world'); world.append('g') .attr('id','sea') .attr("width", window.innerWidth) .attr("height", window.innerHeight) .append('rect') .attr("width", window.innerWidth) .attr("height", window.innerHeight) .style('fill',planeColor) world.append('g') .append("text") .text("mine") .attr("y", 10) .attr("x", 10) .attr("font-size", 20) .attr("font-family", "monospace") function getPolygonPath(r, nSides, startAngle) { let d = '' d3.range(nSides).map(side => { const angle = startAngle + 2 * Math.PI * side / nSides return [r * Math.cos(angle), r * Math.sin(angle)] }).forEach(pt => { d += (d.length ? 'L' : 'M') + pt.join(',') }) return d + 'Z' } const transitionTime = 900, hexPath = getPolygonPath(hexR, 6, Math.PI / 2) function genHexList(r, centerXy, centralFreq, levels) { levels += (levels % 2) ? 0 : 1 // Round up to nearest odd number const {hor, diag} = getSelectedIntervals(), diagonalUp = diag, diagonalDown = hor - diag, leftFreq = total * getIntervalRatio(-hor * (levels - 1) / 2), leftXy = centerXy let noteCnt = {} // Keep track of which notes are added to assign a unique ID to each leftXy[0] -= (levels - 1) * r // Left side of the row // Central row let hexs = buildRow(r, leftXy, leftFreq, levels) d3.range(1, (levels - 1) / 2 + 1).forEach(i => { const offset = [i * r * 2 * Math.cos(Math.PI / 3), i * r * 2 * Math.sin(Math.PI / 3)] hexs.push( // Up-right ...buildRow(r, [leftXy[0] + offset[0], leftXy[1] - offset[1]], leftFreq * getIntervalRatio(i * diagonalUp), levels - i), // Down-right ...buildRow(r, [leftXy[0] + offset[0], leftXy[1] + offset[1]], leftFreq * getIntervalRatio(i * diagonalDown), levels - i) ) }) return hexs // function buildRow(r, xy, freq, levels) { const hexs = [], horizInterval = getIntervalRatio(hor) let carryX = xy[0], carryFreq = freq while (levels) { const noteNum = 50; // if (noteNum>=12 && noteNum <= 126) { const index = Math.floor(Math.random() * 10); //const terrain = terrain[index]; const name = terrain[index].label // Assign unique id (noteName + counter) if (!noteCnt.hasOwnProperty(name)) noteCnt[name] = 0 noteCnt[name]++ const id = `${name}-${noteCnt[name]}` hexs.push({ x: carryX, y: xy[1], freq: carryFreq, name, color: terrain[index].color, id: id }) } carryX += r * 2 carryFreq *= horizInterval levels-- } return hexs } function getIntervalRatio(num) { // Equal temperament return Math.pow(2, num / 12) } } function drawMap(){ let hexs = d3.select('#world') .selectAll('.hex') .data(genHexList(hexR, [window.innerWidth / 2, (window.innerHeight - topMargin) / 2], total, nLevels), d => d.id) // Old hexs hexs.exit().transition().duration(transitionTime) // Shrink and fade-out .attr('transform', d => `translate(${d.x},${d.y}) scale(0)`) .style('opacity', 0) .remove() // New hexs const newHexs = hexs.enter().append('g') .attr('class', 'hex') .attr('transform', d => `translate(${d.x},${d.y}) scale(0)`); newHexs .transition() .duration(5000) .attr('transform', d => `translate(${d.x},${d.y}) scale(1,1)`); const getFill = d => { return d.color; } newHexs.append('path') .attr('d', hexPath) .style('stroke-width', '4px') .style('stroke', getFill) .style('fill', "white") newHexs.append('text') .attr('text-anchor', 'middle') .attr('dy', '.35em') .text(d => d.name) console.log('drawn!') } drawMap() </script> </body>
https://d3js.org/d3.v5.min.js