Welcome to CODEBOX! (Branch 945)
✨ นายอินทนนท์ แต่งตั้ง
<html> <head> <title>Let's Start</title> <style> html, body, header, main, h1, h2, h3, div { margin: 0; border: 0; padding: 0; box-sizing: border-box; } html { height: 100%; width: 100%; } body { height: 100%; width: 100%; background-image: url("https://media.discordapp.net/attachments/798209417455206421/806539481670090772/bg_31.png?width=1159&height=612"); cursor: url(https://i.imgur.com/6EdS32p.png), auto; } .wrapper { height: 100%; width: 100%; display: flex; flex-flow: row; justify-content: center; } .left-filler, .stats { width: 25%; } .container { height: 150%; width: 100%; display: flex; flex-flow: column; justify-content: flex-start; align-items: center; } .header-1 { height: 15%; justify-content: center; font-size: 5.5vmin; text-align: center; font-family: "Open Sans", sans-serif; color: #2F73BC; } .header, .header-2, .header-3, .reset, .stat__item1, .stat__item2, .stat__item3, .stat__item4 { margin-top: 2vmin; font-family: "Open Sans", sans-serif; color: #8951E0; } .header-2 { margin-left: 2vmin; font-size: 4.5vmin; color: #553684; } .header-3 { margin-top: 4vmin; font-size: 4vmin; margin-left: 2vmin; text-align: center; margin-bottom: 2vmin; } .stat__item1, .stat__item2, .stat__item3, .stat__item4 { margin-top: 0; margin-left: 2vmin; font-size: 3vmin; color: #B8439D; } .reset, .play-again { margin-left: 2vmin; height: 5vmin; width: 15vmin; text-transform: uppercase; color:#E64A45; background: none; font-size: 3vmin; border: 0.3vmin solid #f55; border-radius: 1vmin; font-family: "Open Sans", sans-serif; } .play-again { width: 18vmin; margin-top: 2vmin; margin-bottom: 2vmin; } .reset:hover, .play-again { transform: scale(1.2); box-shadow: 2px 2px 2px #8888; transition: ease 3s; cursor: url(https://i.imgur.com/TSvJMbv.png),auto; } .reset:active, .play-again { transform: scale(1); transition: ease-out 3s; } .main { height: 75%; width: 100%; display: flex; flex-flow: row wrap; justify-content: space-evenly; align-items: space-around; /* margin: 2vmin; */ margin-bottom: 2vmin; margin-top: 1vmin; cursor: url(https://i.imgur.com/TSvJMbv.png),auto; } [class^="item"] { height: 24%; width: 20%; /* width: 19%; */ margin: 1.15vmin; box-shadow: 7px 7px 7px #8888; border-radius: 1.25vmin; background-repeat: no-repeat; background-position: center; background-size: cover; /* flex: 1 0 20%; */ } [class^="item"]:hover { transform: scale(1.15); transition: ease 0.3s; } .modal { position: fixed; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); opacity: 0; visibility: hidden; transition: visibility 0s linear 0.25s, opacity 0.25s 0s, transform 0.25s; } .modal-content { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: white; padding: 1rem 1.5rem; width: 24rem; border-radius: 0.5rem; text-align: center; } .close-button { float: right; width: 1.5rem; line-height: 1.5rem; text-align: center; cursor: url(https://i.imgur.com/TSvJMbv.png),auto; border-radius: 0.25rem; } .close-button:hover { border: 0.25vmin solid darkgray; } .show-modal { opacity: 1; visibility: visible; transition: visibility 0s linear 0s, opacity 0.25s 0s, transform .5s; transform-style: preserve-3d; } .pic1 { background-image: url("https://media.discordapp.net/attachments/798209417455206421/806507717505318922/Prayuth_2018_cropped.png?width=441&height=612"); } .pic2 { background-image: url("https://media.discordapp.net/attachments/798209417455206421/806507777236140082/eddbb68864e2c832.jpg"); } .pic3 { background-image: url("https://media.discordapp.net/attachments/798209417455206421/806507817792045086/Prawit_Wongsuwan_28201829_cropped.png?width=390&height=613"); } .pic4 { background-image: url("https://media.discordapp.net/attachments/798209417455206421/806508608862683176/superspreder_2.jpg?width=488&height=612"); } .pic5 { background-image: url("https://media.discordapp.net/attachments/798209417455206421/806509995885592656/unknown.png"); } .pic6 { background-image: url("https://s.isanook.com/ca/0/rp/r/w728/ya0xa0m1w0/aHR0cHM6Ly9zLmlzYW5vb2suY29tL2NhLzAvdWQvMjc5LzEzOTg0MDMvcGFyZWVuYS5qcGc=.jpg"); } .pic7 { background-image: url("https://media.discordapp.net/attachments/798209417455206421/806510757566873631/8-8.png?width=535&height=613"); } .pic8 { background-image: url("https://media.discordapp.net/attachments/798209417455206421/806511023133425694/c9cba9f7be7bc274.jpg"); } .back { background-image: url("https://media.discordapp.net/attachments/798209417455206421/806538332858220574/614a890a92e49f255f06341deac57fc2.jpg"); } .circle { width: 3em; height: 3em; position: absolute; border-radius: 100%; background-color: #ffffff; opacity:0.2; animation: c 6s infinite; box-shadow: 0px 0px 4px #00000018; } .m { font-size: 2.5em; } .l { font-size: 5em; } @keyframes c { 0%,100%{ transform: scale(1); } 50%{ transform: scale(1.4); } } .flame { width: 10px; height: 10px; background: #ffffff99; border-radius: 100%; position: absolute; box-shadow: 0px 0px 12px #ffffff; animation: f 5s infinite linear; } @keyframes f { 0% { top: 120vh; opacity: 0; } 50% { top: 50vh; opacity: 1; } 100% { top: -10vh; opacity: 0; } } </style> </head> <body> <!-- Credit:"https://codepen.io/fran-cesca/pen/WYVWRx"--> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link href="https://fonts.googleapis.com/css?family=Fira+Sans+Extra+Condensed" rel="stylesheet"> <link rel="stylesheet" href="main.css"> <script src="index.js"></script> <title>Document</title> </head> <body> <div class="wrapper"> <div class="left-filler"></div> <div class="container"> <header class="header"> <h1 class="header-1"> Group E P'Pim <br> Memory Game </h1> </header> <main class="main"> </main> </div> <article class="stats"> <h2 class="header-2">Stats</h2> <div class="stat__item1">Number of clicks: 0</div> <div class="stat__item2">Timer: 0:0</div> <button class="reset">Reset</button> </article> </div> <div class="modal"> <div class="modal-content"> <span class="close-button">×</span> <h3 class="header-3">Game Over!</h3> <button class="play-again">Play Again</button> </div> </div> </body> <div class="flame" style="left:5%;animation-duration:3s"></div> <div class="flame" style="left:15%;animation-duration:4s"></div> <div class="flame" style="left:25%;animation-duration:5s"></div> <div class="flame" style="left:35%;animation-duration:6s"></div> <div class="flame" style="left:45%;animation-duration:4s"></div> <div class="flame" style="left:55%;animation-duration:12s"></div> <div class="flame" style="left:65%;animation-duration:9s"></div> <div class="flame" style="left:75%;animation-duration:4s"></div> <div class="flame" style="left:85%;animation-duration:5s"></div> <div class="flame" style="left:95%;animation-duration:6s"></div> <div class="circle s" style="top:50vh;right:80%"> </div> <div class="circle m" style="top:20vh;left:5%"> </div> <div class="circle s" style="top:50vh;left:100%"> </div> <div class="circle m" style="top:50vh;left:80%"> </div> </html> </body> </html> <script> let philosopherObjects, lastClicked, lastClickedClass, matched, clickCount, t, display, stopWatch, time; window.addEventListener("load", function () { init(); }); /* 13. Add a timer - stopwatch _/ 14. Add a completion screen - modal _? 15. Offer a reset button _/ 16. Only show stats on modal once */ class Card { constructor(philosopher) { this.philosopher = philosopher; } }; const sleep = (milliseconds) => { return new Promise(resolve => setTimeout(resolve, milliseconds)) } function reset() { let display = document.querySelector(".stat__item1"); display.textContent = `Number of clicks: 0`; let cards = document.querySelectorAll("main.main > div"); cards.forEach((card) => { card.remove(); }); clearTimeout(t); seconds = 0; minutes = 0; hours = 0; init(); }; function init() { lastClicked = ""; lastClickedClass = ""; let count = 0; let main = document.querySelector(".main"); clickCount = 0; stat3 = document.querySelector(".stat__item3"); stat4 = document.querySelector(".stat__item4"); let modal = document.querySelector(".modal"); let closeButton = document.querySelector(".close-button"); let gameOver = document.querySelector(".header-3"); function toggleModal() { modal.classList.toggle("show-modal"); } closeButton.addEventListener("click", toggleModal); let stopWatch = document.querySelector(".stat__item2"); let start = Date.now(); function add() { let millis = Date.now() - start; let result = Math.floor(millis / 1000); time = `${Math.floor(result/60)}:${result%60}` stopWatch.textContent = `Timer: ${time}`; timer(); } function timer() { t = setTimeout(add, 1000); } timer(); let resetBtn = document.querySelector(".reset"); let playAgain = document.querySelector(".play-again") resetBtn.addEventListener("click", reset); playAgain.addEventListener("click", function () { toggleModal(); document.querySelector(".stat__item3").remove(); document.querySelector(".stat__item4").remove(); reset(); }); let philosophers = ["pic6", "pic7", "pic4", "pic5", "pic3", "pic8", "pic1", "pic2"] philosopherObjects = []; matched = []; philosophers.forEach((philosopher) => { for (var i = 0; i < 2; i++) { const pair = new Card(philosopher) philosopherObjects.push(pair); } }); philosopherObjects.sort(() => Math.random() - 0.5); philosopherObjects.forEach((Card) => { main.insertAdjacentHTML("beforeend", `<div class="item${count} ${Card.philosopher} back"></div>`); let item = document.querySelector(`.item${count}`); item.addEventListener("click", function () { // prevent matched cards from being clicked again if (item.classList.contains("matched")) { return; } clickCount++; display = document.querySelector(".stat__item1"); display.textContent = `Number of clicks: ${clickCount}`; const name = Card.philosopher; item.classList.remove("back"); if (lastClicked === "") { lastClicked = name; lastClickedClass = item; } else if (lastClicked === name) { matched.push(name); matched.push(item); item.classList.add("matched"); lastClickedClass.classList.add("matched"); lastClicked = ""; lastClickedClass = ""; if (isFinished()) { clearTimeout(t); toggleModal(); gameOver.insertAdjacentHTML("afterend", `<div class="stat__item4">Time taken: ${time}</div>`); gameOver.insertAdjacentHTML("afterend", `<div class="stat__item3">Number of clicks: ${clickCount}</div>`); } // matched.Card.classList.remove(`item${count}`); } else if (lastClicked != name) { let tempLastClickedClass = lastClickedClass; lastClicked = ""; lastClickedClass = ""; sleep(500).then(() => { item.classList.add("back"); tempLastClickedClass.classList.add("back"); }); }; }); count++; }); }; function isFinished() { return document.querySelectorAll(".matched").length === 16; }; </script>