153 lines
3.8 KiB
JavaScript
153 lines
3.8 KiB
JavaScript
import React from "react";
|
|
import styled from "styled-components";
|
|
import { CSSTransition, TransitionGroup } from "react-transition-group";
|
|
|
|
const DEFAULT_WIDTH = 1;
|
|
const DEFAULT_HEIGHT = 1.5;
|
|
|
|
const Card = styled.div`
|
|
display: inline-block;
|
|
position: relative;
|
|
margin-right: 0.2em;
|
|
width: ${props => (props.zoom || 1) * DEFAULT_WIDTH}rem;
|
|
height: ${props => (props.zoom || 1) * DEFAULT_HEIGHT}rem;
|
|
content: "${props => props.value}";
|
|
border: 1px solid gray;
|
|
border-radius: 1px;
|
|
text-align: center;
|
|
line-height: ${props => (props.zoom || 1) * (DEFAULT_HEIGHT + 0)}rem;
|
|
vertical-align: middle;
|
|
background-color: ${props => props.theme.body.color};
|
|
color: ${props => props.theme.body.background};
|
|
font-size: ${props => (props.zoom || 1) * 1.5}rem;
|
|
font-family: Rubik,monospace;
|
|
font-weight: 500;
|
|
box-shadow: 1px 1px 3px #d0bfa3;
|
|
text-shadow: 0 0 1px black;
|
|
overflow: hidden;
|
|
|
|
&::before {
|
|
content: "";
|
|
display: block;
|
|
position: absolute;
|
|
top: 0;
|
|
height: 50%;
|
|
width: 100%;
|
|
left: 0;
|
|
border-bottom: solid 2px #bdb19a;
|
|
}
|
|
|
|
&::after {
|
|
content: "";
|
|
display: block;
|
|
position: absolute;
|
|
top: 0;
|
|
height: 50%;
|
|
width: 100%;
|
|
border-bottom: dotted 2px #ad5a75;
|
|
z-index:1;
|
|
}
|
|
`;
|
|
|
|
const StyledScoreboard = styled.div`
|
|
height: ${props => (props.zoom || 1) * DEFAULT_HEIGHT}rem;
|
|
margin-bottom: 1rem;
|
|
white-space: nowrap;
|
|
|
|
& > div {
|
|
position: relative;
|
|
display: inline-block;
|
|
width: ${props => (props.zoom || 1) * DEFAULT_WIDTH}rem;
|
|
height: ${props => (props.zoom || 1) * DEFAULT_HEIGHT}rem;
|
|
margin-right: ${props => (props.zoom || 1) * 0.3}rem;
|
|
}
|
|
`;
|
|
|
|
const CardCSSTransition = styled(CSSTransition)`
|
|
position: absolute;
|
|
|
|
&.card-enter,
|
|
&.card-appear {
|
|
${Card} {
|
|
transform: rotateX(90deg);
|
|
z-index: 1;
|
|
opacity: 0;
|
|
}
|
|
|
|
&.card-appear-active {
|
|
${Card} {
|
|
transition: transform ease-out 250ms, opacity ease-out 100ms;
|
|
transform: rotateX(0deg);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
&.card-enter-active {
|
|
${Card} {
|
|
transition: transform ease-out 250ms 250ms, opacity ease-out 100ms;
|
|
transform: rotateX(0deg);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
&.card-exit {
|
|
${Card} {
|
|
transform: rotateX(0deg);
|
|
transition: transform ease-out 250ms, opacity ease-out 100ms 150ms;
|
|
opacity: 1;
|
|
}
|
|
|
|
&.card-exit-active {
|
|
${Card} {
|
|
transition: transform ease-out 250ms, opacity ease-out 100ms 150ms;
|
|
transform: rotateX(90deg);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
}
|
|
&.card-exit-done {
|
|
${Card} {
|
|
transform: rotateX(90deg);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
`;
|
|
|
|
export const Scoreboard = ({ score, zoom = 1 } = {}) => {
|
|
const scoreCards = Array.from(`${score}`.padStart(3, "0"));
|
|
return (
|
|
<StyledScoreboard zoom={zoom}>
|
|
<TransitionGroup>
|
|
<CardCSSTransition key={`card0-${scoreCards[0] || "x"}`} timeout={1000} classNames="card">
|
|
<div>
|
|
<Card value={scoreCards[0]} zoom={zoom}>
|
|
{scoreCards[0] || "0"}
|
|
</Card>
|
|
</div>
|
|
</CardCSSTransition>
|
|
</TransitionGroup>
|
|
<TransitionGroup>
|
|
<CardCSSTransition key={`card1-${scoreCards[1] || "x"}`} timeout={1000} classNames="card">
|
|
<div>
|
|
<Card value={scoreCards[1]} zoom={zoom}>
|
|
{scoreCards[1] || "0"}
|
|
</Card>
|
|
</div>
|
|
</CardCSSTransition>
|
|
</TransitionGroup>
|
|
<TransitionGroup>
|
|
<CardCSSTransition key={`card2-${scoreCards[2] || "x"}`} timeout={1000} classNames="card">
|
|
<div>
|
|
<Card value={scoreCards[2]} zoom={zoom}>
|
|
{scoreCards[2]}
|
|
</Card>
|
|
</div>
|
|
</CardCSSTransition>
|
|
</TransitionGroup>
|
|
</StyledScoreboard>
|
|
);
|
|
};
|
|
|
|
export default Scoreboard;
|