initial commit
commit
2995f40d62
|
@ -0,0 +1,100 @@
|
||||||
|
function cardDB() {
|
||||||
|
return {
|
||||||
|
// Major arcana
|
||||||
|
"the fool": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 1
|
||||||
|
},
|
||||||
|
"the magician": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 2
|
||||||
|
},
|
||||||
|
"the high priestess": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 3
|
||||||
|
},
|
||||||
|
"the empress": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 4
|
||||||
|
},
|
||||||
|
"the emperor": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 5
|
||||||
|
},
|
||||||
|
"the hierophant": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 6
|
||||||
|
},
|
||||||
|
"the lovers": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 7
|
||||||
|
},
|
||||||
|
"the chariot": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 8
|
||||||
|
},
|
||||||
|
"justice": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 9
|
||||||
|
},
|
||||||
|
"the hermit": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 10
|
||||||
|
},
|
||||||
|
"wheel of fortune": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 11
|
||||||
|
},
|
||||||
|
"strength": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 12
|
||||||
|
},
|
||||||
|
"death": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 13
|
||||||
|
},
|
||||||
|
"temperance": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 14
|
||||||
|
},
|
||||||
|
"the devil": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 15
|
||||||
|
},
|
||||||
|
"the tower": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 16
|
||||||
|
},
|
||||||
|
"the star": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 17
|
||||||
|
},
|
||||||
|
"the moon": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 18
|
||||||
|
},
|
||||||
|
"the sun": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 19
|
||||||
|
},
|
||||||
|
"judgement": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 20
|
||||||
|
},
|
||||||
|
"the world": {
|
||||||
|
"arcana": "major",
|
||||||
|
"index": 21
|
||||||
|
},
|
||||||
|
|
||||||
|
// Minor arcana
|
||||||
|
"ace of cups": {
|
||||||
|
"arcana": "minor",
|
||||||
|
"index": 1,
|
||||||
|
"suit": "cups"
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default cardDB;
|
|
@ -0,0 +1,32 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>tarot</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>hermetic</h1>
|
||||||
|
|
||||||
|
<button id="reset">reset</button>
|
||||||
|
<br>
|
||||||
|
<div id="deck"></div>
|
||||||
|
<div id="info" style="height: 325px; width: 500px;"></div>
|
||||||
|
<div id="table"></div>
|
||||||
|
|
||||||
|
<div class="blueprint card">
|
||||||
|
<pre></pre>
|
||||||
|
<span></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="module" src="main.js"></script>
|
||||||
|
<style>
|
||||||
|
.blueprint {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,4 @@
|
||||||
|
import Tarot from './tarot.js'
|
||||||
|
|
||||||
|
window.tarot = new Tarot();
|
||||||
|
window.tarot.render();
|
|
@ -0,0 +1,171 @@
|
||||||
|
import cardDB from './cards.js';
|
||||||
|
|
||||||
|
// TODO reset state button
|
||||||
|
|
||||||
|
class Tarot {
|
||||||
|
constructor() {
|
||||||
|
this.cardDB = cardDB();
|
||||||
|
this.deck = new CardPile();
|
||||||
|
for (const cardName in this.cardDB) {
|
||||||
|
this.deck.add(cardName);
|
||||||
|
}
|
||||||
|
this.table = new CardPile();
|
||||||
|
|
||||||
|
const deckElem = document.querySelector("#deck");
|
||||||
|
const tableElem = document.querySelector("#table");
|
||||||
|
const infoElem = document.querySelector("#info");
|
||||||
|
const resetElem = document.querySelector("#reset");
|
||||||
|
|
||||||
|
// TODO bring those top level functions in as methods
|
||||||
|
this.renderers = [
|
||||||
|
new Renderer(
|
||||||
|
deckElem,
|
||||||
|
deckRender(this.deck)),
|
||||||
|
|
||||||
|
new Renderer(
|
||||||
|
tableElem,
|
||||||
|
tableRender(this, this.table)),
|
||||||
|
|
||||||
|
new Renderer(
|
||||||
|
infoElem,
|
||||||
|
infoRender(tableElem, deckElem))
|
||||||
|
];
|
||||||
|
|
||||||
|
// handlers
|
||||||
|
// TODO make it feel similar to the renderers? or just have a general way to list out events
|
||||||
|
// that should trigger a render
|
||||||
|
tableElem.addEventListener("mouseenter", this.render.bind(this));
|
||||||
|
tableElem.addEventListener("mouseleave", this.render.bind(this));
|
||||||
|
deckElem.addEventListener("click", this.drawCard.bind(this));
|
||||||
|
resetElem.addEventListener("click", this.reset.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
let card = this.table.drawRandom();
|
||||||
|
while (card != null) {
|
||||||
|
this.deck.add(card);
|
||||||
|
card = this.table.drawRandom();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
drawCard() {
|
||||||
|
let cardName = this.deck.drawRandom();
|
||||||
|
if (cardName === null) {
|
||||||
|
this.render();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.table.add(cardName);
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
for (const renderer of this.renderers) {
|
||||||
|
renderer.render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function infoRender(tableElem) {
|
||||||
|
return function(elem) {
|
||||||
|
const cardElem = tableElem.querySelector(".card:hover");
|
||||||
|
if (cardElem == null) {
|
||||||
|
elem.innerHTML = "";
|
||||||
|
return
|
||||||
|
}
|
||||||
|
elem.innerHTML = cardElem.querySelector("span").innerHTML;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function tableRender(tarot, table) {
|
||||||
|
return function(elem) {
|
||||||
|
const cardsOut = elem.querySelectorAll('.card');
|
||||||
|
for (let cardElem of cardsOut) {
|
||||||
|
if (!table.has(cardElem.getAttribute('data-cardName'))) {
|
||||||
|
cardElem.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let cardName of table.cards) {
|
||||||
|
const found = elem.querySelector(`[data-cardName="${cardName}"]`);
|
||||||
|
if (found != null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let bp = document.querySelector(".card.blueprint");
|
||||||
|
let cardElem = bp.cloneNode(true);
|
||||||
|
cardElem.classList.remove("blueprint");
|
||||||
|
cardElem.setAttribute("data-cardName", cardName)
|
||||||
|
cardElem.setAttribute("style", "float:left; width: 150px; height: 250px; border: 1px solid pink;");
|
||||||
|
cardElem.querySelector("span").innerHTML = cardName;
|
||||||
|
cardElem.addEventListener("mouseenter", tarot.render.bind(tarot));
|
||||||
|
elem.append(cardElem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deckRender(deck) {
|
||||||
|
return function(elem) {
|
||||||
|
const width = deck.size;
|
||||||
|
elem.setAttribute("style", `float:left; height: 250px; width: 150px; border-left: 1px solid white; border-top: 1px solid white; border-bottom: ${width}px solid white; border-right: ${width}px solid white`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deckClick(deckElem, deck) {
|
||||||
|
return function() {
|
||||||
|
console.log(deckElem, deck);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Renderer {
|
||||||
|
constructor(element, renderFn) {
|
||||||
|
this.element = element;
|
||||||
|
this.renderFn = renderFn;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
this.renderFn(this.element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CardPile {
|
||||||
|
constructor() {
|
||||||
|
this.cards = new Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
add(cardName) {
|
||||||
|
this.cards.add(cardName);
|
||||||
|
}
|
||||||
|
|
||||||
|
has(cardName) {
|
||||||
|
return this.cards.has(cardName);
|
||||||
|
}
|
||||||
|
|
||||||
|
get size() {
|
||||||
|
return this.cards.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawRandom() {
|
||||||
|
const size = this.cards.size
|
||||||
|
if (size === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const index = Math.floor(Math.random() * Math.floor(size));
|
||||||
|
let i = 0;
|
||||||
|
let cardName = "";
|
||||||
|
for (let card of this.cards) {
|
||||||
|
if (i === index) {
|
||||||
|
cardName = card;
|
||||||
|
break
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
this.cards.delete(cardName);
|
||||||
|
|
||||||
|
return cardName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Tarot;
|
Loading…
Reference in New Issue