%input{:class => "menu-use-case", "type" => "checkbox", "id" => "menu-use-case"}
%label{:for => "menu-use-case"}
  Use case with a menu
.joystick
  -(1..28).each do |hover|
    %a{:class => "joystick__hover hover-#{hover}", "href" => "#"}
  -(1..28).each do |led|
    %div{:class => "joystick__led led-#{led}"}
  .joystick__zero
  .joystick__stick
  .joystick__ball
  %ul.menu
    -(1..28).each do |menu|
      %li{:class => "menu-item menu-item-#{menu}"}
        %span
          Menu item #{menu}

  
    
View Compiled
/*--------------- COLORS ---------------------*/

$primary : #fff;
$led-color: #fff;

/*---------------------------------------------*/

$pi: 3.14159265359;
$_precision: 10;
$angle: 12.8571429deg;

@function pow($base, $exp) {
  $value: $base;
  @if $exp > 1 {
    @for $i from 2 through $exp {
      $value: $value * $base;
    }
  }
  @if $exp < 1{
    @for $i from 0 through -$exp {
      $value: $value / $base;
    }
  }
  @return $value;
}

@function fact($num) {
  $fact: 1;
  @if $num > 0{
    @for $i from 1 through $num {
      $fact: $fact * $i;
    }
  }
  @return $fact;
}

@function _to_unitless_rad($angle) {
  @if unit($angle) == "deg" {
    $angle: $angle / 180deg * $pi;
  }
  @if unit($angle) == "rad" {
    $angle: $angle / 1rad;
  }
  @return $angle;
}

@function sin($angle){
  $a: _to_unitless_rad($angle);
  $sin: $a;
  @for $n from 1 through $_precision {
    $sin: $sin + (pow(-1, $n) / fact(2 * $n + 1) ) * pow($a, (2 * $n + 1));
  }
  @return $sin;
}

@function cos($angle){
  $a: _to_unitless_rad($angle);
  $cos: 1;
  @for $n from 1 through $_precision {
    $cos: $cos + ( pow(-1,$n) / fact(2*$n) ) * pow($a,2*$n);
  }
  @return $cos;
}

@function tan($angle){
  @return sin($angle) / cos($angle);
}

@mixin led {
  background: $led-color;
  box-shadow: 0 0 5px $led-color;
}
@mixin led-low-1 {
  background: rgba($led-color, 0.5);
  box-shadow: 0 0 5px rgba($led-color, 0.5);
}
@mixin led-low-2 {
  background: rgba($led-color,0.1);
  box-shadow: 0 0 5px rgba($led-color,0.1);
}

