Minimum animation time for operations

by Egor Mokeev

HTML

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<div class="p-3">
  <div class="mb-3">
    <div class="mb-2"><strong>Animation without minimum time</strong></div>
    <button class="btn btn-primary mb-2" id="withoutButton">Update</button>
    <div class="mb-2">Operation time: <span id="withoutTime">0</span>ms</div>
  </div>
  <div class="mb-3">
    <div class="mb-2"><strong>Animation with minimum time</strong></div>
    <button class="btn btn-primary mb-2" id="withButton">Update</button>
    <div class="mb-2">Operation time: <span id="withTime">0</span>ms</div>
  </div>
</div>

JavaScript

const minRequestTime = 30;
const maxRequestTime = 250;
const minAnimationTime = 250;

class AnimationWithoutMinimumTime {
	constructor(button) {
  	this._button = button;
    this._animationPromiseResolve = null;
  }
  
  startOperation() {
  	this._startAnimation();
    (new Promise((resolve) => { this._animationPromiseResolve = resolve; }))
    	.then(this._finishAnimation.bind(this));
  }
  
  finishOperation() {
  	this._animationPromiseResolve();
  }
  
  _startAnimation() {
  	this._button.setAttribute('disabled', '');
  }
  
  _finishAnimation() {
  	this._button.removeAttribute('disabled');
  }
}

class AnimationWithMinimumTime {
	constructor(button, minAnimationTime) {
  	this._button = button;
    this._minAnimationTime = minAnimationTime;
    this._animationPromiseResolve = null;
  }
  
  startOperation() {
  	this._startAnimation();
    Promise.all([
        new Promise((resolve) => { this._animationPromiseResolve = resolve; }),
        new Promise((resolve) => { setTimeout(resolve, this._minAnimationTime) })
    ]).then(this._finishAnimation.bind(this));
  }
  
  finishOperation() {
  	this._animationPromiseResolve();
  }
  
  _startAnimation() {
  	this._button.setAttribute('disabled', '');
  }
  
  _finishAnimation() {
  	this._button.removeAttribute('disabled');
  }
}

function timeoutPromise(time) {
	return new Promise((resolve) => { setTimeout(resolve, time) });
}

const withoutButton = document.getElementById('withoutButton');
const withoutAnimation = new AnimationWithoutMinimumTime(withoutButton);
initElements(withoutButton, withoutAnimation, document.getElementById('withoutTime'));

const withButton = document.getElementById('withButton');
const withAnimation = new AnimationWithMinimumTime(withButton, minAnimationTime);
initElements(withButton, withAnimation, document.getElementById('withTime'));

function initElements(button, animation, timeContainer) {
  button.addEventListener('click', () => {
    const requestTime =...