UNPKG

@leofavre/memory-game-component

Version:

A memory game web component.

98 lines (84 loc) 2.17 kB
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> `; };