| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- import { _decorator, Component, Node, Prefab, EventTouch, SystemEventType, Vec3, CCBoolean, tween, EventHandler, Layout, UITransform, Label } from 'cc';
- import { DEV } from 'cc/env';
- import { GeometryUtils } from '../../core/utils/GeometryUtils';
- const { ccclass, property } = _decorator;
- @ccclass('ListPanel')
- export class ListPanel extends Component {
- @property({ type: Prefab, tooltip: "页面Item预制体" })
- itemPrefab: Prefab = null;
- @property({ type: Node, tooltip: "页面节点,触摸检测" })
- panelNode: Node = null;
- @property({ type: Node, tooltip: "页面Content节点" })
- panelContent: Node = null;
- @property({ type: Label, tooltip: "文本页签" })
- txtPage: Label = null;
- @property({ tooltip: "是否为虚拟列表" })
- isVirtualList: boolean = true;
- @property({ tooltip: "是否为循环列表" })
- isLoopPanel: boolean = false;
- // @property({
- // type: [Node],
- // tooltip: "页面子节点",
- // visible() { return this.isVirtualList; }
- // })
- // panelChildNodes: Node[] = [];
- //渲染事件(渲染器)
- @property({
- type: EventHandler,
- tooltip: DEV && '渲染事件(渲染器)',
- })
- public renderEvent: EventHandler = new EventHandler();
- private _numItems: number = 5;
- set numItems(val: number) {
- this._numItems = val;
- if (this.renderEvent) {
- for (let i = 0; i < this.panelContent.children.length; i++) {
- let item = this.panelContent.children[i];
- EventHandler.emitEvents([this.renderEvent], item, i % this._numItems);
- }
- }
- this.txtPage.string = `${this._index + 1}/${this._numItems}`;
- }
- get numItems() {
- return this._numItems;
- }
- private panelItemWidth: number = 540;
- private _index: number = 0;
- private _panelTotalIndex: number = 0;
- private _panelIndex: number = 0;
- private leftPadding = 20;
- private rightPadding = 20;
- private spacingX = 20;
- private get deltaMoveDis() {
- return this.panelItemWidth + this.spacingX;
- }
- private contentUt: UITransform;
- private initPoint: Vec3 = Vec3.ZERO;
- private startPoint: Vec3 = Vec3.ZERO;
- private curPoint: Vec3 = Vec3.ZERO;
- //private moveDis: number = 0;
- onLoad() {
- this.contentUt = this.panelContent.getComponent(UITransform);
- this.panelNode.on(SystemEventType.TOUCH_START, this.onTouchStart, this);
- }
- start() {
- this.curPoint = new Vec3(this.panelContent.position.x, this.panelContent.position.y, 0);
- this.panelContent.getComponent(Layout).enabled = false;
- this.txtPage.string = `${this._index + 1}/${this._numItems}`;
- }
- private onTouchStart(e: EventTouch) {
- this.initPoint = this.startPoint = GeometryUtils.V2ToV3(e.getUILocation());
- this.panelNode.on(SystemEventType.TOUCH_MOVE, this.onTouchMove, this);
- this.panelNode.on(SystemEventType.TOUCH_END, this.onTouchEnd, this);
- this.panelNode.on(SystemEventType.TOUCH_CANCEL, this.onTouchEnd, this);
- }
- private onTouchMove(e: EventTouch) {
- let touches = e.getAllTouches();
- if (touches.length == 1) {
- let point = GeometryUtils.V2ToV3(e.getUILocation());
- let offsetX = point.x - this.startPoint.x;
- this.moving(new Vec3(offsetX, 0, 0));
- this.startPoint = point;
- }
- }
- private onTouchEnd(e: EventTouch) {
- let point = GeometryUtils.V2ToV3(e.getUILocation());
- let disVec = point.subtract(this.initPoint);
- let dis = disVec.length();
- //console.log("Dis: " + disVec);
- if (dis > this.panelItemWidth * 0.55) {
- if (disVec.x <= 0) {
- if (this._index < this._numItems - 1 || this.isLoopPanel) {
- this._panelTotalIndex++;
- this.movePanel(true);
- } else {
- this.moveRevert();
- console.log("到了最右边");
- }
- } else {
- if (this._index > 0 || this.isLoopPanel) {
- this._panelTotalIndex--;
- this.movePanel(false);
- } else {
- this.moveRevert();
- console.log("到了最左边");
- }
- }
- } else {
- this.moveRevert();
- console.log("翻页失败");
- }
- //this.panelContent.setPosition(this.curPoint);
- this.startPoint = Vec3.ZERO;
- this.panelNode.off(SystemEventType.TOUCH_MOVE, this.onTouchMove, this);
- this.panelNode.off(SystemEventType.TOUCH_END, this.onTouchEnd, this);
- this.panelNode.off(SystemEventType.TOUCH_CANCEL, this.onTouchEnd, this);
- }
- private moveRevert() {
- console.log("panelPos: ", this.panelContent.position);
- console.log("panel init Pos: ", this.curPoint);
- tween(this.panelContent).to(0.15, { position: this.curPoint }).start();
- }
- private movePanel(isMoveRight: boolean) {
- isMoveRight ? this._index++ : this._index--;
- isMoveRight ? this._panelIndex++ : this._panelIndex--;
- if (this.isLoopPanel) {
- if (this._index < 0) this._index = this._numItems - 1;
- if (this._index > this._numItems - 1) this._index = 0;
- }
- let isRight = 0;
- console.log("PanelIndex: " + this._panelIndex + " Data Index: " + this._index);
- this._panelIndex == 2 && (isRight = 1);
- this._panelIndex == 0 && (isRight = -1);
- let targetPos = new Vec3(-this.deltaMoveDis * this._panelTotalIndex, 0, 0);
- //this.curPoint = targetPos;
- tween(this.panelContent).to(0.15, { position: targetPos }).call(() => {
- if (!this.isLoopPanel) { //非循环列表 会到达顶部
- if (isRight == 1) {
- if (this._index < this._numItems - 1) {
- let firstItem = this.panelContent.children[0];
- let lastPosX = this.panelContent.children[2].position.x;
- if (this.panelContent.children[2].position.x + this.panelItemWidth > this.contentUt.width)
- this.contentUt.width += this.panelItemWidth + this.spacingX;
- firstItem.setSiblingIndex(2);
- firstItem.setPosition(new Vec3(lastPosX + this.panelItemWidth + this.spacingX, 0, 0));
- this._panelIndex = 1;
- }
- } else if (isRight == -1) {
- if (this._index > 0) {
- let lastItem = this.panelContent.children[2];
- let firstPosX = this.panelContent.children[0].position.x;
- lastItem.setSiblingIndex(0);
- lastItem.setPosition(new Vec3(firstPosX - this.panelItemWidth - this.spacingX, 0, 0));
- this._panelIndex = 1;
- }
- }
- } else { //循环列表
- //TODO
- if (isRight == 1) {
- let firstItem = this.panelContent.children[0];
- let lastPosX = this.panelContent.children[2].position.x;
- if (this.panelContent.children[2].position.x + this.panelItemWidth > this.contentUt.width)
- this.contentUt.width += this.panelItemWidth + this.spacingX;
- firstItem.setSiblingIndex(2);
- firstItem.setPosition(new Vec3(lastPosX + this.panelItemWidth + this.spacingX, 0, 0));
- this._panelIndex = 1;
- } else if (isRight == -1) {
- let lastItem = this.panelContent.children[2];
- let firstPosX = this.panelContent.children[0].position.x;
- lastItem.setSiblingIndex(0);
- lastItem.setPosition(new Vec3(firstPosX - this.panelItemWidth - this.spacingX, 0, 0));
- this._panelIndex = 1;
- }
- }
- this.curPoint = targetPos;
- this.txtPage.string = `${this._index + 1}/${this._numItems}`;
- }).start();
- }
- private moving(offset: Vec3) {
- this.startPoint = Vec3.ZERO;
- offset.x *= 0.5;
- offset.y *= 0.5;
- this.panelContent.setPosition(new Vec3(this.panelContent.position.x + offset.x, this.panelContent.position.y + offset.y, 0));
- }
- private onClickLeft() {
- if (this._index > 0 || this.isLoopPanel) {
- this._panelTotalIndex--;
- this.movePanel(false);
- } else {
- this.moveRevert();
- console.log("到了最左边");
- }
- }
- private onClickRight() {
- if (this._index < this._numItems - 1 || this.isLoopPanel) {
- this._panelTotalIndex++;
- this.movePanel(true);
- } else {
- this.moveRevert();
- console.log("到了最右边");
- }
- }
- }
|