JSFiddle - React, Tailwind, and code Playground

by stovberpv

HTML

<canvas></canvas>
<div class='logo-wrapper'>
  <svg class='logo' viewBox="0 0 200 50">
    <svg class='rabbit' x="0" y="0">
      <circle class='round' cx="50%" cy="50%" r="15"></circle>
    </svg>
    <svg class='part left' viewBox="0 0 100 50" x="0" y="0">
      <path class='rect' d="m0 0 h 50, v 50, h -50, z"/>
    </svg>
    <svg class='part right' viewBox="0 0 100 50" x="50" y="0">
      <path class='rect' d="m0 0 h 50, v 50, h -50, z"/>
    </svg>
  </svg>
</div>

CSS

/* #region core styles */
html, body {
  height: 100%;
}
body {
  top: 0;
  left: 0;
  background-color: #0f1223;
}
/* #endregion */

/* #region wrapper behavior */
.logo-wrapper {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 200px;
  height: 50px;
  margin: 0 auto;
  cursor: pointer;
  border-radius: 50%;
  overflow: hidden;
}
/* #endregion */

/* #region colors */
.logo-wrapper .logo .rabbit .round {
  fill: #ffcc00;
  transition: all .6s;
  opacity: 0;
  filter: drop-shadow( 9px 9px 9px rgba(255, 255, 255, 1));
}
.logo-wrapper .logo.fixed .rabbit .round {
  opacity: 1;
}
.logo-wrapper .logo .part {
  transition: all .3s;
  fill: #f5f5f5;
}
.logo-wrapper .logo .part:hover {
  /*opacity: .5;*/
}
.logo-wrapper .logo .part.left:hover {
   fill: tomato;
}
.logo-wrapper .logo .part.right:hover {
   fill: cornflowerblue;
}
/* #endregion */

/* #region slide animation */
.logo-wrapper .logo .part .rect {
  transition: all .3s;
}
.logo-wrapper .logo.fixed .part.left .rect {
  transform: translate(-50%, 0%);
}
.logo-wrapper .logo.fixed .part.right .rect {
  transform: translate(50%, 0%);
}
/* #endregion */

















body {
  width: 100%;
  height: 100vh;
  background-color: #000;
  background-image: radial-gradient(circle at top right, rgba(121, 68, 154, 0.13),       transparent),
    radial-gradient(circle at 20% 80%, rgba(41, 196, 255, 0.13), transparent)
}
canvas {
  position: fixed;
  width: 100%;
  height: 100%;
}

JavaScript

;(function() {
	let wrapper = document.querySelector('.logo-wrapper');
  let logo = wrapper.querySelector('.logo');
  
  wrapper.addEventListener('click', () => {
  	logo.classList.toggle('fixed');
  });
})();




const STAR_COUNT = ( window.innerWidth + window.innerHeight ) / 8,
      STAR_SIZE = 3,
      STAR_MIN_SCALE = 0.2,
      OVERFLOW_THRESHOLD = 50;

const canvas = document.querySelector( 'canvas' ),
      context = canvas.getContext( '2d' );

let scale = 1, // device pixel ratio
    width,
    height;

let stars = [];

let pointerX,
    pointerY;

let velocity = { x: 0, y: 0, tx: 0, ty: 0, z: 0.0005 };

let touchInput = false;

generate();
resize();
step();

window.onresize = resize;
canvas.onmousemove = onMouseMove;
canvas.ontouchmove = onTouchMove;
canvas.ontouchend = onMouseLeave;
document.onmouseleave = onMouseLeave;

function generate() {

   for( let i = 0; i < STAR_COUNT; i++ ) {
    stars.push({
      x: 0,
      y: 0,
      z: STAR_MIN_SCALE + Math.random() * ( 1 - STAR_MIN_SCALE )
    });
   }

}

function placeStar( star ) {

  star.x = Math.random() * width;
  star.y = Math.random() * height;

}

function recycleStar( star ) {

  let direction = 'z';

  let vx = Math.abs( velocity.tx ),
	    vy = Math.abs( velocity.ty );

  if( vx > 1 && vy > 1 ) {
    let axis;

    if( vx > vy ) {
      axis = Math.random() < Math.abs( velocity.x ) / ( vx + vy ) ? 'h' : 'v';
    }
    else {
      axis = Math.random() < Math.abs( velocity.y ) / ( vx + vy ) ? 'v' : 'h';
    }

    if( axis === 'h' ) {
      direction = velocity.x > 0 ? 'l' : 'r';
    }
    else {
      direction = velocity.y > 0 ? 't' : 'b';
    }
  }
  
  star.z = STAR_MIN_SCALE + Math.random() * ( 1 - STAR_MIN_SCALE );

  if( direction === 'z' ) {
    star.z = 0.1;
    star.x = Math.random() * width;
    star.y = Math.random() * height;
  }
  else if( direction === 'l' ) {
    star.x = -STAR_SIZE;
    star.y = height * Math.random();
  }
  else if( direction === 'r' ) {
    star.x = width...