JSFiddle - React, Tailwind, and code Playground

by necolas

HTML

<div id="menu">
    <button id="menu-control">+</button>
    <a class="a option" href="#n" data-pos="0">A</a>
    <a class="b option" href="#n" data-pos="1">B</a>
    <a class="c option" href="#n" data-pos="2">C</a>
    <a class="d option" href="#n" data-pos="3">D</a>
    <a class="e option" href="#n" data-pos="4">E</a>
    <a class="f option" href="#n" data-pos="5">F</a>
</div>

SCSS

$prefixes = -webkit, -moz, -ms, -o;

body {
    font-family: sans-serif;   
}

#menu {
    position: relative;
    background: #eee;
    width: 200px;
    height: 200px;
    color: white;
    margin: 50px auto;
    text-align: center;
    
    button {
        position: absolute;
        z-index: 2;
        box-sizing: border-box;
        bottom: 0;
        left: 0;
        width: 40px;
        height: 40px;
        padding: 0;
        border: 1px solid black;
        border-radius: 99px;
        box-shadow: inset 0 0 0 3px white;
        margin: 0 0 -20px -20px;
        font-size: 30px;
        line-height: 40px;
        font-weight: bold;
        text-shadow: 0 1px 1px rgba(0,0,0,0.2);
        cursor: pointer;
        color: white;
        background: red;
    }

    .option {
        position: absolute;
        z-index: 1;
        box-sizing: border-box;
        bottom: 0;
        left: 0;
        width: 30px;
        height: 30px;
        border: 1px solid black;
        border-radius: 99px;
        margin: 0 0 -15px -15px;
        box-shadow: inset 0 0 0 3px white;
        line-height: 30px;
        text-decoration: none;
        color: white;
        background: black;
        
        -webkit-transition-timing-function: cubic-bezier(0.500, 0.250, 0.575, 1.650);

        @each $prefix in $prefixes {
            #{$prefix}-transition-property: #{$prefix}-transform, bottom, left;
            #{$prefix}-transition-duration: 0.6s, 0.4s, 0.4s;
            #{$prefix}-transition-timing-function: linear, ease, ease;
        }

    }

    .spread {
        @each $prefix in $prefixes {
            #{$prefix}-transition-timing-function: linear, cubic-bezier(0.250, 0.250, 0.005, 1.650), cubic-bezier(0.250, 0.250, 0.005, 1.650);
            #{$prefix}-transform:rotate(720deg);

        }
    }

}

JavaScript

$(function(){
    
    var menu = $('#menu'),
        menucontrol = $('#menu-control'),
        width = menu.width(),
        height = menu.height(),
        radius,
        options = $('.option'),
        len = options.length;

    
    if (width > height) {
        radius = height;
    } else {
        radius = width;
    }

    $.each(options, function() {
        var pos = parseInt($(this).data('pos'));
        
        $(this).css({
            '-webkit-transition-delay' : (0.02 * pos) + 's'
        });
    });
        
    $(menu).on('click', menucontrol, function() {
        $.each(options, function() {
            var _this = $(this),
                pos = parseInt(_this.data('pos')),
                angle = (90/(len - 1)) * (len - pos -1) * Math.PI/180;
            
            if(_this.is('.spread')) {     
                _this.css({
                    'bottom' : 0,
                    'left' : 0,
                    '-webkit-transition-delay' : (0.02 * (len - pos -1)) + 's'
                }).removeClass('spread');
            }
            
            else {
                _this.css({
                    'bottom' : Math.sin(angle) * radius,
                    'left' : Math.cos(angle) * radius,
                    '-webkit-transition-delay' : (0.02 * pos) + 's'
                }).addClass('spread');
            }
        });
    });
    
});