<div class='board'></div>
<div class='clone'>
<div class='face'></div>
<div class='face'></div>
<div class='face'></div>
<div class='face'></div>
<div class='face'></div>
<div class='face'></div>
</div>
<div class='overlay hidden'>
<div class='gameover'>
<p>Super gemacht!</p>
<button class='reset'>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000"><path d="M485.8 113.9L349.3 250.5c-3.5 3.5-3.5 9.1 0 12.6l136.6 136.6c5.6 5.6 15.2 1.6 15.2-6.3V120.2c-.1-7.9-9.7-11.9-15.3-6.3z" fill="#fff"/><path d="M500 194.8V317c125.9 0 228 102.1 228 228S625.9 773 500 773v121.8c193.3 0 350-156.7 350-350s-156.7-350-350-350zM272 545c0-55.1 19.6-105.7 52.1-145.1 6.5-7.9 5.9-19.5-1.4-26.8l-58.3-58.3c-8.2-8.2-21.7-7.7-29.3 1-53 61.5-85.1 141.5-85.1 229 0 193.3 156.7 350 350 350V773c-125.9 0-228-102.1-228-228z" fill="#fff"/></svg>
</button>
</div>
</div>
<!-- Preload Game Sounds -->
<audio preload="auto" class="audio-win" >
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/dino-win.mp3">
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/dino-win.ogg">
</audio>
<audio preload="auto" class="audio-ahahah" >
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-ahahah.mp3">
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-ahahah.ogg">
</audio>
<audio preload="auto" class="audio-dino" >
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audo-dino.mp3">
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-dino.ogg">
</audio>
<audio preload="auto" class="audio-egg" >
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-egg.mp3">
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-egg.ogg">
</audio>
<audio preload="auto" class="audio-erupt" >
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-erupt.mp3">
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-erupt.ogg">
</audio>
<audio preload="auto" class="audio-ptero" >
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-ptero.mp3">
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-ptero.ogg">
</audio>
<audio preload="auto" class="audio-tri" >
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-tri.mp3">
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/audio-tri.ogg">
</audio>
body {
align-items: center;
background-image: radial-gradient(circle 448px at center, #e0e0e0 0%, #ffffff 50%);
display: flex;
height: 100vh;
justify-content: center;
overflow: hidden;
perspective: 1200px;
}
.board {
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(4, 100px);
grid-template-rows: repeat(4, 100px);
position: relative;
top: 20px;
transform-style: preserve-3d;
transform: rotateX(20deg) rotateZ(2deg);
user-select: none;
}
.clone {
display: none;
}
.cube {
animation: enter 600ms ease-out;
transform-style: preserve-3d;
transform: translateZ(0) scale(1);
transition: all 350ms ease-out;
transform-origin: 50% 50%;
backface-visibility: hidden;
&.flipped {
pointer-events: none;
transform: rotateY(180deg) translateZ(0) scale(1);
transition: all 500ms ease-out;
}
&.matched {
pointer-events: none;
transform: rotateY(180deg) translateZ(0) scale(1);
animation: match 650ms ease-out;
}
}
.face {
outline: 1px solid transparent;
backface-visibility: hidden;
box-shadow: inset 0 0 1px 1px #fff;
height: 100px;
overflow: hidden;
position: absolute;
transform-origin: 50% 50%;
width: 100px;
}
.face:nth-child(1) {
background-color: #a72c80;
cursor: pointer;
transform: rotateY(0deg) translateZ(10px);
transition: background 150ms ease-out;
&:before {
align-items: center;
bottom: 0;
color: #fff;
content: '?';
display: flex;
font-family: 'Verdana', cursive;
font-size: 60px;
justify-content: center;
left: 0;
position: absolute;
right: 0;
top: 0;
}
}
.face:nth-child(2) {
background-color: darken(#a72c80, 10%);
width: 20px;
transform: rotateY(90deg) translateZ(90px)
}
.face:nth-child(3) {
background-color: dodgerblue;
transform: rotateY(180deg) translateZ(10px)
}
.face:nth-child(4) {
background-color: darken(#a72c80, 10%);
width: 20px;
transform: rotateY(270deg) translateZ(10px)
}
.face:nth-child(5) {
background-color: darken(#a72c80, 10%);
height: 20px;
transform: rotateX(90deg) translateZ(10px)
}
.face:nth-child(6) {
background-color: darken(#a72c80, 10%);
height: 20px;
transform: rotateX(-90deg) translateZ(90px)
}
.overlay {
align-items: center;
background: rgba(255,255,255,0.75);
width: 100vw;
display: flex;
justify-content: center;
left: 0;
opacity: 1;
position: absolute;
height: 100vh;
top: 0;
transition: all 500ms ease-out;
z-index: 100;
&.hidden {
opacity: 0;
pointer-events: none;
transition: all 300ms ease-out;
.gameover {
transform: translateY(60px);
transition: all 300ms ease-out;
}
}
}
.gameover {
align-items: center;
background-color: #fff;
border-radius: 120px;
border: 12px solid #50b8f7;
color: #2e2e2e;
display: flex;
font-family: 'Verdana', cursive;
font-size: 40px;
height: 120px;
width: 340px;
justify-content: space-between;
padding: 0 10px 0 30px;
transform: translateY(0);
transition: all 500ms ease-out;
user-select: none;
}
.reset {
background-color: #fbc300;
border-radius: 50%;
border: 0;
box-shadow: 0px 6px 0px 0px #f2a003;
cursor: pointer;
display: block;
height: 94px;
margin-left: 20px;
position: relative;
top: -3px;
width: 96px;
&:active {
box-shadow: none;
top: 0;
}
&:focus {
outline: 0;
}
}
.twitter__link {
user-select: none;
cursor: pointer;
position: absolute;
right: 10px;
top: 12px;
z-index: -1;
background: #fff;
border-radius: 20px;
height: 30px;
text-decoration: none;
padding-right: 10px;
justify-content: space-between;
font-family: sans-serif;
font-weight: 600;
display: flex;
align-items: center;
color: #00aced;
font-size: 14px;
width: 74px;
opacity: 0.4;
z-index: 10;
&:hover {
opacity: 1;
}
}
.twitter__icon {
height: 30px;
}
[data-tile="egg"] {
div:nth-child(3) {
background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/naseweis1.png) center center no-repeat;
background-size: contain;
}
}
[data-tile="egg"]~[data-tile="egg"] {
div:nth-child(3) {
background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/naseweis2.png) center center no-repeat;
background-size: contain;
}
}
[data-tile="dino"] {
div:nth-child(3) {
background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/hosentraeger1.png);
background-size: contain;
}
}
[data-tile="dino"]~[data-tile="dino"] {
div:nth-child(3) {
background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/hosentraeger2.png);
background-size: contain;
}
}
[data-tile="ahahah"] {
div:nth-child(3) {
background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/zoepfe1.png) center center no-repeat;
background-size: contain;
}
}
[data-tile="ahahah"]~[data-tile="ahahah"] {
div:nth-child(3) {
background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/zoepfe2.png) center center no-repeat;
background-size: contain;
}
}
[data-tile="tri"] {
div:nth-child(3) {
background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/fleissig1.png) center center no-repeat;
background-size: contain;
}
}
[data-tile="tri"]~[data-tile="tri"] {
div:nth-child(3) {
background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/fleissig2.png) center center no-repeat;
background-size: contain;
}
}
[data-tile="ptero"] {
div:nth-child(3) {
background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/oben1.png) center center no-repeat;
background-size: contain;
}
}
[data-tile="ptero"]~[data-tile="ptero"] {
div:nth-child(3) {
background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/oben2.png) center center no-repeat;
background-size: contain;
}
}
[data-tile="erupt"] {
div:nth-child(3) {
background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/gabel1.png) center center no-repeat;
background-size: contain;
}
}
[data-tile="erupt"]~[data-tile="erupt"] {
div:nth-child(3) {
background: #fff8e7 url(https://mundartatlas.de/wp-content/uploads/gabel2.png) center center no-repeat;
background-size: contain;
}
}
audio {
display: none;
}
@keyframes enter {
0% {
transform: translateZ(-20px) scale(0.3);
}
50% {
transform: translateZ(20px) scale(1.02);
}
100% {
transform: translateZ(0) scale(1);
}
}
@keyframes match {
0% {
transform: rotateY(180deg) translateZ(-15px);
}
50% {
transform: rotateY(180deg) translateZ(10px);
}
100% {
transform: rotateY(180deg) translateZ(0);
}
}
View Compiled
const board = document.querySelector('.board');
const clone = document.querySelector('.clone');
const overlay = document.querySelector('.overlay');
const reset = document.querySelector('.reset');
const tileOptions = ['erupt', 'ptero', 'tri', 'ahahah', 'egg', 'dino'];
const state = {
selections: [],
boardLocked: false,
matches: 0
};
reset.addEventListener('click', () => {
if (state.boardLocked) return;
resetGame();
});
function resetGame() {
state.boardLocked = true;
state.selections = [];
state.matches = 0;
document.querySelectorAll('.cube').forEach(tile => {
tile.removeEventListener('click', () => selectTile(tile));
tile.remove();
});
overlay.classList.add('hidden');
createBoard();
}
function createBoard() {
const tiles = shuffleArray([tileOptions, tileOptions]);
const length = tiles.length;
for (let i = 0; i < length; i++) {
window.setTimeout(() => {
board.appendChild(buildTile(tiles.pop(), i));
}, i * 100);
}
window.setTimeout(() => {
document.querySelectorAll('.cube').forEach(tile => {
tile.addEventListener('click', () => selectTile(tile));
});
state.boardLocked = false;
}, tiles.length * 100);
}
function buildTile(option, id) {
const tile = clone.cloneNode(true);
tile.classList.remove('clone');
tile.classList.add('cube');
tile.setAttribute('data-tile', option);
tile.setAttribute('data-id', id);
return tile;
}
function selectTile(selectedTile) {
if (state.boardLocked || selectedTile.classList.contains('flipped')) return;
state.boardLocked = true;
if (state.selections.length <= 1) {
selectedTile.classList.add('flipped');
state.selections.push({
id: selectedTile.dataset.id,
tile: selectedTile.dataset.tile,
el: selectedTile
});
}
/* =================================*
* Welcome to Timeout City *
* Time since last incident: 300ms *
* =================================*/
if (state.selections.length === 2) {
if (state.selections[0].tile === state.selections[1].tile) {
window.setTimeout(() => {
state.selections[0].el.classList.add('matched');
state.selections[1].el.classList.add('matched');
state.boardLocked = false;
state.matches = state.matches + 1;
if (state.matches === tileOptions.length) {
window.setTimeout(() => {
overlay.classList.remove('hidden');
document.querySelector('.audio-win').play();
}, 600);
}
state.selections = [];
document.querySelector(`.audio-${selectedTile.dataset.tile}`).play();
}, 600);
} else {
setTimeout(() => {
document.querySelectorAll('.cube').forEach(tile => {
tile.classList.remove('flipped');
});
state.boardLocked = false;
}, 800);
state.selections = [];
}
} else {
state.boardLocked = false;
}
}
// 🍝 Copy-Pasta - "ain't nobody got time for that"
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
createBoard();
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.