资讯专栏INFORMATION COLUMN

3D滚动下拉菜单-简直不要太任性

ruicbAndroid / 1177人阅读

摘要:看到一个很棒的菜单效果,分享一下原文滚动下拉菜单简直不要太任性预览先看看最终效果简介由来最初看到这个是在年月,猛戳这里妙味官网,觉得非常炫。

看到一个很棒的菜单效果,分享一下
原文 3D滚动下拉菜单-简直不要太任性

预览(先看看最终效果)

http://runjs.cn/detail/re75abbw

简介(由来)

最初看到这个是在14年5月,猛戳这里:妙味官网,觉得非常炫。想要做出来,所以就开始学习web。

那时候是做c/s的,也因为这个走上了b/s之路, 现在前后台都要写了。

前几天又来试试,发现自己能大概实现了,好屌。

因为平时主要是实现功能,所以可能一些代码习惯,实现方式不太好,希望指出来。

前提(需要了解的东西) 1. css3基础

我也是一个菜鸟,会的不多( ̄∇ ̄),就不在这里show无知了,主要涉及到:transform,transform-style(IE不支持?)

可以参见:Transform-style和Perspective属性

2. 了解缓动

大家玩一玩这个菜单,会看到它不是匀速展开的,而是在展开动作的末尾“抖”一下

这个涉及到算法...我个人仅作了解(就是只知道这个东西,怎么实现不知道)

各种缓动效果和更详细的说明:JavaScript Tween算法及缓动效果

3. 利用jquery来实现缓动

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下拉菜单的代码:

3D下拉菜单 :在线演示查看源码

HTML :



    
        
        RunJS
    
    
    
        
    

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;
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85535.html

相关文章

  • CSS3热身实战--过渡与动画(实现炫酷下拉,手风琴,无缝滚动

    摘要:规定动画的时长。注意子菜单要用隐藏,在显示的时候再设置。如果不加,实际上子菜单,以及子菜单下面的一直在页面上,如果鼠标移上去子菜单,以及子菜单下面的。 1.前言 在自己的专栏上写了十几篇文章了,都是与js有关的。暂时还没有写过关于css3的文章。css3,给我的感觉就是,不难,但是很难玩转自如。今天,就用css3来实现三个特效,希望这三个特殊能让大家受到启发,利用css3做出更好,更炫...

    zqhxuyuan 评论0 收藏0
  • 支持大数据渲染下拉列表组件开发 SuperSelect(基于antd Select)

    摘要:功能简介的组件不支持大数据量的下拉列表渲染,下拉列表数量太多会出现性能问题,基于封装实现,替换原组件下拉列表,只渲染几十条列表数据,随下拉列表滚动动态刷新可视区列表状态,实现大数据量列表高性能渲染。功能简介 antd 的 Select 组件不支持大数据量的下拉列表渲染,下拉列表数量太多会出现性能问题, SuperSelect 基于 antd 封装实现,替换原组件下拉列表,只渲染几十条列表数据...

    phoenixsky 评论0 收藏0
  • FE.CSS-Sultana后记:纯css也能写col,select,datepicker,caro

    摘要:接着只要在中使用就能搞定自适应。代码如下标题标题标题标题标题在上述点功能中,可以用变量解决,比如实现了宽度,高度圆点大小直径的控件。 未完待续 背景 如今css3越来越发达,focus-within等属性也已经开始在Chrome得到支持。如果有出色的css功底,一点点ps技能,你也能用css3配合原生html标签写出优秀的框架。通过对css3的实践,我发现自定义原生控件并不是什么难事,...

    BigTomato 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<