【cocos creator】js实现CocosCreator ScrollView无限滑动

参考https://blog.csdn.net/juedno/article/details/81775599

// Learn cc.Class:
//  - https://docs.cocos.com/creator/manual/en/scripting/class.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

cc.Class({
    extends: cc.Component,

    properties: {
        // foo: {
        //     // ATTRIBUTES:
        //     default: null,        // The default value will be used only when the component attaching
        //                           // to a node for the first time
        //     type: cc.SpriteFrame, // optional, default is typeof default
        //     serializable: true,   // optional, default is true
        // },
        // bar: {
        //     get () {
        //         return this._bar;
        //     },
        //     set (value) {
        //         this._bar = value;
        //     }
        // },
        item: cc.Prefab,
        Scroll: cc.ScrollView,
        //显示用的content
        content: cc.Node,
        //附加mask组件的对象
        maskNode: cc.Node,
        //方向,0是垂直方向,1是水平方向
        dir: 0,
        isVertical: true,
    },

    // LIFE-CYCLE CALLBACKS:

    onLoad() {
        this.itemsList = new Array();

        this.num = 30;
        this.itemNum = 3;
        //滑动的方向

        this.distance = 300;//item之间的间距
        this.needSize = 0;//需求要求的高度/宽度
        this.visibleHeight = 0;//显示范围高度
        this.itemsHeight = 0;//物品高度
        this.OnScrollFun = null;//滑动回调
        //可见范围
        this.minY = 0;
        this.maxY = 0;
        //可以显示的范围,可见范围 超过 可以显示的范围,就刷新列表(把缓存的item放到下面或上面)
        this.minVisibleY = 0;
        this.maxVisibleY = 0;
        this.initX = this.distance / 2;
        this.initY = -this.distance / 2;
        this.miniIdx = 0;
        this.maxIdx = 0;
        this.curOffset = 0;
        this.startY = this.content.y;
    },

    start() {
        this.Init(this.itemNum);
    },

    Init(num) {
        /*
        var eventHandler = new cc.Component.EventHandler();
        eventHandler.target = this.node;
        eventHandler.component = "ScrollHelper";
        eventHandler.handler = "OnScroll";
        this.Scroll.scrollEvents.push(eventHandler);*/
        this.needSize = this.num * this.distance;
        if (!this.isVertical) {
            this.initX = this.distance / 2;
            this.initY = 0;
            this.content.setContentSize(new cc.Size(this.needSize, this.content.getContentSize().height));

        } else {
            this.initX = 0;
            this.initY = -this.distance / 2;
            this.content.setContentSize(new cc.Size(this.content.getContentSize().width, this.needSize));
        }
        this.visibleHeight = this.maskNode.getContentSize().height;
        this.InitObjs();
    },

    InitObjs() {
        let curX = 0;
        let curY = 0;
        for (let i = 0; i < this.itemNum; i++) {
            let obj = cc.instantiate(this.item);
            obj.parent = this.content;
            //this.node.getComponent("CollectPanel").setPic(i, obj);
            obj.active = true;
            if (!this.isVertical) {
                curX = this.initX + this.distance * i;
                // console.error("curX:" + curX);
            }
            else {
                curY = this.initY - this.distance * i;
                // console.error("curY:" + curY);
            }

            obj.setPosition(cc.v2(curX, curY));
            this.onRefresh(obj, i, i);
            this.itemsList.push(obj);
        }
    },

    //计算边界,超过边界则刷新列表
    //offest是左上角原点滑动的偏移量
    countBorder(offest) {
        let height = this.visibleHeight;//可见高度
        this.minY = offest;//获得相对于左上角原点的最小y值
        this.maxY = offest + height;//获得相对于左上角原点的最大y值
    },

    OnScroll() {
        //获取滚动视图相对于左上角原点的当前滚动偏移
        let scrollOffset = this.Scroll.getScrollOffset();
        let offest = 0;
        if (!this.isVertical)
            //水平的offset是负数,为什么会有这么sb的设计,将它取反和垂直方向的统一一下
            offest = -scrollOffset.x;
        else
            offest = this.content.y;
        this.curOffset = offest;
        this.refresh();
    },

    //强行刷新
    refresh() {
        let offest = this.curOffset;

        //最大高度,超过该高度,不刷新
        let maxY = this.needSize;
        if (offest < 0 || offest + this.visibleHeight >= maxY)
            return;
        let idx = 0;//从0开始

        this.countBorder(offest);
        // return;

        this.oldIndex = this.miniIdx;
        this.miniIdx = Math.floor(offest / this.distance);

        if (this.oldIndex === this.miniIdx) {
            return;
        }
        //cc.log(this.oldIndex, this.miniIdx);
        //cc.log(this.miniIdx)
        // console.error("this.miniIdx:" + this.miniIdx);

        this.minVisibleY = this.miniIdx * this.distance;
        this.maxVisibleY = this.maxIdx * this.distance;
        //miniIdx到maxIdx都会刷新
        for (let i = 0; i < this.itemNum; i++) {
            let obj = this.itemsList[i];
            idx = this.miniIdx + i;
            this.refreshItem(idx, i, obj);
        }
        this.maxIdx = this.miniIdx + this.itemNum;
    },

    //idx是UI该刷新的第几个元素
    refreshItem(idx, objIdx, obj) {
        if (idx < 0 || idx >= this.num)
            return;

        if (obj == null) {
            console.error("obj为空!");
            return;
        }
        let curX = 0;
        let curY = 0;
        if (!this.isVertical)
            curX = this.initX + this.distance * idx;
        else
            curY = this.initY - this.distance * idx;
        // console.error("idx:" + idx + ",curX:" + curX + ",curY:" + curY);
        obj.setPosition(cc.v2(curX, curY));
        //obj.setPositionX(curX);
        //obj.setPositionY(curY);
        this.onRefresh(obj, idx, objIdx);
    },

    /**
     * 刷新回调
     * @param obj 
     * @param idx 需求显示的索引
     * @param objIdx 实际的item索引
     */
    onRefresh(obj, idx, objIdx) {
        //测试用
        //let label = cc.find("text", obj).getComponent(cc.Label);
        //label.string = idx;
        //if (this.OnScrollFun)
        //    this.OnScrollFun(obj, idx, objIdx);
        //cc.log(idx, objIdx)
        idx = parseInt(idx);
        this.node.getComponent("CollectPanel").setPic(idx, objIdx);
    },
});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烧仙草奶茶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值