html{
  min-height: 100%;
}
body{
  background: radial-gradient(at 25% 25%, darken($primary,5) 0%, darken($primary,15) 100%);
  min-height: 100%;
  overflow:hidden;
}
.joystick{
  background: radial-gradient(at 75% 75%, darken($primary,5) 0%, darken($primary,15) 100%);
  box-shadow: 0 -5px 5px rgba(255, 255, 255, 0.1),
    0 5px 5px rgba(255, 255, 255, 0.05),
    inset 0 5px 5px rgba(0, 0, 0, 0.02),
    inset 0 -5px 5px rgba(255, 255, 255, 0.05);
  position:absolute;
  height: 200px;
  width: 200px;
  border-radius: 50%;
  top: 50%;
  left: 50%;
  transform:translate(-50%,-50%);
  &__ball{
  background: radial-gradient(at 25% 25%, darken($primary,5) 0%, darken($primary,15) 100%);
  position:absolute;
  height: 70%;
  width: 70%;
  border-radius: 50%;
  top: 50%;
  left: 50%;
  transform:translate(-50%,-50%);
  transform-style: preserve-3d;
  perspective: 1000px;
  box-shadow: inset -5px -10px 40px rgba(0, 0, 0, 0.05), inset 0px 0px 10px rgba(0, 0, 0, 0.3), inset 0px 0px 5px rgba(0, 0, 0, 0.5), inset 0px 0px 3px 1px rgba(0, 0, 0, 0.51), 0px 0px 10px rgba(0, 0, 0, 0.3);
  }
  &__zero{
  position:absolute;
  z-index:4;
  height: 30%;
  width: 30%;
  border-radius: 50%;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  }
  &__stick{
  background: radial-gradient(at 50% 75%, darken($primary,5) 0%, darken($primary,15) 100%);
  box-shadow: inset 5px 5px 10px rgba(255, 255, 255, 0.3),
    inset -5px -5px 10px rgba(0, 0, 0, 0.15),
    0 2px 10px -5px rgba(0, 0, 0, 0.7),
    0 4px 20px -10px rgba(0, 0, 0, 0.2),
    -50px 0 40px -20px rgba(0, 0, 0, 0.2),
    50px 50px 40px -20px rgba(0, 0, 0, 0.2);
  position:absolute;
  z-index:2;
  height: 50%;
  width: 50%;
  border-radius: 50%;
  top: 50%;
  left: 50%;
  margin: -25% -25%;
  transition: 200ms ease all;
    &:before{
      content: '';
      background: #fff;
      position: absolute;
      top : 10px;
      left : 49px;
      width: 3px;
      height: 3px;
      border-radius: 50%;
      box-shadow: 0 2px 3px #000,
        39px 40px #fff,
        39px 42px 3px #000,
        0px 80px #fff,
        0px 82px 3px #000,
        -39px 40px #fff,
        -39px 42px 3px #000;
      opacity: 0.15;
    }
    &:after{
      content: '';
      position: absolute;
      top : 50%;
      left : 50%;
      width: 50%;
      height: 50%;
      margin: -25% -25%;
      border-radius: 50%;
      box-shadow: -5px -5px 20px -10px;
      filter:blur(5px);
      opacity:0.4;
    }
  }
  &__hover{
    position:absolute;
    z-index: 3;
    width:12%;
    height:50%;
    left:50%;
    margin-left:-6%;
    transform-origin: 50% 100%;
    @for $hover from 1 to 29{ 
      $led : $hover;
      &.hover-#{$hover}{
        transform:rotate( ($angle*( $hover - 1)) );
        &:hover, &:focus{
          ~ .menu{
            transform: translateY( -100%/28*( $hover - 1) );
            .menu-item-#{$hover}{
              filter:blur(0px);
              opacity: 1;
            }
            .menu-item-#{$hover - 1}{
              filter:blur(2px);
              opacity: 0.9;
            }
            .menu-item-#{$hover + 1}{
              filter:blur(3px);
              opacity: 0.9;
            }
          }
          ~ .joystick__stick{
            $ty: -50 * cos($angle *( $hover - 1)) ;
            $tx: 50 * cos( (90deg - ($angle * ( $hover - 1)) ) ) ;
            transform: translate($tx*1%,$ty*1%) rotateX(1deg*$ty*0.5) rotateY(1deg*$tx*-0.5);
            box-shadow: inset (5px* $tx*0.05) (5px* $ty*0.05) 10px rgba(255, 255, 255, 0.3),
              inset (-5px* $tx*0.05) (-5px* $ty*0.05) 10px rgba(0, 0, 0, 0.15),
              0 2px 10px -5px rgba(0, 0, 0, 0.7),
              0 4px 20px -10px rgba(0, 0, 0, 0.2),
              (1px * $ty * 0.5) 0 40px -20px rgba(0, 0, 0, 0.2),
              (-1px * $ty * 0.5) 50px 40px -20px rgba(0, 0, 0, 0.2);
            
            &:after{
              box-shadow:  (-5px* $tx*0.05) (-5px* $ty*0.05) 20px -10px;
            }
          }
          @for $l from 0 to 6 {
            @if ($led + $l) > 28 {
              ~ .led-#{(0 - ( 28 - $led - $l))}{
                @include led;
              }
              @if ($l == 5 ) {
                ~ .led-#{(0 - ( 28 - $led - $l) + 1)}{
                @include led-low-1;
                }
                ~ .led-#{(0 - ( 28 - $led - $l) + 2)}{
                @include led-low-2;
                }
              }
            }@else{
              ~ .led-#{$led+$l}{
                @include led;
              }
            }
            @if ($led - $l) < 1 {
              ~ .led-#{(28 + ($led - $l))}{
                @include led;
              }
              @if ($l == 5 ) {
                ~ .led-#{(28 + ($led - $l)) - 1}{
                @include led-low-1;
                }
                ~ .led-#{(28 + ($led - $l)) - 2}{
                @include led-low-2;
                }
              }
            }@else{
              ~ .led-#{$led - $l}{
                @include led;
              }
            }
          }
          ~ .led-#{$led + 6},
          ~ .led-#{$led - 6}{
                @include led-low-1;
          }
          ~ .led-#{$led + 7},
          ~ .led-#{$led - 7}{
                @include led-low-2;
          }
        }
      }
    }
  }
  &__led{
    position: absolute;
    top: -40px;
    left: 50%;
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.7);
    transform-origin: 0 140px;
    transition: 200ms ease all;
    @for $c from 2 to 29 {
      &.led-#{$c}{
        transform:rotate(($c - 1)*$angle);
      }
    }
  }
}
.menu{
  position: absolute;
  display:none;
  top : 50%;
  left: 100%;
  margin-top: -30px;
  margin-left : 200px;
  list-style:none;
  padding : 0;
  width: 250px;
  transition: 200ms ease all;
  .menu-item{
    margin: 20px 0;
    filter:blur(10px);
    opacity: 0.5;
    transition: 200ms ease all;
    span{
      font-size: 2rem;
      font-family: sans-serif;
      color: darken($primary, 80);
    }
  }
}
.menu-use-case{ 
  opacity: 0;
  + label{
    position:absolute;
    background: darken($primary, 90);
    color: $primary;
    font-family: sans-serif;
    left: 20px;
    top: 0;
    padding: 15px 20px;
    font-size: 1.2rem;
    cursor: pointer;
    border-radius: 0 0 5px 5px;
    box-shadow: 0 10px 10px -10px #0000008f;
    &:before{
      content: '';
      width: 20px;
      height: 20px;
      margin-right: 10px;
      vertical-align: -3px;
      display: inline-block;
      background: $primary;
      transition: 200ms ease all;
    }
    &:after{
      content: '';
      position: absolute;
      height: 6px;
      width: 12px;
      border-left: 2px solid darken($primary, 90);
      border-bottom: 2px solid darken($primary, 90);
      transform: rotate(-45deg);
      top: 20px;
      left: 23px;
      opacity: 0;
    }
  }
}
.menu-use-case:checked{
  + label{
    &:after{
      opacity: 1;
    }
  }
  ~ .joystick .menu{
    display:block;
  }
} 
View Compiled
/* 
Full CSS Neumorphic Joystick
Inspired by @cerpow (https://twitter.com/cerpow)
https://dribbble.com/shots/13241875-Neumorphic-Joystick
BONUS : you can use the TAB key
*/

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.