JSFiddle - React, Tailwind, and code Playground

by Alexandru Gatea

HTML

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- Just a bunch of randomly placed elements -->
<button style="top: 100px; left: 100px;" class="float-trigger float-btn"><i class="fa fa-bars"></i></button>
<button style="top: 100px; left: 400px;"class="float-trigger float-btn"><i class="fa fa-bars"></i></button>
<button style="top: 300px; left: 200px;"class="float-trigger float-btn"><i class="fa fa-bars"></i></button>
<button style="top: 300px; left: 500px;"class="float-trigger float-btn"><i class="fa fa-bars"></i></button>




<!-- This is stand alone -->
  <ul class="share-items">
    <li class="floating-item item-heart">
      <a href="javascript:void(0)" class="float-btn">
        <i class="fa fa-heart"></i>
      </a>
    </li>
    <li class="floating-item item-star">
      <a href="javascript:void(0)" class="float-btn">
        <i class="fa fa-star"></i>
      </a>
    </li>
    <li class="floating-item item-wifi">
      <a href="javascript:void(0)" class="float-btn">
        <i class="fa fa-wifi"></i>
      </a>
    </li>
    <li class="floating-item item-bell">
      <a href="javascript:void(0)" class="float-btn">
        <i class="fa fa-bell"></i>
      </a>
    </li>
  </ul>

SCSS

// variables

$btnSize: 34px;
$btn-color: #607D8B;

  .float-btn {
      width: $btnSize;
      height: $btnSize;
      line-height: $btnSize;
      border-radius: 50%;
      text-align: center;
      outline: none;
      border: none;
      padding: 0;
      cursor: pointer;
      display: block;
      transition: all 0.15s ease-in-out;
      position:relative;
      i {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
      }
  }
	
	
  .float-trigger {
    position: absolute;
    z-index: 100;
    background: $btn-color;
    color: #fff;
    transition: all 0.3s ease;
  }
	
	
  .share-items {
    z-index: 0;
    position: fixed;
		top:17px;
		left:17px;
					width: $btnSize;
			height: $btnSize;
/*     top: 50%;
    left: 50%;
    transform: translate(-50%, -50%); */
    .floating-item {
      transform: translate(-50%, -50%);
      transition: all 0.3s ease;
      opacity: 0;
      position: absolute;
      color: #fff;
      transition: all 0.3s ease;
      border-radius: 50%;

			top:0;
			left: 0;
     
      .float-btn {
        text-decoration: none;
        color: inherit;
        &:hover {
          transform: scale(1.2);
          box-shadow: 0px 0px 0px 3px rgba(0,0,0,0.2);
        }
      }
    }
    .item-heart .float-btn {background: #f44336}
    .item-star .float-btn {background: #9C27B0}
    .item-wifi .float-btn {background: #3F51B5}
    .item-bell .float-btn {background: #03A9F4}
    .item-cloud .float-btn {background: #8BC34A}
    .item-cog .float-btn {background: #FF9800}
    .item-folder .float-btn {background: #FF5722}
    .item-paper-plane .float-btn {background: #795548}
  }

.floating-share {
  position: relative;
  width: 100%;
  height: 100vh;
  justify-content: center;
  align-items: center;
  display: flex;


}


.share-items.opened {
  .float-trigger {
    transform: scale(1.5);
    box-shadow: 0px 0px 0px 5px rgba($btn-color, 0.3);
  }
}

// animations

@for $i from 1...

JavaScript

// the math function that places the bubbles on a circle arch 
jQuery.fn.semiCircle = function(cx, cy, radius, radiusY, startDegrees, endDegrees) {
  if (radiusY === undefined) radiusY = radius;
  if (startDegrees === undefined) startDegrees = 0;
  if (endDegrees === undefined) endDegrees = 360;
  var startRadians = startDegrees * Math.PI / 180,
    endRadians = endDegrees * Math.PI / 180,
    stepRadians = (endRadians - startRadians) / (this.length - 1);
  return this.each(function(i) {
    var a = i * stepRadians + startRadians,
      x = Math.cos(a) * radius + cx,
      y = Math.sin(a) * radiusY + cy;
    $(this).css({
      left: x + 'px',
      top: y + 'px'
    });
  });
};


// store needed selectors
let floatTrigger = $('.float-trigger');
let floatingEl = $('.floating-item');
let floatParent = $('.share-items');



floatTrigger.on('click', function() {
	
	// get X and Y position of the clicked pin
	let trigPosX = $(this).position().left + $(this).width() / 2;
	let trigPosY = $(this).position().top + $(this).height() / 2;

	//set the position of the standalone floating buttons in the center of the clicked icon
	floatParent.css({
		top: trigPosY + "px",
		left: trigPosX + "px"
	});
	
	//change the icon inside the trigger
	$(this).find('.fa').toggleClass('fa-bars fa-times');



  if (floatParent.hasClass("opened")) {
    floatingEl.semiCircle(0, 0, 0, 0, 0, 0); //reset icons positions to 0
		floatParent.removeClass("opened").addClass("closing"); // close the floating items with an animation
    setTimeout(function() {
      floatParent.removeClass("closing");
    }, 200);
		
		//get pos of new clicked element
		
		


  } else {
    floatingEl.semiCircle(0, 0, 100, 100, 0, 90);
    floatParent.addClass("opened").removeClass("closing");
  }

});