panel with a timer, shuffle button
This commit is contained in:
parent
c01ac52bbd
commit
15dbe4487f
5
mj/.idea/.gitignore
generated
vendored
5
mj/.idea/.gitignore
generated
vendored
@ -1,5 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
6
mj/.idea/misc.xml
generated
6
mj/.idea/misc.xml
generated
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
</project>
|
12
mj/.idea/mj.iml
generated
12
mj/.idea/mj.iml
generated
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
8
mj/.idea/modules.xml
generated
8
mj/.idea/modules.xml
generated
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/mj.iml" filepath="$PROJECT_DIR$/.idea/mj.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
17
mj/icons/refresh.svg
Normal file
17
mj/icons/refresh.svg
Normal file
@ -0,0 +1,17 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#eff0f1;
|
||||
}
|
||||
.ColorScheme-Highlight {
|
||||
color:#3daee9;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 11 3 C 9.558286 3 8.2107109 3.3829219 7.0449219 4.0449219 L 7.7832031 4.7832031 C 7.7832031 4.7832031 7.7851562 4.78125 7.7851562 4.78125 L 10.564453 7.5585938 L 11.271484 6.8515625 L 8.7890625 4.3710938 C 9.4846855 4.1384172 10.223912 4 11 4 C 14.87797 4 18 7.122 18 11 C 18 12.1625 17.714172 13.253897 17.216797 14.216797 L 17.955078 14.955078 C 18.617129 13.789278 19 12.4417 19 11 C 19 6.568 15.431966 3 11 3 z M 4.0449219 7.0449219 C 3.3828709 8.2107219 3 9.5583 3 11 C 3 15.432 6.568034 19 11 19 C 12.441714 19 13.789289 18.617078 14.955078 17.955078 L 14.271484 17.271484 L 14.273438 17.269531 L 11.445312 14.441406 L 10.738281 15.148438 L 13.216797 17.626953 C 12.519497 17.860874 11.778264 18 11 18 C 7.12203 18 4 14.878 4 11 C 4 9.8375 4.2858291 8.7461031 4.7832031 7.7832031 L 4.0449219 7.0449219 z "
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
57
mj/main.css
57
mj/main.css
@ -1,21 +1,52 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: Sans;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.fs,
|
||||
body,
|
||||
html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.card,
|
||||
.cp {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.button {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
transition: background-color 200ms ease-in-out;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.cp {
|
||||
color: white;
|
||||
font-family: monospace;
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
width: 150px;
|
||||
height: 220px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #ddd;
|
||||
background-color: #d8ecbe;
|
||||
margin: 5px;
|
||||
float: left;
|
||||
box-shadow: #000000 1px 1px 7px -1px;
|
||||
box-shadow: #000000 1px 1px 5px -1px;
|
||||
font-size: 17pt;
|
||||
color: #4c4c4c;
|
||||
opacity: 1;
|
||||
user-select: none;
|
||||
|
||||
transition: background-color 200ms ease-in-out,
|
||||
opacity 200ms ease-in-out,
|
||||
@ -25,13 +56,23 @@ body {
|
||||
}
|
||||
|
||||
.selected {
|
||||
background-color: #76bce2;
|
||||
background-color: #8bc9ee;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.card.selected:hover {
|
||||
background-color: #76bce2;
|
||||
background-color: #8bc9ee;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
background-color: #e3cfbb;
|
||||
}
|
||||
|
||||
.panel {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background-color: #198cfc;
|
||||
box-shadow: #000000 0px 1px 4px 0px;
|
||||
}
|
34
mj/main.js
34
mj/main.js
@ -1,4 +1,5 @@
|
||||
import Card from './card.js'
|
||||
import Card from './card.js';
|
||||
import Panel from './panel.js';
|
||||
|
||||
document.body.innerText = "";
|
||||
|
||||
@ -25,8 +26,21 @@ const vocabulary = [
|
||||
let deck = [];
|
||||
let selected = null;
|
||||
|
||||
Card.setBounds(0, 0, window.innerWidth, window.innerHeight)
|
||||
for (let i = 0; i < 50; ++i) {
|
||||
let panel = new Panel();
|
||||
let field = document.createElement("div");
|
||||
field.classList.add("fs");
|
||||
field.style.position = "relative";
|
||||
panel.append(document.body);
|
||||
panel.installShuffle(reshuffle);
|
||||
document.body.appendChild(field);
|
||||
|
||||
window.onresize = function() {
|
||||
Card.setBounds(0, 0, field.offsetWidth, field.offsetHeight);
|
||||
reshuffle();
|
||||
}
|
||||
|
||||
Card.setBounds(0, 0, field.offsetWidth, field.offsetHeight);
|
||||
for (let i = 0; i < 30; ++i) {
|
||||
let id = Math.floor(Math.random() * vocabulary.length);
|
||||
let set = vocabulary[id];
|
||||
for (let s = 0; s < set.length; ++s) {
|
||||
@ -39,15 +53,18 @@ for (let i = 0; i < 50; ++i) {
|
||||
|
||||
deck = shuffle(deck);
|
||||
for (let i = 0; i < deck.length; ++i) {
|
||||
document.body.appendChild(deck[i].element);
|
||||
field.appendChild(deck[i].element);
|
||||
}
|
||||
|
||||
panel.startTimer();
|
||||
|
||||
function onCardClick(card) {
|
||||
if (selected != null) {
|
||||
if (card === selected) {
|
||||
return;
|
||||
}
|
||||
if (selected.setId === card.setId && selected.cardId !== card.cardId) {
|
||||
card.select();
|
||||
score(selected, card);
|
||||
selected = null;
|
||||
return;
|
||||
@ -69,12 +86,17 @@ function score(c1, c2) {
|
||||
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 reshuffle() {
|
||||
for (let i = 0; i < deck.length; ++i) {
|
||||
deck[i].disrotate();
|
||||
deck[i].displace();
|
||||
}
|
||||
}
|
||||
|
||||
function fade(c1, c2) {
|
||||
c1.destructor();
|
||||
c2.destructor();
|
||||
|
123
mj/panel.js
Normal file
123
mj/panel.js
Normal file
@ -0,0 +1,123 @@
|
||||
const height = 100;
|
||||
|
||||
class Panel {
|
||||
constructor() {
|
||||
this.element = document.createElement("div");
|
||||
this.element.classList.add("panel")
|
||||
this.element.style.height = height + "px";
|
||||
|
||||
this._createLeftPanel();
|
||||
this._createRightPanel();
|
||||
this._createCentralPanel();
|
||||
|
||||
this._shuffle = null;
|
||||
|
||||
this._time = null;
|
||||
|
||||
this._updateInterval = setInterval(this._update.bind(this), 53);
|
||||
}
|
||||
destructor() {
|
||||
this.element.remove();
|
||||
}
|
||||
append(element) {
|
||||
element.style.position = "relative";
|
||||
element.style.paddingTop = height + "px";
|
||||
element.appendChild(this.element);
|
||||
}
|
||||
installShuffle(func) {
|
||||
this._shuffle = func;
|
||||
}
|
||||
startTimer() {
|
||||
this._time = Date.now();
|
||||
}
|
||||
_createLeftPanel() {
|
||||
this._leftPanel = document.createElement("div");
|
||||
this._leftPanel.style.position = "absolute";
|
||||
this._leftPanel.style.top = "0";
|
||||
this._leftPanel.style.left = "0";
|
||||
|
||||
this._shuffleButton = document.createElement("div");
|
||||
this._shuffleButton.classList.add("button");
|
||||
this._shuffleButton.style.backgroundImage = "url(icons/refresh.svg)";
|
||||
this._shuffleButton.style.height = height + "px";
|
||||
this._shuffleButton.style.width = height + "px";
|
||||
this._shuffleButton.style.position = "absolute";
|
||||
this._shuffleButton.style.top = "0";
|
||||
this._shuffleButton.style.left = "0";
|
||||
this._shuffleButton.title = "Shuffle";
|
||||
this._shuffleButton.addEventListener("click", this._onShuffle.bind(this));
|
||||
|
||||
this._leftPanel.appendChild(this._shuffleButton);
|
||||
|
||||
this.element.style.paddingLeft = height + "px";
|
||||
this.element.appendChild(this._leftPanel);
|
||||
}
|
||||
_createRightPanel() {
|
||||
this._rightPanel = document.createElement("div");
|
||||
this._rightPanel.style.position = "absolute";
|
||||
this._rightPanel.style.top = "0";
|
||||
this._rightPanel.style.right = "0";
|
||||
this.element.appendChild(this._rightPanel);
|
||||
}
|
||||
_createCentralPanel() {
|
||||
this._centralPanel = document.createElement("div");
|
||||
this._centralPanel.classList.add("fs", "cp");
|
||||
this._centralPanel.style.display = "flex";
|
||||
this._centralPanel.style.alignItems = "center";
|
||||
this._centralPanel.style.justifyContent = "center";
|
||||
|
||||
this._ms = document.createElement("span");
|
||||
this._mds = document.createElement("span");
|
||||
this._ss = document.createElement("span");
|
||||
this._sdmin = document.createElement("span");
|
||||
this._mins = document.createElement("span");
|
||||
|
||||
this._ms.innerText = "000";
|
||||
this._mds.innerText = ":";
|
||||
this._ss.innerText = "00";
|
||||
this._sdmin.innerText = ":";
|
||||
this._mins.innerText = "00";
|
||||
|
||||
this._centralPanel.appendChild(this._mins);
|
||||
this._centralPanel.appendChild(this._sdmin);
|
||||
this._centralPanel.appendChild(this._ss);
|
||||
this._centralPanel.appendChild(this._mds);
|
||||
this._centralPanel.appendChild(this._ms);
|
||||
|
||||
this.element.appendChild(this._centralPanel);
|
||||
}
|
||||
_update() {
|
||||
if (this._time !== null) {
|
||||
let time = Date.now() - this._time;
|
||||
let minutes = Math.floor(time / (1000 * 60));
|
||||
time = time % (1000 * 60);
|
||||
let seconds = Math.floor(time / 1000);
|
||||
time = time % 1000;
|
||||
|
||||
this._mins.innerText = pad(minutes, 2);
|
||||
this._ss.innerText = pad(seconds, 2);
|
||||
this._ms.innerText = pad(time, 3);
|
||||
}
|
||||
}
|
||||
_onShuffle() {
|
||||
if (this._shuffle !== null) {
|
||||
this._shuffle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function pad (num, amount) {
|
||||
let p = pads[amount];
|
||||
let sNum = num.toString();
|
||||
let pref = p[sNum.length];
|
||||
return pref + sNum;
|
||||
}
|
||||
|
||||
const pads = [
|
||||
[""],
|
||||
["0", ""],
|
||||
["00", "0", ""],
|
||||
["000", "00", "0", ""]
|
||||
]
|
||||
|
||||
export default Panel;
|
Loading…
Reference in New Issue
Block a user