cocos2d-js侧滑菜单SlidingMenu

效果:


代码:

可以自己添加标题与item

var SlidingMenu = cc.LayerColor.extend({
    MOVE_TIME: 0.5,                         //移动的事件
    TAG_PARENT: "SlidingMenu",
    SLIDINGMENU_WIDTH: 400,                 //slidingmenu的宽度
    ITEM_DISTANCE_OF_LABEL_LEFT: 80,       //label与左的间隔
    ITEM_DISTANCE_OF_ICON_LEFT: 20,       //icon与左边的间隔
    ITEM_DISTANCE_OF_TOP: 50,               //上边的间隔
    ITEM_DISTANCE_OF_BETWEEN: 20,           //item与item之间的间隔
    ITEM_DISTANCE: 60,                      //item的宽度
    ITEM_TITLE_DISTANCE: 50,                //itemTitle的宽度
    itemColor: cc.color(120, 120, 120),       //item的背景色
    itemTitleColor: cc.color(60, 60, 60),       //itemTitle的背景色
    layerColor: cc.color(50,50,50),             //layer的背景色
    lineColor: cc.color(100,100,100),           //分割线的颜色
    winSize: null,
    parentLayer: null,                      //slidingmenu的父节点
    dismissListener: null,                   //监听隐藏slidingmenu
    itemPosition: null,                     //item的位置
    menuList: [],                           //item的list
    menuFuncList: [],                       //itemTitle的list
    itemCount: 0,                           //item的数量
    itemTitleCount: 0,                      //itemTitle的数量
    clickItemListener: null,                //点击item的listener
    slidingHeight: 0,                       //slidngmenu的高度
    itemIndex:0,                            //条目的下标
    clickItem:null,                         //是否点击
    itemLine:null,                          //item的分割线
    posY:0,                                 //item的y轴的位置
    backgroundLayer:null,                                 //item的y轴的位置
    lastPosition:0,                        //上一次this.y的位置
    ctor: function (parentLayer) {
        this._super();
        var self = this;
        this.parentLayer = parentLayer;
        self.winSize = cc.winSize;
        self.initSlidingMenu();
        /**
         * 点击外面隐藏slidingmenu的监听事件
         * @type {cc.EventListener}
         */
        this.dismissListener = cc.EventListener.create({
            event: cc.EventListener.TOUCH_ONE_BY_ONE,  //单点触摸
            swallowTouches: false,    //拦截传递
            onTouchBegan: function (touches) {
                var point = touches.getLocation();
                var rect = self.parentLayer.getBoundingBox();
                if (cc.rectContainsPoint(rect, point)) {
                    self.dismiss();
                }
                return true;
            }
        });
        /**
         * 点击条目的监听事件
         * @type {cc.EventListener}
         */
        this.clickItemListener = cc.EventListener.create({
            event: cc.EventListener.TOUCH_ONE_BY_ONE,
            swallowTouches:false,
            onTouchBegan: function (touche) {
                var point = touche.getLocation();
                self.lastPosition = self.y;
                point.y -= self.y;
                for (var i = 0;i < self.itemCount; i++){
                    self.clickItem = self.menuList[i];
                    if (cc.rectContainsPoint(self.clickItem,point)){
                        self.itemIndex = i;
                        return true;
                    }
                }
                return false;
            },
            onTouchEnded: function (touche) {
                var point = touche.getLocation();
                point.y -= self.y;
                if (cc.rectContainsPoint(self.clickItem,point) && self.lastPosition === self.y ){
                    var callfunc = self.menuFuncList[self.itemIndex];
                    callfunc.apply();
                    self.dismiss();
                    return true;
                }
            }
        });
        //通过事件监听,获得鼠标(鼠标滚轮)或touch移动偏移量,来改变menu的坐标
        if ('touches' in cc.sys.capabilities)
            cc.eventManager.addListener({
                event: cc.EventListener.TOUCH_ALL_AT_ONCE,
                swallowTouches:false,
                onTouchesMoved: function (touches, event) {
                    var target = event.getCurrentTarget();
                    var delta = touches[0].getDelta();
                    target.moveMenu(delta);
                    return true;
                },
                onTouchesEnded: function (touche,event) {  //松开的时候判断是否弹回原处
                    var target = event.getCurrentTarget();
                    var duration = 0.2;
                    var moveto;
                    //判断slidingmenu的高度是否大于height的高度
                    //如果slidingmenu的高度大于height的高度则不会回到原处
                    //如果小于的话则会回到原处
                    if (self.slidingHeight < self.winSize.height){
                        moveto = new cc.moveTo(duration,0,0);
                        target.runAction(moveto);
                        return;
                    }
                    if (self.y > (self.slidingHeight - self.winSize.height)){
                        moveto = new cc.moveTo(duration,0,self.slidingHeight - self.winSize.height);
                        target.runAction(moveto);
                        return;
                    }
                    if (self.y < 0){
                        moveto = new cc.moveTo(duration,0,0);
                        target.runAction(moveto);
                    }
                }
            }, this);
        else if ('mouse' in cc.sys.capabilities) {
            cc.eventManager.addListener({
                event: cc.EventListener.MOUSE,
                onMouseMove: function (event) {
                    if (event.getButton() == cc.EventMouse.BUTTON_LEFT)
                        event.getCurrentTarget().moveMenu(event.getDelta());
                },
                onMouseUp: function (event) {
                    var target = event.getCurrentTarget();
                    var duration = 0.2;
                    var moveto;
                    //判断slidingmenu的高度是否大于height的高度
                    //如果slidingmenu的高度大于height的高度则不会回到原处
                    //如果小于的话则会回到原处
                    if (self.slidingHeight < self.winSize.height){
                        moveto = new cc.moveTo(duration,0,0);
                        target.runAction(moveto);
                        return;
                    }
                    if (self.y > (self.slidingHeight - self.winSize.height)){
                        moveto = new cc.moveTo(duration,0,self.slidingHeight - self.winSize.height);
                        target.runAction(moveto);
                        return;
                    }
                    if (self.y < 0){
                        moveto = new cc.moveTo(duration,0,0);
                        target.runAction(moveto);
                    }
                }
            }, this);
        }
        cc.eventManager.addListener(this.clickItemListener,this);
        cc.eventManager.addListener(this.dismissListener, this);
        cc.eventManager.pauseTarget(this,true);
    },
    //控制移动Menu坐标的方法
    moveMenu: function (delta) {
        var self = this;
        var newY = self.y + delta.y;
        if (newY < 100){   //上边没有了
            newY = self.y +delta.y/5;
        }
        var moreLength = this.itemCount * self.ITEM_DISTANCE + self.itemTitleCount * self.ITEM_TITLE_DISTANCE - self.winSize.height;
        if (newY > moreLength){   //下边也没有了
            newY = this.y + delta.y/5;
        }
        if (newY < 0) {
            this.y = newY;
            return;
        }
        if ( newY < moreLength) {
            newY = this.y + delta.y;
            this.y = newY;
            return;
        }
        if (newY > moreLength) {
            this.y = newY;
        }
    },
    /**
     * 初始化slidingmenu
     */
    initSlidingMenu: function () {
        var self = this;
        //设置背景  大小 位置
        self.setColor(self.layerColor);
        self.setContentSize(self.SLIDINGMENU_WIDTH, self.winSize.height);
        self.setPosition(0, 0);

        //设置阴影
        var shadow = new cc.LayerGradient();
        shadow.setPosition(-17, 0);
        shadow.setVector(cc.p(-1,0));
        shadow.setStartColor(cc.color(0,0,0));
        shadow.setEndColor(self.layerColor);
        shadow.setStartOpacity(255);
        shadow.setEndOpacity(0);
        shadow.setContentSize(20,self.winSize.height);
        self.parentLayer.addChild(shadow,3);

        //增加一块跟背景色一样的板
        self.backgroundLayer = new cc.LayerColor();
        self.backgroundLayer.setColor(self.layerColor);
        self.backgroundLayer.setContentSize(self.SLIDINGMENU_WIDTH, self.winSize.height);
        self.backgroundLayer.setPosition(0,0);

    },
    /**
     * 添加item
     */
    addMenuItem: function (icon,itemLabel, callback) {
        var self = this;
        self.menuFuncList[self.itemCount] = callback;  //把对应的callback存到menuFuncList中
        //对应每一个item的 Layer
        var itemLayer = self.menuList[self.itemCount] = new cc.LayerColor();
        itemLayer.setContentSize(self.SLIDINGMENU_WIDTH, self.ITEM_DISTANCE);
        itemLayer.setColor(this.itemColor);
        self.itemCount++;
        self.posY = self.winSize.height - (self.ITEM_DISTANCE ) * self.itemCount - (self.ITEM_TITLE_DISTANCE) * self.itemTitleCount;
        itemLayer.setPosition(0, self.posY);

        //Item对应的icon
        var itemIcon = new cc.Sprite(icon);
        itemIcon.setPosition(self.ITEM_DISTANCE_OF_ICON_LEFT,self.ITEM_DISTANCE / 2);
        itemIcon.setAnchorPoint(0,0.5);
        itemLayer.addChild(itemIcon);

        //item对应的文字
        var item = new cc.LabelTTF(itemLabel, "Arial", 30);
        item.setPosition(self.ITEM_DISTANCE_OF_LABEL_LEFT, self.ITEM_DISTANCE / 2);
        item.setAnchorPoint(0, 0.5);
        itemLayer.addChild(item);

        //需不需要画线 如果上一个是menu的话则需要 如果没有title则不需要
        var line = new cc.DrawNode();
        itemLayer.addChild(line);
        line.drawSegment(cc.p(0,0),cc.p(self.SLIDINGMENU_WIDTH,0),2,self.lineColor);
        self.addChild(itemLayer);
    },
    /**
     *添加标题
     */
    addMenuTitle: function (itemTitle) {
        var self = this;
        var itemTitleLayer = new cc.LayerColor();
        itemTitleLayer.setContentSize(self.SLIDINGMENU_WIDTH, self.ITEM_TITLE_DISTANCE);
        itemTitleLayer.setColor(this.itemTitleColor);
        self.itemTitleCount++;
        self.posY = self.winSize.height - (self.ITEM_DISTANCE ) * self.itemCount - (self.ITEM_TITLE_DISTANCE) * self.itemTitleCount;
        itemTitleLayer.setPosition(0, self.posY);
        var item = new cc.LabelTTF(itemTitle, "Arial", 30);
        item.setPosition(self.ITEM_DISTANCE_OF_LABEL_LEFT, self.ITEM_TITLE_DISTANCE / 2);
        item.setAnchorPoint(0, 0.5);
        itemTitleLayer.addChild(item);
        self.addChild(itemTitleLayer);
    },
    /**
     * 显示slidingmenu
     */
    showSliding: function () {
        var self = this;
        this.parentLayer.stopAllActions();
        var parentMove = new cc.moveTo(self.MOVE_TIME, self.SLIDINGMENU_WIDTH, 0);
        this.parentLayer.runAction(parentMove);
        cc.eventManager.pauseTarget(this.parentLayer,true);
        if ((this.parentLayer.getParent().getChildByName(self.TAG_PARENT)) == null) {
            self.parentLayer.getParent().addChild(self.backgroundLayer,1);
            this.parentLayer.getParent().addChild(this, 2, self.TAG_PARENT);
        }
        self.slidingHeight = self.ITEM_DISTANCE * self.itemCount + self.itemTitleCount * self.ITEM_TITLE_DISTANCE;
        cc.eventManager.resumeTarget(this,true);  //恢复监听事件
    },
    /**
     * 隐藏slidingmenu
     */
    dismiss: function () {
        var self = this;
        cc.eventManager.resumeTarget(self.parentLayer,true);
        self.parentLayer.stopAllActions();
        var hideSlidingMenu = new cc.moveTo(self.MOVE_TIME, 0, 0);
        self.parentLayer.runAction(hideSlidingMenu);
        cc.eventManager.pauseTarget(this,true);   //暂停所有监听事件
    },
    /**
     * 设置slidingmenu背景
     */
    setLayerColor: function (color) {
        this.layerColor = color;
        this.setColor(color);
    },
    /**
     * 设置条目的背景色
     */
    setItemColor: function () {
        this.itemColor = color;
    },
    /**
     * 设置分割线的颜色
     */
    setLineColor: function (color) {
        this.lineColor = color;
    }
});


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值