JSFiddle - React, Tailwind, and code Playground

by neonDog

HTML

<img class="wheel" src="https://neoncreativestudios.co.uk/explorer_wheel.png">
<img class="wheel rear" src="https://neoncreativestudios.co.uk/explorer_wheel.png">

<button class="setting" data-action="set" data-speed="600">600kmh</button>
<button class="setting" data-action="set" data-speed="20">20kmh</button>
<button class="setting" data-action="set" data-speed="10">10kmh</button>
<button class="setting" data-action="set" data-speed="1">1kmh</button>
<button class="setting" data-action="set" data-speed="0">0kmh</button>
<button class="setting" data-action="up">Speed up</button>
<button class="setting" data-action="down">Slow</button>

<div id="debug"></div>

SCSS

.wheel {
    width:7vw;
    position:absolute;
    z-index:20;
    top:15%;
    left:0%;
    //animation:spin 3s linear infinite;
    //animation-direction: reverse;
    
    &.rear {
      left:20%;
    }
    
    &.paused {
      animation-play-state: paused;
    }
    
  }


@keyframes spin { 100% { transform:rotate(360deg); } }

JavaScript

let currentAngle = 0;
let r = 0;
let velocity = 0;
let targetSpeed = 0;
let acceleration = 0.05; //How much to increase or decrease per frame

let hasPaused = false;
const wheels = document.body.getElementsByClassName('wheel');

document.addEventListener('click', function(e) {

	const el = e.target.closest('.setting');
  
  if (el) {
  	const data = el.dataset;
    
    if (data.action === 'toggle') {
    	hasPaused = !hasPaused;
    	for (const wheel of wheels) {
      	wheel.classList.toggle('paused',hasPaused);
      }
      return;
    } else if (data.action === 'up') {
    	targetSpeed++;
    } else if (data.action === 'down') {
    	targetSpeed--;
    } else if (data.action === 'set') {
    	targetSpeed = parseInt(data.speed);
    }
    
    console.log(r);
  }
  
  
});

function animate() {
	requestAnimationFrame(animate);
  
  currentAngle += Math.round(r / 2);
  if (currentAngle >= 360) {
  	currentAngle = 0;
  }
  
  wheels[0].style.transform = 'rotate(-'+ currentAngle +'deg)';
  wheels[1].style.transform = 'rotate(-'+ currentAngle +'deg)';
  debug.innerText = 'Target: '+targetSpeed + ', Speed: ' + r.toFixed() + ', Rotation: ' + currentAngle;
  
	if (Math.floor(r) === targetSpeed) {
  	return;
  } else if (r > targetSpeed) {
    r -= acceleration;
  } else if (r < targetSpeed) {
    r += acceleration;
  }
  
  //wheels[0].style.animationDuration = Math.floor((150 - r) * 8) +'ms';
  //wheels[1].style.animationDuration = Math.floor((150 - r) * 8) +'ms';
  
}

animate();