JSFiddle - React, Tailwind, and code Playground

by Diana Lemen

HTML

<div class="wrapper">
<button id="triggerUp" class="switchBtns"></button>
  <div class="rect static"></div>
  <div class="rect move"></div>
  <div class="value" id="score"></div>
<button id="triggerDown" class="switchBtns"></button>
  <div class="leftPiece pieces"></div>
  <div class="rightPiece pieces"></div>
  <div class="horizontalLine"></div>
</div>

CSS

@import url('https://fonts.googleapis.com/css?family=Roboto:300,400,500');

.switchBtns {
  width: 0;
  height: 0;
  padding: 0;
  position: absolute;
  left: 1 px;
  outline: none;
  cursor: pointer;
}

.switchBtns:active,
.switchBtns:focus {
   box-shadow: none;
}

#triggerUp {
  border-top: 0;
  border-left: 9px solid transparent;
  border-right: 9px solid transparent;
  border-bottom: 13px solid #2b2b2b;
  top: 30px;
  left: 20px;
}

#triggerDown {
  border-left: 9px solid transparent;
  border-right: 9px solid transparent;
  border-top: 13px solid #2b2b2b;
  border-bottom: 0;
  top: 107px;
  left: 20px;
}

.rect {
  position: absolute;
  top: 0px;
  width: 56px;
  height: 25px;
  left: 1px;
}

.static {
  background: black;
  top: 50px;
}

.move {
  top: 75px;
  color: #ddd;
  font-size: 3em;
  line-height: 100px;
  text-align: center;
  background: #444;
  transform-origin: 0 0;
}

.action {
  animation: move 1s forwards;
}

.actionDown {
  animation: static 1s forwards;
}

.wrapper {
  position: absolute;
  left: 40%;
  top: 0;
}

.value {
  color: white;
  position: absolute;
  z-index: 999;
  top: 52px;
  font-family: sans-serif;
  left: 7px;
  font-size: 40px;
  overflow: hidden;
  width: 44px;
  height: 47px;
  font-weight: bold;
  font-style: normal;
  font-stretch: condensed;
  line-height: normal;
  letter-spacing: normal;
}

@keyframes move {
 0% {
    transform-origin: 100% 0;
    transform: perspective(150px) rotateX(0deg);
}

 100% {
    background: black;
    transform-origin: 0 0;
    transform: perspective(150px) rotateX(280deg);
  }
}

@keyframes static {
 100% {
    transform-origin: 100% 0;
    transform: perspective(150px) rotateX(280deg);
}

 0% {
    background: black;
    transform-origin: 0 0;
    transform: perspective(150px) rotateX(560deg);
  }
}

.horizontalLine {
  position: absolute;
  top: 75px;
  width: 56px;
  border-top: 1px solid black;
  z-index: 1000;
  left: 1px;
}

.pieces {
  width: 1px;
  height: 7px;
  position:...

JavaScript

document.getElementById("score").innerHTML = '00';

const minScoreValue = 0;
const maxScoreValue = 99;
let score = parseInt(document.getElementById("score").innerHTML);
let scoreCounter = 0;

const setDisableClassOnIncDecBtns = () => {
	const increaseBtnColor = score == minScoreValue ? 'gray' : '#2b2b2b';
	const decreaseBtnColor = score == maxScoreValue ? 'gray' : '#2b2b2b';
  
	$('#triggerDown').css('border-top-color', increaseBtnColor);
  $('#triggerUp').css('border-bottom-color', decreaseBtnColor);
}

setDisableClassOnIncDecBtns();

const onIncDecBtnsClick = (e, currentDirection) => {
	const isCurrentDirectionUp = currentDirection === 'increaseBtn';
  const animationClass = isCurrentDirectionUp ? 'action' : 'actionDown';
  
	setDisableClassOnIncDecBtns();
  
  e.preventDefault();
  var el = $('.move').clone();
  $('.move').addClass(animationClass);
  el.appendTo($('.wrapper'));
  setTimeout(() => $('.'+ animationClass).remove(), 500);
}

const setScore = (scoreCounter) => {
	score = scoreCounter < 10 ? '0' + scoreCounter : scoreCounter;
  setTimeout(() => document.getElementById("score").innerHTML = score, 300);
}

const onIncreaseBtnClick = (e) => {
	 scoreCounter += 1;
   setScore(scoreCounter);
   onIncDecBtnsClick(e, 'increaseBtn');
};

const onDecreaseBtnClick = (e) => {
   scoreCounter -= 1;
   setScore(scoreCounter);
   onIncDecBtnsClick(e, 'decreaseBtn');
};

$('#triggerUp').on('click', (e) => {
	if (score >= minScoreValue && score < maxScoreValue) {
   onIncreaseBtnClick(e);
	}
});

$('#triggerDown').on('click', (e) => {
	if (score > minScoreValue && score <= maxScoreValue) {
  	onDecreaseBtnClick(e);
	}
});

const getCurrentScore = () => score;