这是一款基于jquery ui的可自由拖拽的弹性圆形菜单效果。该圆形菜单可以通过点击一个圆形按钮来弹出4个子菜单按钮。弹性效果由anime.js来制作,效果非常炫酷。
在页面中引入jquery和jqueryui文件,以及anime.js和需要的样式文件style.css。
<link rel="stylesheet" href="css/style.css"> <script src="path/to/jquery.min.js"></script> <script src="path/to/jquery-ui.min.js"></script> <script src="path/to/anime.js"></script>
圆形菜单的HTML结构如下:
<div class="center menu"> <div id="myMenu"></div> </div>
在页面DOM元素加载完毕之后,通过下面的js代码来完成圆形菜单的拖拽功能,以及弹性效果。
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("fi-" + 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();="" }="" }="" }="" var="" menu="new" menu("#mymenu");="" var="" item1="new" item("list");="" var="" item2="new" item("torso",="" "#ff5c5c");="" var="" item3="new" item("social-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);="" $(document).delay(50).queue(function(next)="" {="" menu.open();="" next();="" $(document).delay(1000).queue(function(next)="" {="" menu.close();="" next();="" });="" });="">