看到一个很棒的菜单效果,分享一下
原文 3D滚动下拉菜单-简直不要太任性javascript
http://runjs.cn/detail/re75abbwcss
最初看到这个是在14年5月,猛戳这里:妙味官网
,以为很是炫。想要作出来,因此就开始学习web。html
那时候是作c/s的,也由于这个走上了b/s之路, 如今先后台都要写了。java
前几天又来试试,发现本身能大概实现了,好屌。jquery
由于平时主要是实现功能,因此可能一些代码习惯,实现方式不太好,但愿指出来。css3
我也是一个菜鸟,会的很少( ̄∇ ̄),就不在这里show无知了,主要涉及到:transform
,transform-style(IE不支持?)
web
能够参见:Transform-style和Perspective属性算法
你们玩一玩这个菜单,会看到它不是匀速展开的,而是在展开动做的末尾“抖”一下学习
这个涉及到算法...我我的仅做了解(就是只知道这个东西,怎么实现不知道)动画
各类缓动效果和更详细的说明:JavaScript Tween算法及缓动效果
jquery有animate方法,能够很是方便的实现动画,原理是实时改变节点的样式
。
附:使用jquery的animate实现的动画,节点最好不要设置css3的transition,有冲突
我看到jquery的动画也不是匀速改变,因而查了一下资料,确实也有这个缓动算法,默认只有两种:linear匀速
,swing慢-快-慢
,添加扩展方法来实现(如2中连接缓动实例的 easeOutBack):慢-中-快-太快致使超过了-返回到正确的位置
,专业术语为:超过范围的三次方缓动
:
jQuery.extend(jQuery.easing, { easeOutBack: function (x, t, b, c, d, s) { if (s == undefined) s = 1.70158; return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; } })
jQuery的animate动画,我之前不知道在哪里看到的:只能实现能够用数字表示的动画。也就是说css3的transform是不行的。可是animate有一种重载!
经常使用的方式:
$("html,body").animate({ scrollTop: "0px" }, 1000);
另外一种重载:
$({ num: 32 }).animate({ num: 64 }, { duration:1000, step: function () { console.log("当前的num是:" + this.num); }, complete: function () { console.log("结束了,num是:" + this.num); } });
哈哈,看到这个你们就有思路了吧:
根据要改变的样式定义一个对象,利用animate改变这个对象,监听step和complete事件来拼接新的样式赋值给你要执行动画的元素!
在妙味官网上面看了好久都不知道从何看起,把这个作出来以后看到博友 吕大豹 将妙味的代码扒出来了,艹,仍是没看懂。
如下是3D下拉菜单的代码:
HTML :
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>RunJS</title> <script type="text/javascript" class="library" src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script> </head> <body> <div id="fold_box" class="P800"> <div id="fold" class="T3D fold_pager"> <h2>3D下拉菜单</h2> <div id="fold_list" class="T3D fold_pager" style="transform: rotateX(-180deg); -webkit-transform: rotateX(-180deg);"> <a href="#">基于 - jquery+缓动</a> <div class="T3D fold_pager" style="transform: rotateX(-180deg); -webkit-transform: rotateX(-180deg);"> <a href="#">基于 - jquery+缓动</a> <div class="T3D fold_pager" style="transform: rotateX(-180deg); -webkit-transform: rotateX(-180deg);"> <a href="#">基于 - jquery+缓动</a> <div class="T3D fold_pager" style="transform: rotateX(-180deg); -webkit-transform: rotateX(-180deg);"> <a href="#">基于 - jquery+缓动</a> <div class="T3D fold_pager" style="transform: rotateX(-180deg); -webkit-transform: rotateX(-180deg);"> <a href="#">基于 - jquery+缓动</a> <div class="T3D fold_pager" style="transform: rotateX(-180deg); -webkit-transform: rotateX(-180deg);"> <a href="#">基于 - jquery+缓动</a> <div class="T3D fold_pager" style="transform: rotateX(-180deg); -webkit-transform: rotateX(-180deg);"> <a href="#">基于 - jquery+缓动</a> <div class="T3D fold_pager" style="transform: rotateX(-180deg); -webkit-transform: rotateX(-180deg);"> <a href="#">基于 - jquery+缓动</a> <div class="T3D fold_pager" style="transform: rotateX(-180deg); -webkit-transform: rotateX(-180deg);"> <a href="#">基于 - jquery+缓动</a> <div class="T3D fold_pager" style="transform: rotateX(-180deg); -webkit-transform: rotateX(-180deg);"> <a href="#">基于 - jquery+缓动</a> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </div> </body> </html>
JavaScript :
//添加缓动扩展 jQuery.extend(jQuery.easing,{ easeOutBack: function (x, t, b, c, d, s) { if (s == undefined) s = 1.70158; return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; } }) var pageArr; function rotateDown(index) { if (index < 0 || index >= pageArr.length) { return; } var ele = pageArr.eq(index); ele.children("a").css("background-color", "#fff"); var obj = ele.data("obj"); if (!obj) { ele.data("obj", { r: getNumByEle(ele) }); obj = ele.data("obj"); } else obj.r = getNumByEle(ele); $(obj).animate({ r: 0 }, { duration: 1000, easing: "easeOutBack", step: function () { ele.css({ "-moz-transform": "rotateX(" + this.r + "deg)", "-webkit-transform": "rotateX(" + this.r + "deg)", "-0-transform": "rotateX(" + this.r + "deg)", "-ms-transform": "rotateX(" + this.r + "deg)", "transform": "rotateX(" + this.r + "deg)" }); //根据偏移量判断是否展开下一个 if (ele.data("opening")) return; //已经开始折叠下一个了 var rotateOff = getNumByEle(ele); if (rotateOff > -120) { ele.data("opening", true); rotateDown(index + 1); } }, complete: function () { ele.css({ transform: "rotateX(0deg)" }); } }); } function rotateUp(index) { if (index < 0 || index >= pageArr.length) { return; } var ele = pageArr.eq(index); ele.children("a").css("background-color", "rgb(223,223,223)"); var obj = ele.data("obj"); if (!obj) { ele.data("obj", { r: getNumByEle(ele) }); obj = ele.data("obj"); } else obj.r = getNumByEle(ele); $(obj).animate({ r: -180 }, { duration: 600, easing: "linear", step: function () { ele.css({ "-moz-transform": "rotateX(" + this.r + "deg)", "-webkit-transform": "rotateX(" + this.r + "deg)", "-0-transform": "rotateX(" + this.r + "deg)", "-ms-transform": "rotateX(" + this.r + "deg)", "transform": "rotateX(" + this.r + "deg)" }); //根据偏移量判断是否折叠上一个 if (ele.data("closing")) return; //已经开始折叠上一个了 var rotateOff = getNumByEle(ele); if (rotateOff < -60) { ele.data("closing", true); rotateUp(index - 1); } }, complete: function () { ele.css({ transform: "rotateX(-180deg)" }); } }); } function getNumByEle(ele) { var rotateStyle = ele.attr("style"); return rotateStyle.match(/rotateX\(([-]?\d+)/)[1]; } function stopAll() { for (var i = 0; i < pageArr.length; i++) { var ele = pageArr.eq(i); ele.data("opening", false); ele.data("closing", false); var obj = ele.data("obj"); if (obj && $(obj).stop) { $(obj).stop(true, false); } } } $(function(){ pageArr = $("#fold .fold_pager"); $("#fold").mousemove(function (e) { //Y轴旋转 var el = e.clientX - $(this).offset().left; var off = 60 * el / $(this).width() - 30; //this.style.transform = "rotateY(" + off + "deg)"; $(this).css({ "-webkit-transform":"rotateY(" + off + "deg)", "-moz-transform":"rotateY(" + off + "deg)", "-ms-transform":"rotateY(" + off + "deg)", "-o-transform":"rotateY(" + off + "deg)", "transform":"rotateY(" + off + "deg)" }); }).mouseenter(function () { //展开 stopAll(); rotateDown(0); }).mouseleave(function () { //折叠 stopAll(); rotateUp(pageArr.length - 1); }); });
CSS :
*{ box-sizing: border-box; } .P800 { -webkit-perspective: 800px; -moz-perspective: 800px; -ms-perspective: 800px; perspective: 800px; } .T3D { -webkit-transform-style: preserve-3d; -moz-transform-style: preserve-3d; -ms-transform-style: preserve-3d; transform-style: preserve-3d; } body{ background: #fff url(http://www.miaov.com/2013/css/bg/bg1.jpg) no-repeat top right; } #fold_box { position: absolute; right: 100px; top: 0; width: 146px; height: 54px; } #fold h2 { margin: 0; width: 146px; height: 54px; padding-top: 18px; line-height: 36px; text-indent: 50px; font-size: 16px; color: #fff; background: url(http://www.miaov.com/2013/img/topMenu/topMenu.png) no-repeat; position: relative; z-index: 2; font-family: arial; -ms-transform: translateZ(1px); -moz-transform: translateZ(1px); -webkit-transform: translateZ(1px); -o-transform: translateZ(1px); transform: translateZ(1px); } #fold_list { list-style: none; margin: 0; padding: 0; } .fold_pager { width: 146px; height: 30px; transform-origin: center top; } #fold_list a { display: inline-block; background-color: rgb(223, 223, 223); width: 146px; height: 29px; margin-bottom: 1px; line-height: 29px; color: #d16c6c; text-indent: 16px; font-size: 13px; text-decoration: none; z-index: 3; font-family: arial; -ms-transition: 0.6s; -moz-transition: 0.6s; -webkit-transition: 0.6s; -o-transition: 0.6s; transition: 0.6s; } #fold_list a:hover { background-color: #f69 !important; color: #fff; text-indent: 20px; font-size: 14px; box-shadow: 1px 1px 3px 2px #dfdfdf; }