diff --git a/mj/.idea/.gitignore b/mj/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/mj/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/mj/.idea/misc.xml b/mj/.idea/misc.xml new file mode 100644 index 0000000..28a804d --- /dev/null +++ b/mj/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/mj/.idea/mj.iml b/mj/.idea/mj.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/mj/.idea/mj.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/mj/.idea/modules.xml b/mj/.idea/modules.xml new file mode 100644 index 0000000..45d0b26 --- /dev/null +++ b/mj/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/mj/card.js b/mj/card.js new file mode 100644 index 0000000..92b95a9 --- /dev/null +++ b/mj/card.js @@ -0,0 +1,97 @@ +let x1 = 0; +let x2 = 1000; +let y1 = 0; +let y2 = 1000; + +const width = 150; +const height = 220; +const hw = width / 2; +const hh = height / 2; +const r = Math.sqrt(width * width + height * height) / 2; +const a = Math.asin(hw / r) * 180 / Math.PI; +class Card { + constructor(word, clickHandler, setId, cardId) { + this.word = word; + this.setId = setId; + this.cardId = cardId; + this._onCLick = clickHandler; + this.selected = false; + + this._rotation = 0; + this.element = document.createElement("div"); + this.element.classList.add("card"); + this.element.innerText = word; + + this.x = 0; + this.y = 0; + + this.element.addEventListener("click", this._onElementClick.bind(this)); + } + destructor() { + this.element.remove(); + } + select() { + if (!this.selected) { + this.element.classList.add("selected"); + this.selected = true; + } + } + unselect() { + if (this.selected) { + this.element.classList.remove("selected"); + this.selected = false; + } + } + disrotate() { + let angle = Math.random() * 150 - 75; + this.rotate(angle); + } + rotate(angle) { + this._rotation = angle; + this.element.style.transform = "rotate(" + angle +"deg)" + } + position(x, y) { + this.element.style.position = "absolute"; + this.x = x; + this.y = y; + this.element.style.top = y + "px"; + this.element.style.left = x + "px"; + } + displace() { + let lA; + let cA = 90; + if (this._rotation > 0) { + lA = this._rotation - a; + cA += this._rotation + a; + } else { + lA = this._rotation + a; + cA -= this._rotation - a; + } + + let hl = r * Math.abs(Math.cos(lA * Math.PI/180)); + let hc = r * Math.abs(Math.cos(cA * Math.PI/180)) + let yDiff = hl - hh; + let xDiff = hc - hw; + let minY = yDiff + y1; + let maxY = y2 - height - yDiff; + let minX = xDiff + x1; + let maxX = x2 - width - xDiff; + + let x = Math.round(Math.random() * (maxX - minX) + minX); + let y = Math.round(Math.random() * (maxY - minY) + minY); + + this.position(x, y); + } + _onElementClick(e) { + this._onCLick(this); + } + + static setBounds(minX, minY, maxX, maxY) { + x1 = minX; + x2 = maxX - 7; + y1 = minY; + y2 = maxY - 7; + } +} + +export default Card \ No newline at end of file diff --git a/mj/index.html b/mj/index.html new file mode 100644 index 0000000..2d9224b --- /dev/null +++ b/mj/index.html @@ -0,0 +1,13 @@ + + + + + Match + + + + + +loading... + + \ No newline at end of file diff --git a/mj/main.css b/mj/main.css new file mode 100644 index 0000000..0942bbb --- /dev/null +++ b/mj/main.css @@ -0,0 +1,37 @@ +body { + margin: 0; + font-family: Sans; +} + +.card { + display: flex; + width: 150px; + height: 220px; + align-items: center; + justify-content: center; + background-color: #ddd; + margin: 5px; + float: left; + box-shadow: #000000 1px 1px 7px -1px; + font-size: 17pt; + color: #4c4c4c; + opacity: 1; + + transition: background-color 200ms ease-in-out, + opacity 200ms ease-in-out, + top 200ms ease-in-out, + left 200ms ease-in-out, + transform 100ms ease-in-out; +} + +.selected { + background-color: #76bce2; +} + +.card.selected:hover { + background-color: #76bce2; +} + +.card:hover { + background-color: #e3cfbb; +} \ No newline at end of file diff --git a/mj/main.js b/mj/main.js new file mode 100644 index 0000000..7f47755 --- /dev/null +++ b/mj/main.js @@ -0,0 +1,91 @@ +import Card from './card.js' + +document.body.innerText = ""; + +const vocabulary = [ + ["drive", "drove"], + ["send", "sent"], + ["understand", "understood"], + ["find", "found"], + ["write", "wrote"], + ["feel", "felt"], + ["fall", "fell"], + ["run", "ran"], + ["do", "did"], + ["speak", "spoke"], + ["awake", "awoke"], + ["bear", "bore"], + ["bend", "bent"], + ["bite", "bit"], + ["cling", "clung"], + ["breed", "bred"], + ["feed", "fed"] +]; + +let deck = []; +let selected = null; + +Card.setBounds(0, 0, window.innerWidth, window.innerHeight) +for (let i = 0; i < 50; ++i) { + let id = Math.floor(Math.random() * vocabulary.length); + let set = vocabulary[id]; + for (let s = 0; s < set.length; ++s) { + let card = new Card(set[s], onCardClick, id, s); + card.disrotate(); + card.displace(); + deck.push(card); + } +} + +deck = shuffle(deck); +for (let i = 0; i < deck.length; ++i) { + document.body.appendChild(deck[i].element); +} + +function onCardClick(card) { + if (selected != null) { + if (card === selected) { + return; + } + if (selected.setId === card.setId && selected.cardId !== card.cardId) { + score(selected, card); + selected = null; + return; + } + selected.unselect(); + } + selected = card; + card.select(); +} + +function score(c1, c2) { + deck.splice(deck.indexOf(c1), 1) + deck.splice(deck.indexOf(c2), 1); + + let x = window.innerWidth / 2 + let y = -500; + + c1.position(x, y); + c2.position(x, y); + c1.rotate(0); + c2.rotate(0); + c1.element.style.zIndex = "5"; + c2.element.style.zIndex = "5"; + + setTimeout(fade.bind(null, c1, c2), 200); +} + +function fade(c1, c2) { + c1.destructor(); + c2.destructor(); +} + +function shuffle(deck) { + let spare = deck.slice(); + let result = []; + while (spare.length > 0) { + let index = Math.floor(Math.random() * spare.length); + result.push(spare.splice(index, 1)[0]); + } + return result; +} \ No newline at end of file