@leofavre/memory-game-component
Version:
A memory game web component.
98 lines (84 loc) • 2.17 kB
JavaScript
import { html } from '@leofavre/elmnt';
import '@leofavre/flip-card-component';
import sequence from '../helpers/sequence.js';
import {
getNumberOfCards,
getCardAtPosition,
isCardRevealed,
isCardMatched
} from '../state/memoryGameSelectors.js';
const renderCard = ({ state, handleClick }) => position => {
const { name, img } = getCardAtPosition(position, state);
const revealed = isCardRevealed(position, state) ||
isCardMatched(position, state);
return html`
<flip-card
?revealed=${revealed}
@click=${handleClick(position)}
class="memory-game--card">
<span class="memory-game--bg"></span>
<span class="memory-game--text">${name}</span>
<img class="memory-game--media" src="${img}">
</flip-card>
`;
};
export default props => {
const interactiveClass = props.state.isInteractive
? ' memory-game--wrapper-interactive'
: '';
return html`
<style>
:host {
--flip-card-perspective: none;
--flip-card-proportion: 3.5/4.2;
--flip-card-border: #91a4a4;
--flip-card-border-radius: 2px;
--flip-card-background: #aab9b9;
display: block;
width: 100%;
font-family: "Whitney SSm A", "Whitney SSm B", sans-serif;
font-style: normal;
font-weight: 400;
perspective: 1800px;
}
.memory-game--wrapper {
display: grid;
grid-template-columns: repeat(var(--memory-game-cards-per-line, 6), 1fr);
grid-gap: var(--memory-game-gap, 20px) var(--memory-game-gap, 20px);
pointer-events: none;
}
.memory-game--wrapper-interactive {
pointer-events: all;
}
.memory-game--wrapper-interactive .memory-game--card {
cursor: pointer;
}
.memory-game--media {
position: absolute;
display: block;
top: calc(4% * var(--flip-card-proportion));
left: 4%;
width: 92%;
height: auto;
background: #fff;
}
.memory-game--text {
position: absolute;
top: 82.5%;
left: 4%;
font-size: 12px;
}
.memory-game--bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #fff;
}
</style>
<div class="memory-game--wrapper${interactiveClass}">
${sequence(getNumberOfCards(props.state)).map(renderCard(props))}
</div>
`;
};