JSFiddle - React, Tailwind, and code Playground

by Michael Prosser

HTML

<div class="world">
  <div class="ground">
  </div>
  <div class="sign hasshadow">
  </div>
</div>

CSS

.sign{
  pointer-events:none;
  background-image:url('https://sleekinteractive.com/assets/clipart.sign.png');
  background-size:contain;
  height:100px;
  width:100px;
  position:absolute;
  left:50%;
  top:50%;
  margin-top:-50px;
  margin-left:-50px;
 transform:translateZ(-60px);
}
.hasshadow{
  transform-style:preserve-3d;
}
.hasshadow:after{
  content:"";
  position:absolute;
  width:100%;
  height:100%;
  background-image:inherit;
  display:block;
  background-size:inherit;
  transform: rotateX(90deg);
  filter: brightness(0.1);
  transform-origin:50% 100%;
  backface-visibility:hidden;
}
.ground{
  width:2000px;
  height:2000px;
  border-radius:50%;
  background-color:#061906;
  transform:rotateX(90deg);
  position:absolute;
  left:50%;
  top:50%;
  margin-top:-1000px;
  margin-left:-1000px;
  pointer-events:none;
}

html{
  height:100%;
}
body{
  background-color:#111;
  height:100%;
  margin:0px;
}
.world{
  background-color:#000;
  position:relative;
  perspective:100px;
  perspective-origin:30% 20%;
  height:400px;
  overflow:hidden;
}
.ground:after{
  content:"";
  display:block;
  height:100%;
  width:100%;
  background-size:100% 100%;
  background: radial-gradient(circle, rgba(239,246,14,0.2) 0%, rgba(0,0,0,1) 77%);
  border-radius:50%;
}

JavaScript

var world;

window.addEventListener('load', e => {

	world = document.querySelector('.world');
  
  world.addEventListener('mousemove', e => {
  
  	var xPercentage = (e.offsetX/window.innerWidth)*100;
    var yPercentage = (e.offsetY/window.innerHeight)*100;
   
    world.style.perspectiveOrigin = xPercentage + '% ' + Math.min(yPercentage,40) + '%';
    
	 
  });

});