Floating Draggable Popup Menu With jQuery And Animate.js

File Size: 2.49 KB
Views Total: 9038
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
   
Floating Draggable Popup Menu With jQuery And Animate.js

A Messenger like popup menu concept where you're able to click on the toggle icon to display a horizontal menu bar with a bounce effect based on anime.js. Also allows to drag the popup menu anywhere you want based on the jQuery UI's draggable functionality.

How to use it:

1. Load jQuery library and other required JS libraries (jQuery UI and Anime.js) in your html document.

<script src="//code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="//code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/animejs/1.1.3/anime.min.js"></script>

2. In this case, we're going to use Font Awesome for the menu icons.

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">

3. Create a container for the popup menu.

<div class="menu">
  <div id="myMenu"></div>
</div>

4. Style the menu items & icons in the CSS.

.menu {
  width: 40px;
  height: 40px;
}

.item {
  position: absolute;
  left: 0px;
  top: 0px;
  width: 40px;
  height: 40px;
  background-color: white;
  -moz-border-radius: 50%;
  -webkit-border-radius: 50%;
  border-radius: 50%;
  cursor: pointer;
  text-align: center;
  line-height: 40px;
}

i {
  font-size: 24px;
  color: #222222;
}

5. The core JavaScript for the popup menu.

var timeOut;

class Item {
  constructor(icon, backgroundColor) {
      this.$element = $(document.createElement("div"));
      this.icon = icon;
      this.$element.addClass("item");
      this.$element.css("background-color", backgroundColor);
      var i = document.createElement("i");
      $(i).addClass("fa " + icon);
      this.$element.append(i);
      this.prev = null;
      this.next = null;
      this.isMoving = false;
      var element = this;
      this.$element.on("mousemove", function() {
          clearTimeout(timeOut);
          timeOut = setTimeout(function() {
              if (element.next && element.isMoving) {
                  element.next.moveTo(element);
              } 
          }, 10);
      });
  }
  
  moveTo(item) {
      anime({
          targets: this.$element[0],
          left: item.$element.css("left"),
          top: item.$element.css("top"),
          duration: 700,
          elasticity: 500
      });
      if (this.next) {
          this.next.moveTo(item);
      }
  }

  updatePosition() {    
      anime({
          targets: this.$element[0],
          left: this.prev.$element.css("left"),
          top: this.prev.$element.css("top"),
          duration: 200
      });
      
      if (this.next) {
          this.next.updatePosition();
      }
  }
}

class Menu {
  constructor(menu) {
      this.$element = $(menu);
      this.size = 0;
      this.first = null;
      this.last = null;
      this.timeOut = null;
      this.hasMoved = false;
      this.status = "closed";
  }
  
  add(item) {
      var menu = this;
      if (this.first == null) {
          this.first = item;
          this.last = item;
          this.first.$element.on("mouseup", function() {
              if (menu.first.isMoving) {
                  menu.first.isMoving = false;        
              } else {
                  menu.click();
              }
          }); 
          item.$element.draggable(
              {
                  start: function() {
                      menu.close();
                      item.isMoving = true;
                  }  
              },
              {
                  drag: function() {
                      if (item.next) {
                          item.next.updatePosition();
                      }
                  }
              },
              {
                  stop: function() {
                      item.isMoving = false;
                      item.next.moveTo(item);
                  }
              }
          );
      } else {
          this.last.next = item;
          item.prev = this.last;
          this.last = item;
      }
      this.$element.after(item.$element);
      
      
  }
  
  open() {
      this.status = "open";
      var current = this.first.next;
      var iterator = 1;
      var head = this.first;
      var sens = head.$element.css("left") < head.$element.css("right") ? 1 : -1;
      while (current != null) {
          anime({
              targets: current.$element[0],
              left: parseInt(head.$element.css("left"), 10) + (sens * (iterator * 50)),
              top: head.$element.css("top"),
              duration: 500
          });
          iterator++;
          current = current.next;
      }    
  }
  
  close() {
      this.status = "closed";
      var current = this.first.next;
      var head = this.first;
      var iterator = 1;
      while (current != null) {
          anime({
              targets: current.$element[0],
              left: head.$element.css("left"),
              top: head.$element.css("top"),
              duration: 500
          });
          iterator++;
          current = current.next;
      }
  }
  
  click() {
      if (this.status == "closed") {
          this.open();
      } else {
          this.close();
      }
  }
  
}

$(document).delay(50).queue(function(next) {
    menu.open();
    next();
    $(document).delay(1000).queue(function(next) {
        menu.close();
        next();
    });
});

6. Add custom items to the popup menu.

var menu = new Menu("#myMenu");
var item1 = new Item("fa-bars");
var item2 = new Item("torso", "#FF5C5C");
var item3 = new Item("fa-facebook", "#5CD1FF");
var item4 = new Item("paypal", "#FFF15C");
var item5 = new Item("link", "#64F592");

menu.add(item1);
menu.add(item2);
menu.add(item3);
menu.add(item4);
menu.add(item5);

This awesome jQuery plugin is developed by andyNroses. For more Advanced Usages, please check the demo page or visit the official website.