JSFiddle - React, Tailwind, and code Playground

by BurpmanJunior

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/stackblur-canvas/1.4.0/stackblur.min.js"></script>
<div id="stage"></div>

CSS

body{
  /* overflow: hidden; */
}

canvas{
  display: block;
  margin: 0 auto;
}

Babel + JSX

/**
 * Layer Walk
 */

console.clear();

/** Base canvas animation class */
class CanvasAnimation{

  /**
   * Animation core initialization
   */
  constructor(){
    /** Init variables */

    // Canvas & DOM
    this.DOM_ELEMENT = document.createElement('canvas');
    this.SCENE       = this.DOM_ELEMENT.getContext('2d');

    // Layout
    this.WIDTH = this.HEIGHT = 0;

    // Play
    this.PLAY_STATE = this.ELAPSED = this.ELAPSED_OFFSET = 0;
    
    /** Utilities */
    this.PI2 = Math.PI * 2;
  }


  /**
   * Append DOM element
   * @param {HTMLElement} elem Target DOM element
   */
  appendTo(elem){
    if(!elem instanceof HTMLElement){ return false; }
    elem.appendChild(this.DOM_ELEMENT);
    return true;
  }


  /**
   * Set internal size references and canvas size
   * @param {Number} x
   * @param {Number} y Null to sync with width
   */
  setSize(x, y = null){
    this.WIDTH    = this.DOM_ELEMENT.width = x;
    this.HEIGHT   = this.DOM_ELEMENT.height = y === null ? x : y;
    this.XY_RATIO = this.WIDTH / this.HEIGHT;
  }


  /**
   * Animation loop management
   */
  animate(){
    // Conditional animation loop
    if(this.PLAY_STATE){
      requestAnimationFrame(() => { this.animate(); });
    }

    // Time update
    this.ELAPSED = new Date().getTime() - this.ELAPSED_OFFSET;

    this.updateScene();
    this.renderScene();
  }


  /**
   * Single frame advancement
   * @param  {Mixed} delta  Forward animation delta in milliseconds. Set null to advance with stored elapsed offet
   */
  nextFrame(delta = null){
    // Time update
    if(delta !== null){
      this.ELAPSED        += delta * 1;
      this.ELAPSED_OFFSET += delta * 1;
    }else{
      this.ELAPSED = new Date().getTime() - this.ELAPSED_OFFSET;
    }

    this.updateScene();
    this.renderScene();
  }


  /**
   * Begin new animation loop
   */
  play(){
    this.PLAY_STATE     = true;
    this.ELAPSED        = this.ELAPSED || 0;
    this.ELAPSED_OFFSET = new Date().getTime();

   ...