Built with blockbuilder.org
xxxxxxxxxx
<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