Created
December 23, 2020 20:07
-
-
Save oskarrough/da46aa7c866e9a8a7672184481398953 to your computer and use it in GitHub Desktop.
stwmap
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
<button onClick="generate()">Generate</button> | |
<slay-map rows="10" columns="6"></slay-map> |
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
// Returns a random number between min (inclusive) and max (inclusive) | |
function randomBetween(min, max) { | |
return Math.floor( | |
Math.random() * (max - min + 1) + min | |
) | |
} | |
// Returns a new, shuffled version of an array. | |
// See https://bost.ocks.org/mike/shuffle/ | |
function shuffle(array) { | |
// Make a copy | |
array = array.slice() | |
var m = array.length | |
var t | |
var i | |
// While there remain elements to shuffle⦠| |
while (m) { | |
// Pick a remaining element⦠| |
i = Math.floor(Math.random() * m--) | |
// And swap it with the current element. | |
t = array[m] | |
array[m] = array[i] | |
array[i] = t | |
} | |
return array | |
} | |
// Returns a "graph" of the map we want to render, | |
// using nested arrays for the rows and columns. | |
function generateGraph(rows, columns) { | |
const graph = [] | |
const size = columns * rows | |
for (let r = 0; r<rows; r++) { | |
const row = [] | |
// In each row we want from a to b encounters. | |
const encounters = randomBetween(2,5) | |
for (let i = 0; i<encounters; i++) { | |
row.push({type: 'encounter'}) | |
} | |
// Fill empty columns. | |
while (row.length < columns) { | |
row.push({type: false}) | |
} | |
// Randomize the order. | |
graph.push(shuffle(row)) | |
} | |
return graph | |
} | |
// This is an example of how you can render the graph as a map. | |
class SlayMap extends HTMLElement { | |
connectedCallback() { | |
this.state = { | |
rows: this.getAttribute('rows'), | |
columns: this.getAttribute('columns') | |
} | |
this.render() | |
} | |
randomEncounter() { | |
return shuffle(Array.from('ππππ°β'))[0] | |
} | |
render() { | |
const {rows, columns} = this.state | |
const graph = generateGraph(rows, columns) | |
this.innerHTML = ` | |
<slay-map-row center> | |
<slay-map-encounter>ππ</slay-map-encounter> | |
</slay-map-row> | |
${graph.map((row) => ` | |
<slay-map-row> | |
${row.map((col) => { | |
if (col.type === 'encounter') { | |
return `<slay-map-encounter>${this.randomEncounter()}</slay-map-encounter>` | |
} | |
return `<slay-map-node></slay-map-node>` | |
}).join('')} | |
</slay-map-row> | |
`).join('')} | |
<slay-map-row center> | |
<slay-map-encounter>ποΈ</slay-map-encounter> | |
</slay-map-row> | |
<svg class="paths"><rect width="20" height="20" fill="red" /></svg> | |
` | |
this.scatter() | |
this.drawPaths() | |
} | |
// Move the encounters around a bit. | |
scatter() { | |
const nodes = this.querySelectorAll('slay-map-encounter') | |
nodes.forEach(node => { | |
node.style.transform = `translate3d( | |
${randomBetween(-35,35)}%, | |
${randomBetween(-40,40)}%, | |
0) | |
` | |
}) | |
} | |
// Playing around with connecting the nodes #naive | |
drawPaths() { | |
const parent = this.getBoundingClientRect() | |
function getPos(el) { | |
const rect = el.getBoundingClientRect() | |
return { | |
top: rect.top - parent.top, | |
left: rect.left - parent.left, | |
width: rect.width, | |
height: rect.height | |
} | |
} | |
const connectNodes = (a, b) => { | |
if (!a || !b) return | |
const svg = this.querySelector('svg.paths') | |
const line = document.createElementNS('http://www.w3.org/2000/svg', 'line') | |
const aPos = getPos(a) | |
const bPos = getPos(b) | |
line.setAttribute('x1', aPos.left + aPos.width / 2) | |
line.setAttribute('y1', aPos.top + aPos.height / 2) | |
line.setAttribute('x2', bPos.left + bPos.width / 2) | |
line.setAttribute('y2', bPos.top + bPos.height / 2) | |
svg.appendChild(line) | |
console.log({a, b, line}) | |
} | |
const getEncounter = (row, index) => this.querySelector(`slay-map-row:nth-child(${row}) slay-map-encounter:nth-of-type(${index})`) | |
const rows = this.querySelectorAll('slay-map-row') | |
rows.forEach((row, i) => { | |
connectNodes(getEncounter(i, 1), getEncounter(i+1, 1)) | |
// connectNodes(getEncounter(i, 2), getEncounter(i+1, 2)) | |
// connectNodes(getEncounter(i, 3), getEncounter(i+1, 3)) | |
// connectNodes(getEncounter(i, 4), getEncounter(i+1, 4)) | |
// const encounters = rows[i].querySelectorAll('slay-map-encounter') | |
// encounters.forEach(encounter => { | |
// let nextEncounters = rows[i+1].querySelectorAll('slay-map-encounter') | |
// nextEncounters.forEach(encounter2 => { | |
// connectNodes(encounter, getEncounter(i+2, 1)) | |
// }) | |
// }) | |
}) | |
// connect bottom | |
connectNodes(getEncounter(12, 1), getEncounter(11, 2)) | |
connectNodes(getEncounter(12, 1), getEncounter(11, 3)) | |
connectNodes(getEncounter(12, 1), getEncounter(11, 4)) | |
connectNodes(getEncounter(12, 1), getEncounter(11, 5)) | |
connectNodes(getEncounter(11, 2), getEncounter(10, 2)) | |
connectNodes(getEncounter(10, 2), getEncounter(9, 2)) | |
// connectNodes(getEncounter(1, 1), getEncounter(2, 3)) | |
// connectNodes(getEncounter(1, 1), getEncounter(2, 4)) | |
// connectNodes(getEncounter(1, 1), getEncounter(2, 5)) | |
} | |
} | |
customElements.define('slay-map', SlayMap) | |
function generate() { | |
let slayMap = document.querySelector('slay-map') | |
slayMap.render() | |
} | |
// https://github.com/oskarrough/slaytheweb/issues/28 | |
// https://i.imgur.com/oAofMa0.jpg | |
// https://github.com/yurkth/stsmapgen | |
// https://github.com/SunnySunMoon/Slay-the-Spire-Map | |
///// ARCHIVE BELOW | |
/* | |
createMap({columns, rows}) { | |
const graph = generateGraph(columns, rows) | |
const element = this | |
graph.forEach((row, rowIndex) => { | |
const r = document.createElement('div') | |
r.classList.add('Map-row') | |
for (let i = 0; i<columns; i++) { | |
// Render columns. | |
var c = document.createElement('div') | |
const type = row[i].type | |
c.classList.add(`Map-${type}`) | |
if (type === 'encounter') { | |
//ππππ°β | |
c.textContent = shuffle(Array.from("ππππ°β"))[0] | |
} | |
// c.style.transform = `translateY(${randomBetween(-50,50)}%)` | |
r.appendChild(c) | |
} | |
element.appendChild(r) | |
}) | |
return element | |
} | |
render2() { | |
this.innerHTML = '' | |
this.createMap({ | |
columns: 6, | |
rows: 10 | |
}) | |
} | |
*/ |
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
slay-map { | |
box-sizing: border-box; | |
display: grid; | |
/* grid-template-rows: repeat(12, 1fr); */ | |
/* grid-gap: 1em; */ | |
background: darkgreen; | |
width: 28rem; | |
max-width: 100%; | |
height: 40rem; | |
border: 4px solid black; | |
/* margin: 1em 0; */ | |
padding: 1em; | |
position: relative; | |
} | |
slay-map-row { | |
display: grid; | |
grid-template-columns: repeat(6, 1fr); | |
grid-gap: 1em; | |
/* background: hsla(0,0%,0%, 0.1); */ | |
} | |
slay-map-row[center] { | |
grid-template-columns: repeat(12, 1fr); | |
} | |
slay-map-row[center] slay-map-encounter { | |
grid-column-start: 6; | |
grid-column-end: 8; | |
transform: none !important; | |
background: hsla(0,0%,0%, 0.5); | |
} | |
slay-map-node, | |
slay-map-encounter { | |
margin: 0.25rem; | |
/* border: 1px solid; */ | |
border-radius: 50%; | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
} | |
slay-map-encounter { | |
background: hsla(0,0%,0%, 0.05); | |
color: gold; | |
} | |
slay-map-encounter:hover { | |
background: hsla(0,0%,0%, 0.9); | |
transition: background 250ms; | |
cursor: pointer; | |
} | |
slay-map svg.paths { | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
pointer-events: none; | |
} | |
slay-map svg.paths line { | |
stroke: black; | |
stroke-width: 3px; | |
stroke-dasharray: 7px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment