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();