JSFiddle - React, Tailwind, and code Playground

by Michael Prosser

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

CSS

html,body{
  height:100%;
  margin:0px;
  background-color:#212529;
  color:#fff;
  font-family:helvetica;
}

nav.chainedlightening{
  perspective:200px;
  left:0px;
  right:0px;
  top:0px;
  bottom:0px;
  position:absolute;
  perspective-origin:50% 50%;
}
nav.chainedlightening ul{
  list-style:none;
  display:block;
  padding:0px;
  margin:0px;
  position:absolute;
  transition:all 1s;
  transform: translateZ(-50px);
  left:50%;
  top:50%;
}
nav.chainedlightening ul li{
  display:block;
  width:120px;
  height:120px;
  position:absolute;
  transition:all 0.7s;
  transform: translateX(0px);
  left:50%;
  top:50%;
  margin-left:-60px;
  margin-top:-60px;
}
nav.chainedlightening ul li>div{
  display:block;
  border:solid 1px #fff;
  border-radius:50%;
  text-align:center;
  width:120px;
  height:120px;
  position:relative;
  cursor:pointer;
  transition:all 0.7s;
  background-color:#212529;
}
nav.chainedlightening ul li>div:hover{
  background-color:#111;
}
nav.chainedlightening ul li>div span{
  display:block;
  vertical-align:middle;
  top:50%;
  position:absolute;
  left:0px;
  right:0px;
  transform:translateY(-50%);
}

JavaScript

function ChainedLightening(parentNode,data) {
  
	// create the dom element for menu
  
	var nav = $('<nav class="chainedlightening"></nav>');
  
  var nextPane = function(){
  
  	nav.find('>ul').each(function(){
    
    	var z = parseInt($(this).attr('data-z'))-500;
      
      var o = 1/Math.abs(z)*50;
      
      var pe = 'none'; 
      
      if(z == 0 ){
      
      	o = 1;
        
        pe = 'auto';
      
      }
      
      $(this).attr('data-z',z).css('transform','translateZ(' + z + 'px)').css('opacity',o).css('pointer-events',pe);
    
    });
  
  }
  
  var mapPosition = function(x,y,r,d){
  
  console.log("ROTATION",r);
  
  	x += d * Math.sin(r * Math.PI / 180);
  	y -= d * Math.cos(r * Math.PI / 180);
		
    return { x: x, y: y };

  }
	
	for(var i=0;i<data.length;i++){
  
  	var z = parseInt(i*500);
  	var menu = $('<ul data-z="' + z + '" style="transform:translateZ(' + z + 'px);"></ul>');
    
    var deg = 0;
    
    var degInt = 360 / data[i].length;
	
  	for(var ii=0;ii<data[i].length;ii++){
    
    	var position = mapPosition(0,0,deg,180);
    
    	if(data[i].length == 1){
      
      	position = { x: 0, y: 0 }
      
      }
      
      
      console.log(position);
    
      var item = $('<li style="transform:translateX(' + position.x + 'px) translateY(' + position.y + 'px);"><div><span>' + data[i][ii].label + '</span></div></li>');
      
      deg+=degInt;

		
    	if(i == 0){
      
        item.click(function(){
					
         nextPane();

        });
      
      } else {
      
      	item.click(function(){
					
         nextPane();

        });
      
      }
      
      
      menu.append(item);
      
    }
    
    nav.append(menu);
  
  }
  
  parentNode.append(nav);
	
}

// first 2 levels are loaded when instance is created

new ChainedLightening($('body'),Array(
	Array(
  	{
      label: "Brain",
      hyperlink: "lookup:Brain"
    }
  ),
  Array(
  	{
      label: "Reactive Brain",
      hyperlink:...