在github上看到有人用HTML5 + CSS3 + Javascript实现了jQuery Wheel Menu(旋转菜单),因为本人供职于移动网站的开发,又不是一个专业的前端开发,所以看到这么炫的东东肯定就垂涎三尺,想移植到移动平台,当然最好一句代码不修改直接移植过来是最省事的,但是最终发现此大牛给出的Demo在移动端上展现是有一定问题的,所以在边看中国好声音的过程中,修改了他的一部分代码,实现了在移动浏览器上可以自由使用的jQuery Wheel Menu(旋转菜单)。
既然实现了如此绚丽的菜单,那么在移动网站上究竟在怎么样的场景下可以使用呢?其实,淘宝移动主站(m.taobao.com)左下角的“淘”就是这样一个类似的效果,但是淘宝主站实现的一些绚丽效果有一个让人头疼的问题,就是在移动端没问题,但是在PC端上就是没有任何效果。也许专业的前端能够接受这件事情,毕竟人家做的移动网站和PC无关的。不过因为本人是一个半路出家的很不专业的假“前端”开发工程师,所以我希望在移动端上实现的一些绚丽效果当用PC浏览器访问的时候,用鼠标点击代替移动端手指Tap的时候,也同样看到类似的效果。所以,这次玩的jQuery Wheel Menu在移动端和PC端的浏览器上不管你是Click还是Tap都是可以玩的。
那这种旋转式的菜单到底什么场景下使用呢?还不知道吗?我都举例淘宝了,当然你去看一看嘛,哈哈~这种旋转式菜单适合fixed在页面的左下角或者右下角,将回首页、消息通知、登录、个人中心等此类公共功能放入其中,这样不管你在哪个网页上,想回到这些公共功能的时候,只要点一下左下角或者右下角的这么个小东西,就可以立刻过去。
在线演示地址:http://sandbox.runjs.cn/show/lmfucabu
你也可以拿出手机扫描下方二维码,直接在手机上进行效果演示:
先来几张页面截图吧。
这个控件的实现上主要使用了CSS3的动画实现方式,各位有兴趣的同学,可以借助这个例子来很好地了解一下CSS3的动画实现方式。好了,废话不多说了,直接上代码吧!
Javascript代码:jquery.wheelmenu.js
对Javascript代码没有进行改动,我之所以说自己是个“假”前端就是因为我很不“喜欢”去写Javascript,所以我使用了github上的源码。
!function($){ var defaults = { trigger: "click", animation: "fade", angle: [0,360], animationSpeed: "medium" }; $.fn.centerAround = function (button) { var offset = button.offset(), width = button.outerWidth(), height = button.outerHeight(), buttonX = (offset.left - $(document).scrollLeft() ) + width / 2, buttonY = (offset.top - $(document).scrollTop() ) + height / 2, objectOffset = this.offset(); // alert(width); // alert(height); // alert(buttonX); // alert(buttonY); this.css("position","fixed"); this.css("top", buttonY - (this.outerHeight() / 2) + "px"); this.css("left", buttonX - (this.outerWidth() / 2) + "px"); return this; } $.fn.flyIn = function (el, button, width, height, angle, step, radius, settings) { var d = 0; this.stop(true,true); this.each(function(index) { angle = (settings.angle[0] + (step * index)) * (Math.PI/180); var x = Math.round(width/2 + radius * Math.cos(angle) - $(this).find("a").outerWidth()/2), y = Math.round(height/2 + radius * Math.sin(angle) - $(this).find("a").outerHeight()/2); $(this).animateRotate(360).css({ position: 'absolute', opacity: 0, left: "50%", top: "50%", marginLeft: "-" + $(this).outerWidth() / 2, marginTop: "-" + $(this).outerHeight() / 2 }).delay(d).animate({ opacity:1, left: x + 'px', top: y + 'px' }, settings.animationSpeed[1]); d += settings.animationSpeed[0]; }); } $.fn.flyOut = function (el, button) { var d = 0; this.stop(true,true); $(this.get().reverse()).each(function() { $(this).animateRotate(-360).delay(d).animate({ opacity:0, left: el.outerWidth() / 2 + "px", top: el.outerHeight() / 2 + "px" }, 150); d += 15; }).promise().done( function() { el.removeClass("active").css("visibility", "hidden").hide(); button.removeClass("active") }); } $.fn.fadeInIcon = function (el, button, width, height, angle, step, radius, settings) { var d = 0; this.stop(true,true); this.each(function(index) { angle = (settings.angle[0] + (step * index)) * (Math.PI/180); var x = Math.round(width/2 + radius * Math.cos(angle) - $(this).find("a").outerWidth()/2), y = Math.round(height/2 + radius * Math.sin(angle) - $(this).find("a").outerHeight()/2); $(this).css({ position: 'absolute', left: x + 'px', top: y + 'px', opacity: 0 }).delay(d).animate({opacity:1}, settings.animationSpeed[1]); d += settings.animationSpeed[0]; }); } $.fn.fadeOutIcon = function (el, button) { var d = 0; this.stop(true,true); $(this.get().reverse()).each(function() { $(this).delay(d).animate({opacity:0}, 150); d += 15; }).promise().done( function() { el.removeClass("active").css("visibility", "hidden").hide(); button.removeClass("active") }); } $.fn.hideIcon = function (button, settings) { var fields = this.find(".item"), el = this; switch (settings.animation) { case 'fade': fields.fadeOutIcon(el, button) break; case 'fly': fields.flyOut(el, button) break; } } $.fn.showIcon = function (button, settings) { var el = this, zindex = '6'; if (settings.trigger == "hover") { var zindex = '3'; } button.addClass("active").css({ 'z-index': zindex }); el.show().css({ position: 'absolute', 'z-index': '5', 'padding': '30px' // add safe zone for mouseover }).centerAround(button); el.addClass("wheel active").css("visibility", "visible").show(); if (el.attr('data-angle')) { settings.angle = el.attr('data-angle') } settings = predefineAngle(settings); var radius = el.width() / 2, fields = el.find(".item"), container = el, width = container.innerWidth(), height = container.innerHeight(), angle = 0, step = (settings.angle[1] - settings.angle[0]) / fields.length; switch (settings.animation) { case 'fade': fields.fadeInIcon(el, button, width, height, angle, step, radius, settings) break; case 'fly': fields.flyIn(el, button, width, height, angle, step, radius, settings) break; } } $.fn.animateRotate = function(angle, duration, easing, complete) { return this.each(function() { var $elem = $(this); $({deg: 0}).animate({deg: angle}, { duration: duration, easing: easing, step: function(now) { $elem.css({ transform: 'rotate(' + now + 'deg)' }); }, complete: complete || $.noop }); }); }; function predefineAngle (settings) { var convert = false if ($.type(settings.angle) == "string") { try { if (eval(settings.angle).length > 1) convert = true } catch(err) { convert = false } if (convert == true) { settings.angle = JSON.parse(settings.angle); } else { switch (settings.angle) { case 'N': settings.angle = [180,380] break; case 'NE': settings.angle = [270,380] break; case 'E': settings.angle = [270,470] break; case 'SE': settings.angle = [360,470] break; case 'S': settings.angle = [360,560] break; case 'SW': settings.angle = [90,200] break; case 'W': settings.angle = [90,290] break; case 'NW': settings.angle = [180,290] break; case 'all': settings.angle = [0,360] break; } } } return settings; } function predefineSpeed(settings) { if ($.type(settings.animationSpeed) == "string") { switch (settings.animationSpeed) { case 'slow': settings.animationSpeed = [75,700] break; case 'medium': settings.animationSpeed = [50,500] break; case 'fast': settings.animationSpeed = [25,250] break; case 'instant': settings.animationSpeed = [0,0] break; } } return settings; } $.fn.wheelmenu = function(options){ var settings = $.extend({}, defaults, options); settings = predefineSpeed(settings); return this.each(function(){ var button = $(this) var el = $($(this).attr("href")); el.addClass("wheel"); button.css("opacity", 0).animate({ opacity: 1 }) if (settings.trigger == "hover") { button.bind({ mouseenter: function() { el.showIcon(button, settings); } }); el.bind({ mouseleave: function() { el.hideIcon(button, settings); } }); } else { button.click( function() { if (el.css('visibility') == "visible") { el.hideIcon(button, settings); } else { el.showIcon(button, settings); } }); } }); } }(window.jQuery);
CSS代码:wheelmenu.css
我对CSS的代码是比较有兴趣玩的,所以并没有完全使用作者的CSS代码以及代码结构,因为我觉得作者的CSS代码在规范性上还是存在一定问题的(提供了CSS文件,但是在Demo的html中又写了很大一段代码,这种规范向来都是我鄙视的,鄙视一下大拿作者,来提升一下自己吧,哈哈~)
body { background: #C1FFC1; padding: 0; text-align: center; position: relative; margin: 0; } a { text-decoration: none; } .main { width: 100%; margin: 0 auto; } h1 { font-family: 'Pacifico', cursive; margin: 10px; width: 100%; color: #CD2626; } .wheel-button { position: relative; line-height: 35px; font-weight: bold; font-size: 35px; background: #FF7300; padding: 10px; text-align: center; border-radius: 50px; width: 35px; height: 35px; color: white; display: block; margin: 20px auto 20px; border: 1px solid #cccccc; box-shadow: 0 1px 2px rgba(0,0,0,0.25); -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.25); -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.25); } .wheel-button span, .wheel span{ position: relative; -moz-transition: all 1s ease; -webkit-transition: all 1s ease; -o-transition: all 1s ease; transition: all 1s ease; display: block; } .wheel-button.active span{ transform: rotate(135deg); -ms-transform: rotate(135deg); /* IE 9 */ -webkit-transform: rotate(135deg); /* Safari and Chrome */ } .pointer { color: #836FFF; font-family: 'Pacifico', cursive; font-size: 30px; height: 30px; line-height: 30px; margin: 10px 0 0px 0; } .wheel { margin: 0; padding: 0; list-style: none; width: 200px; /* this will determine the diameter of the circle */ height: 200px; /* this will determine the diameter of the circle */ visibility: hidden; position: relative; display: none; } .wheel li { overflow: hidden; float:left; } .wheel li a { display: block; background: rgba(0,0,0,0.5); border-radius: 50px; font-weight: bold; padding: 10px; text-align: center; width: 20px; height: 20px; border: 1px solid #ffffff; box-shadow: 0 1px 2px rgba(0,0,0,0.25); -moz-box-shadow: 0 1px 2px rgba(0,0,0,0.25); -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.25); color: white; -moz-transition: all 0.25s ease; -webkit-transition: all 0.25s ease; -o-transition: all 0.25s ease; transition: all 0.25s ease; } .wheel-button.ne { border-color: white; background: #1ABC9C; color: #34FFFF; position: fixed; bottom: 10px; left: 10px; } .wheel-button.nw { border-color: white; background-color: #E67E22; color: #FFFC44; position: fixed; bottom: 10px; right: 10px; }
Demo Html代码:wheelmenu.html
一个简单的移动页面的示例代码结构,我对视觉设计欠缺,所以Demo页面各位注重事先的效果就可以了。
<!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0"> <title>jQuery Wheel Menu On Mobile</title> <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script> <script type="text/javascript" src="jquery.wheelmenu.js"></script> <link rel="stylesheet" type="text/css" href="wheelmenu.css" /> <script> addEventListener("load", function() { setTimeout(scrollTo, 0, 0, 0); }, false); $(document).ready(function(){ $(".wheel-button").wheelmenu({ trigger: "click", animation: "fly", animationSpeed: "fast" }); }); </script> </head> <body> <div class="main"> <h1>jQuery Wheel Menu On Mobile</h1> <div class="pointer">Touch me, please!</div> <a href="#wheel" class="wheel-button"> <span>+</span> </a> <ul id="wheel" data-angle="all"> <li class="item"><a href="#home">A</a></li> <li class="item"><a href="#home">B</a></li> <li class="item"><a href="#home">C</a></li> <li class="item"><a href="#home">D</a></li> <li class="item"><a href="#home">E</a></li> <li class="item"><a href="#home">F</a></li> <li class="item"><a href="#home">G</a></li> <li class="item"><a href="#home">H</a></li> <li class="item"><a href="#home">I</a></li> <li class="item"><a href="#home">J</a></li> </ul> <a href="#wheel2" class="wheel-button ne"> <span>+</span> </a> <ul id="wheel2" data-angle="NE" class="wheel"> <li class="item"><a href="#home">A</a></li> <li class="item"><a href="#home">B</a></li> <li class="item"><a href="#home">C</a></li> <li class="item"><a href="#home">D</a></li> </ul> <a href="#wheel3" class="wheel-button nw"> <span>+</span> </a> <ul id="wheel3" data-angle="NW" class="wheel"> <li class="item"><a href="#home">A</a></li> <li class="item"><a href="#home">B</a></li> <li class="item"><a href="#home">C</a></li> <li class="item"><a href="#home">D</a></li> </ul> </div> </body> </html>