├── .gitattributes ├── .gitignore ├── assets ├── scenes │ ├── main.scene.meta │ ├── vertical │ │ ├── vertical-loop.scene.meta │ │ ├── vertical-auto-center.scene.meta │ │ ├── vertical-loop-grid.scene.meta │ │ ├── vertical-auto-center-grid.scene.meta │ │ ├── vertical-refresh-load-grid.scene.meta │ │ └── vertical-refresh-load.scene.meta │ ├── horizontal │ │ ├── horizontal-loop.scene.meta │ │ ├── horizontal-page.scene.meta │ │ ├── horizontal-auto-center.scene.meta │ │ ├── horizontal-loop-grid.scene.meta │ │ ├── horizontal-auto-center-grid.scene.meta │ │ └── horizontal-page-scrollview.scene.meta │ ├── vertical.meta │ └── horizontal.meta ├── scripts │ ├── baseItem.ts.meta │ ├── baseMain.ts.meta │ ├── main.ts.meta │ ├── page.ts.meta │ ├── simple.ts.meta │ ├── vertical.ts.meta │ ├── auto-center.ts.meta │ ├── horizontal.ts.meta │ ├── refresh-load.ts.meta │ ├── simple.ts │ ├── vertical.ts │ ├── horizontal.ts │ ├── auto-center.ts │ ├── main.ts │ ├── page.ts │ ├── baseItem.ts │ ├── baseMain.ts │ └── refresh-load.ts ├── core │ ├── super-layout.ts.meta │ ├── super-scrollview.ts.meta │ ├── super-scrollview.ts │ └── super-layout.ts ├── core.meta ├── scenes.meta ├── prefabs.meta ├── scripts.meta └── prefabs │ ├── page.prefab.meta │ ├── vertical.prefab.meta │ ├── horizontal.prefab.meta │ ├── page-scrollview.prefab.meta │ ├── page.prefab │ ├── page-scrollview.prefab │ ├── horizontal.prefab │ └── vertical.prefab ├── package.json └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /library 2 | /local 3 | /profiles 4 | /settings 5 | /temp 6 | /tsconfig.json 7 | /build 8 | .DS_Store 9 | 10 | .DS_Store 11 | -------------------------------------------------------------------------------- /assets/scenes/main.scene.meta: -------------------------------------------------------------------------------- 1 | {"ver":"1.1.27","importer":"scene","imported":true,"uuid":"d632b43c-2698-49f7-aadd-4bb08f9f189a","files":[".json"],"subMetas":{},"userData":{}} 2 | -------------------------------------------------------------------------------- /assets/scenes/vertical/vertical-loop.scene.meta: -------------------------------------------------------------------------------- 1 | {"ver":"1.1.27","importer":"scene","imported":true,"uuid":"b752f9a8-c9cb-45de-b4dd-9a7c0b8906f7","files":[".json"],"subMetas":{},"userData":{}} 2 | -------------------------------------------------------------------------------- /assets/scenes/horizontal/horizontal-loop.scene.meta: -------------------------------------------------------------------------------- 1 | {"ver":"1.1.27","importer":"scene","imported":true,"uuid":"f92c1cb8-5ae7-4287-aea2-ee456f375152","files":[".json"],"subMetas":{},"userData":{}} 2 | -------------------------------------------------------------------------------- /assets/scenes/horizontal/horizontal-page.scene.meta: -------------------------------------------------------------------------------- 1 | {"ver":"1.1.27","importer":"scene","imported":true,"uuid":"66b03c1a-65a3-41ad-9901-db60208f9a2e","files":[".json"],"subMetas":{},"userData":{}} 2 | -------------------------------------------------------------------------------- /assets/scenes/vertical/vertical-auto-center.scene.meta: -------------------------------------------------------------------------------- 1 | {"ver":"1.1.27","importer":"scene","imported":true,"uuid":"fa64fa10-cf94-4140-b3b1-c5e52e34e88d","files":[".json"],"subMetas":{},"userData":{}} 2 | -------------------------------------------------------------------------------- /assets/scenes/vertical/vertical-loop-grid.scene.meta: -------------------------------------------------------------------------------- 1 | {"ver":"1.1.27","importer":"scene","imported":true,"uuid":"b567d910-611b-4b3c-9906-b676d2992233","files":[".json"],"subMetas":{},"userData":{}} 2 | -------------------------------------------------------------------------------- /assets/scenes/horizontal/horizontal-auto-center.scene.meta: -------------------------------------------------------------------------------- 1 | {"ver":"1.1.27","importer":"scene","imported":true,"uuid":"fc3d68bf-5526-44cc-adc0-82c9d4b41f26","files":[".json"],"subMetas":{},"userData":{}} 2 | -------------------------------------------------------------------------------- /assets/scenes/horizontal/horizontal-loop-grid.scene.meta: -------------------------------------------------------------------------------- 1 | {"ver":"1.1.27","importer":"scene","imported":true,"uuid":"9fc8fe25-7fd3-481c-a6f3-47ce8874142c","files":[".json"],"subMetas":{},"userData":{}} 2 | -------------------------------------------------------------------------------- /assets/scenes/vertical/vertical-auto-center-grid.scene.meta: -------------------------------------------------------------------------------- 1 | {"ver":"1.1.27","importer":"scene","imported":true,"uuid":"41b73afe-edc4-49c1-ab35-a0f626db4b75","files":[".json"],"subMetas":{},"userData":{}} 2 | -------------------------------------------------------------------------------- /assets/scenes/vertical/vertical-refresh-load-grid.scene.meta: -------------------------------------------------------------------------------- 1 | {"ver":"1.1.27","importer":"scene","imported":true,"uuid":"41250b95-8bc5-4b50-9298-d57736bc6f62","files":[".json"],"subMetas":{},"userData":{}} 2 | -------------------------------------------------------------------------------- /assets/scenes/horizontal/horizontal-auto-center-grid.scene.meta: -------------------------------------------------------------------------------- 1 | {"ver":"1.1.27","importer":"scene","imported":true,"uuid":"051c4e18-1275-42de-9e37-580638774d36","files":[".json"],"subMetas":{},"userData":{}} 2 | -------------------------------------------------------------------------------- /assets/scenes/horizontal/horizontal-page-scrollview.scene.meta: -------------------------------------------------------------------------------- 1 | {"ver":"1.1.27","importer":"scene","imported":true,"uuid":"c9590421-e9c2-47d5-8b22-2803c0a47115","files":[".json"],"subMetas":{},"userData":{}} 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "super-scrollview", 3 | "type": "3d", 4 | "uuid": "37ef4763-1b99-4f44-b147-9782d4a097c8", 5 | "version": "3.2.0", 6 | "creator": { 7 | "version": "3.2.0" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /assets/scripts/baseItem.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "4.0.22", 3 | "importer": "typescript", 4 | "imported": true, 5 | "uuid": "747fc08b-96a5-46b8-bc1f-095d428e6666", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": {} 9 | } 10 | -------------------------------------------------------------------------------- /assets/scripts/baseMain.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "4.0.22", 3 | "importer": "typescript", 4 | "imported": true, 5 | "uuid": "d886e837-709b-4aa0-93b3-3b8b04247059", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": {} 9 | } 10 | -------------------------------------------------------------------------------- /assets/scripts/main.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "4.0.22", 3 | "importer": "typescript", 4 | "imported": true, 5 | "uuid": "9ec2ba6a-c457-453a-a456-61e08dfc9e50", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": {} 9 | } 10 | -------------------------------------------------------------------------------- /assets/scripts/page.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "4.0.22", 3 | "importer": "typescript", 4 | "imported": true, 5 | "uuid": "b9acb047-de7c-4339-adee-64c0aa94a22a", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": {} 9 | } 10 | -------------------------------------------------------------------------------- /assets/scripts/simple.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "4.0.22", 3 | "importer": "typescript", 4 | "imported": true, 5 | "uuid": "5f170b85-b864-4225-90a2-1d331a3b186c", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": {} 9 | } 10 | -------------------------------------------------------------------------------- /assets/scripts/vertical.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "4.0.22", 3 | "importer": "typescript", 4 | "imported": true, 5 | "uuid": "ea9d1b02-3661-4863-bf24-d43b44bb4c4e", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": {} 9 | } 10 | -------------------------------------------------------------------------------- /assets/core/super-layout.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "4.0.22", 3 | "importer": "typescript", 4 | "imported": true, 5 | "uuid": "4430b74f-56cb-48ca-b333-ba2056fa19e2", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": {} 9 | } 10 | -------------------------------------------------------------------------------- /assets/core/super-scrollview.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "4.0.22", 3 | "importer": "typescript", 4 | "imported": true, 5 | "uuid": "72cf5dbc-6787-4afa-87cd-6263365dfdb6", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": {} 9 | } 10 | -------------------------------------------------------------------------------- /assets/scripts/auto-center.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "4.0.22", 3 | "importer": "typescript", 4 | "imported": true, 5 | "uuid": "4c92cb3b-cfaf-47d6-8875-9ea25f168a16", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": {} 9 | } 10 | -------------------------------------------------------------------------------- /assets/scripts/horizontal.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "4.0.22", 3 | "importer": "typescript", 4 | "imported": true, 5 | "uuid": "a3055143-44df-4d77-8843-e8fe7975540d", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": {} 9 | } 10 | -------------------------------------------------------------------------------- /assets/scripts/refresh-load.ts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "4.0.22", 3 | "importer": "typescript", 4 | "imported": true, 5 | "uuid": "89a5c43f-a817-4468-b172-8adfec9cca6f", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": {} 9 | } 10 | -------------------------------------------------------------------------------- /assets/scenes/vertical/vertical-refresh-load.scene.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.1.27", 3 | "importer": "scene", 4 | "imported": true, 5 | "uuid": "324a4fd5-1faa-452d-abf7-204c4866d1a3", 6 | "files": [ 7 | ".json" 8 | ], 9 | "subMetas": {}, 10 | "userData": {} 11 | } 12 | -------------------------------------------------------------------------------- /assets/core.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.1.0", 3 | "importer": "directory", 4 | "imported": true, 5 | "uuid": "7bcbe514-0408-49f4-9e02-4705066f7709", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": { 9 | "compressionType": {}, 10 | "isRemoteBundle": {} 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /assets/scenes.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.1.0", 3 | "importer": "directory", 4 | "imported": true, 5 | "uuid": "73ff6884-c3a2-4441-996c-7d485b0d2c0a", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": { 9 | "compressionType": {}, 10 | "isRemoteBundle": {} 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /assets/prefabs.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.1.0", 3 | "importer": "directory", 4 | "imported": true, 5 | "uuid": "aaa1a670-c77e-48d5-8e14-3738d5266460", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": { 9 | "compressionType": {}, 10 | "isRemoteBundle": {} 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /assets/scripts.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.1.0", 3 | "importer": "directory", 4 | "imported": true, 5 | "uuid": "cf65e955-f242-4294-8a14-f875e66e246c", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": { 9 | "compressionType": {}, 10 | "isRemoteBundle": {} 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /assets/prefabs/page.prefab.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.1.27", 3 | "importer": "prefab", 4 | "imported": true, 5 | "uuid": "5b7cc66e-729c-4d72-b5cb-3f2df7e2621c", 6 | "files": [ 7 | ".json" 8 | ], 9 | "subMetas": {}, 10 | "userData": { 11 | "syncNodeName": "page" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /assets/scenes/vertical.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.1.0", 3 | "importer": "directory", 4 | "imported": true, 5 | "uuid": "6d994c7e-a72a-4c04-8ff3-bd945a0eeb8c", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": { 9 | "compressionType": {}, 10 | "isRemoteBundle": {} 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /assets/prefabs/vertical.prefab.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.1.27", 3 | "importer": "prefab", 4 | "imported": true, 5 | "uuid": "5a756b1c-bdd5-478c-a49e-b0bf0ff12dcc", 6 | "files": [ 7 | ".json" 8 | ], 9 | "subMetas": {}, 10 | "userData": { 11 | "syncNodeName": "vertical" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /assets/scenes/horizontal.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.1.0", 3 | "importer": "directory", 4 | "imported": true, 5 | "uuid": "5eaffaa6-0ee8-450f-9527-946c4de6980b", 6 | "files": [], 7 | "subMetas": {}, 8 | "userData": { 9 | "compressionType": {}, 10 | "isRemoteBundle": {} 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /assets/prefabs/horizontal.prefab.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.1.27", 3 | "importer": "prefab", 4 | "imported": true, 5 | "uuid": "59452f19-6f49-40fb-965c-0c4cd0988409", 6 | "files": [ 7 | ".json" 8 | ], 9 | "subMetas": {}, 10 | "userData": { 11 | "syncNodeName": "horizontal" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /assets/prefabs/page-scrollview.prefab.meta: -------------------------------------------------------------------------------- 1 | { 2 | "ver": "1.1.27", 3 | "importer": "prefab", 4 | "imported": true, 5 | "uuid": "04f0cc66-4df6-4be8-ba1d-548f9ff7161a", 6 | "files": [ 7 | ".json" 8 | ], 9 | "subMetas": {}, 10 | "userData": { 11 | "syncNodeName": "page-scrollview" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /assets/scripts/simple.ts: -------------------------------------------------------------------------------- 1 | 2 | import { _decorator, Component, Node } from 'cc'; 3 | import { BaseMain } from './baseMain'; 4 | const { ccclass, property } = _decorator; 5 | 6 | @ccclass('Simple') 7 | export class Simple extends BaseMain { 8 | 9 | async onLoad() { 10 | for (let i = 0; i < 50; i++) { 11 | this.datas.push({ message: i }) 12 | } 13 | await this.layout.total(this.datas.length) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /assets/scripts/vertical.ts: -------------------------------------------------------------------------------- 1 | 2 | import { _decorator, Component, Node, Label, EditBox, Size } from 'cc'; 3 | import { BaseItem } from './baseItem'; 4 | const { ccclass, property } = _decorator; 5 | @ccclass('Vertical') 6 | export class Vertical extends BaseItem { 7 | onLoad() { 8 | this.input.placeholder = this.transform?.height.toString()! 9 | } 10 | onInput() { 11 | let height = Number(this.input.string) 12 | if (isNaN(height)) return 13 | if (height < 100) { 14 | return 15 | } 16 | 17 | this.transform?.setContentSize(new Size(this.transform.contentSize.width, height)) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /assets/scripts/horizontal.ts: -------------------------------------------------------------------------------- 1 | 2 | import { _decorator, Component, Node, Size } from 'cc'; 3 | import { BaseItem } from './baseItem'; 4 | const { ccclass, property } = _decorator; 5 | 6 | @ccclass('Horizontal') 7 | export class Horizontal extends BaseItem { 8 | onLoad() { 9 | this.input.placeholder = this.transform?.width.toString()! 10 | } 11 | onInput() { 12 | let width = Number(this.input.string) 13 | if (isNaN(width)) return 14 | if (width < 100) { 15 | return 16 | } 17 | this.transform?.setContentSize(new Size(Number(this.input.string), this.transform.contentSize.height)) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /assets/scripts/auto-center.ts: -------------------------------------------------------------------------------- 1 | 2 | import { _decorator, Component, Node, EditBox, Label } from 'cc'; 3 | import { Simple } from './simple'; 4 | const { ccclass, property } = _decorator; 5 | 6 | @ccclass('AutoCenter') 7 | export class AutoCenter extends Simple { 8 | @property(Label) label!: Label 9 | @property key: string = "" 10 | start() { 11 | this.label.string = `当前中心锚点:${(this.layout.centerAnchor as any)[this.key]}` 12 | this.layout.scrollToCenter() 13 | } 14 | onInputAnchor(event: EditBox) { 15 | let anchor = Number(event.string) 16 | if (isNaN(anchor)) return 17 | (this.layout.centerAnchor as any)[this.key] = anchor 18 | this.layout.scrollToCenter() 19 | this.label.string = `当前中心锚点:${(this.layout.centerAnchor as any)[this.key]}` 20 | } 21 | } -------------------------------------------------------------------------------- /assets/scripts/main.ts: -------------------------------------------------------------------------------- 1 | 2 | import { _decorator, Component, Node, director } from 'cc'; 3 | const { ccclass, property } = _decorator; 4 | 5 | @ccclass('Main') 6 | export class Main extends Component { 7 | 8 | toScene(event:any,args:string){ 9 | director.loadScene(args) 10 | } 11 | } 12 | 13 | /** 14 | * [1] Class member could be defined like this. 15 | * [2] Use `property` decorator if your want the member to be serializable. 16 | * [3] Your initialization goes here. 17 | * [4] Your update function goes here. 18 | * 19 | * Learn more about scripting: https://docs.cocos.com/creator/3.0/manual/en/scripting/ 20 | * Learn more about CCClass: https://docs.cocos.com/creator/3.0/manual/en/scripting/ccclass.html 21 | * Learn more about life-cycle callbacks: https://docs.cocos.com/creator/3.0/manual/en/scripting/life-cycle-callbacks.html 22 | */ 23 | -------------------------------------------------------------------------------- /assets/scripts/page.ts: -------------------------------------------------------------------------------- 1 | 2 | import { _decorator, Component, Node } from 'cc'; 3 | import { BaseItem } from './baseItem'; 4 | import { SuperLayout } from '../core/super-layout'; 5 | import { BaseMain } from './baseMain'; 6 | const { ccclass, property } = _decorator; 7 | 8 | @ccclass('Page') 9 | export class Page extends BaseMain { 10 | @property(SuperLayout) layout!: SuperLayout 11 | start() { 12 | for (let i = 0; i < 8; i++) { 13 | this.datas.push({ 14 | message: i 15 | }) 16 | } 17 | this.layout.total(this.datas.length) 18 | } 19 | onRefreshEvent(item: Node, index: number) { 20 | item.getComponent(BaseItem)?.show(this.datas[index], index, this.onClickItem.bind(this)) 21 | } 22 | onClickItem() { 23 | } 24 | 25 | onPageEvent(event: any) { 26 | console.error(this.layout.currPageIndex) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /assets/scripts/baseItem.ts: -------------------------------------------------------------------------------- 1 | 2 | import { _decorator, Component, Node, Label, EditBox } from 'cc'; 3 | const { ccclass, property } = _decorator; 4 | 5 | @ccclass('BaseItem') 6 | export class BaseItem extends Component { 7 | @property(Label) label!: Label 8 | @property(EditBox) input!: EditBox 9 | private index!: number 10 | private clickFunc!: Function 11 | get transform() { 12 | return this.node._uiProps.uiTransformComp 13 | } 14 | show(data: any, index: number, callback: Function) { 15 | this.index = index 16 | this.label.string = data.message 17 | this.clickFunc = callback 18 | } 19 | onClick() { 20 | this.clickFunc?.call(this, this.index) 21 | } 22 | 23 | onInput() { 24 | 25 | } 26 | } 27 | 28 | /** 29 | * [1] Class member could be defined like this. 30 | * [2] Use `property` decorator if your want the member to be serializable. 31 | * [3] Your initialization goes here. 32 | * [4] Your update function goes here. 33 | * 34 | * Learn more about scripting: https://docs.cocos.com/creator/3.0/manual/en/scripting/ 35 | * Learn more about CCClass: https://docs.cocos.com/creator/3.0/manual/en/scripting/ccclass.html 36 | * Learn more about life-cycle callbacks: https://docs.cocos.com/creator/3.0/manual/en/scripting/life-cycle-callbacks.html 37 | */ 38 | -------------------------------------------------------------------------------- /assets/scripts/baseMain.ts: -------------------------------------------------------------------------------- 1 | 2 | import { _decorator, Component, Node, EditBox, director } from 'cc'; 3 | import { SuperLayout } from '../core/super-layout'; 4 | import { BaseItem } from './baseItem'; 5 | const { ccclass, property } = _decorator; 6 | 7 | @ccclass('BaseMain') 8 | export class BaseMain extends Component { 9 | @property(SuperLayout) layout!: SuperLayout 10 | @property(EditBox) input!: EditBox 11 | protected datas: any[] = [] 12 | 13 | toHeader() { 14 | this.layout.scrollToHeader(1) 15 | } 16 | toFooter() { 17 | this.layout.scrollToFooter(1) 18 | } 19 | toIndex() { 20 | var index = Number(this.input.string) 21 | if (isNaN(index)) return 22 | this.layout.scrollToIndex(index, 1) 23 | } 24 | toBack() { 25 | director.loadScene("main") 26 | } 27 | 28 | onRefreshEvent(item: Node, index: number) { 29 | item.getComponent(BaseItem)?.show(this.datas[index], index, this.onClickItem.bind(this)) 30 | } 31 | onClickItem(index: number) { 32 | this.datas.splice(index, 1) 33 | this.layout.total(this.datas.length) 34 | } 35 | addItem(event: any, args: any) { 36 | let count = Number(args) 37 | if (isNaN(count)) return 38 | for (let i = 0; i < count; i++) { 39 | this.datas.push({ message: this.datas.length }) 40 | } 41 | this.layout.total(this.datas.length) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SuperScrollView 2 | 3 | # Optimization for Cocoscreator cc.ScrollView 4 | 5 | [Online Demonstration Effect] (https://icipiqkm.github.io/super-scrollView/) 6 | 7 | [Cocos forum address] (https://forum.cocos.org/topic/118518) 8 | 9 | [Cocoscreator2.x Old Edition here] (https://github.com/icipiqkm/UisuperScrollView) 10 | 11 | # illustrate 12 | 13 | --- 14 | 15 | The increase or decrease of the entire list of data is processed by the use layer. The components don’t need to know what your data structure is 16 | No matter what you do to your array (push, pop ....) 17 | Or when you modify the content of a certain element, you just need to tell the component how many data you have, 18 | This is the method of superlayout.total 19 | 20 | # Interface 21 | 22 | - SuperLayout.total (length: Number) This method is to tell the component how many data you have. Whenever you add deletion or your array length has not changed, but the content of your array has changed. You can call this method to refresh this method. 23 | - SuperLayout.scrolltoheader rolled to the starting location 24 | - SuperLayout.scrolltofooter rolled to the end position 25 | - SuperLayout.scrolltoindex rolled to the specified location 26 | - If you like it, don't forget to click Star, thank you 27 | 28 | # Code is not easy to give a reward at hand to this guy! 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /assets/scripts/refresh-load.ts: -------------------------------------------------------------------------------- 1 | 2 | import { _decorator, Node, Tween, Vec3, Label } from 'cc'; 3 | import { BaseMain } from './baseMain'; 4 | const { ccclass, property } = _decorator; 5 | 6 | @ccclass('RefreshLoad') 7 | export class RefreshLoad extends BaseMain { 8 | @property(Node) header!: Node 9 | @property(Node) footer!: Node 10 | onLoad() { 11 | this.header.setScale(new Vec3(1, 0, 1)) 12 | this.footer.setScale(new Vec3(1, 0, 1)) 13 | } 14 | 15 | private headerTween!: Tween 16 | private footerTween!: Tween 17 | onHeader(scrollView: any, event: any) { 18 | if (event.progress > 2) { 19 | if (!(this.header as any)['playing']) { 20 | this.headerTween = new Tween(this.header!); 21 | this.headerTween.to(0.518, { 22 | scale: new Vec3(1, 1, 1), 23 | }, { 24 | easing: "elasticOut" 25 | }); 26 | this.headerTween.start(); 27 | (this.header as any)['playing'] = true 28 | } 29 | } else { 30 | this.headerTween?.stop(); 31 | (this.header as any)['playing'] = false 32 | this.header.setScale(new Vec3(1, event.progress, 1)) 33 | } 34 | 35 | let label = this.header.getComponentInChildren(Label)! 36 | if (event.stage == "touch") { 37 | label.string = "↓ 继续下拉" 38 | } 39 | if (event.stage == "wait") { 40 | label.string = "↑ 松开刷新" 41 | } 42 | if (event.stage == "lock") { 43 | label.string = this.datas.length == 0 ? "没有数据" : "刷新中..." 44 | } 45 | if (event.stage == 'release') { 46 | label.string = "" 47 | } 48 | if (event.action) { 49 | this.scheduleOnce(() => this.layout.total(this.datas.length), 1) 50 | } 51 | } 52 | onFooter(scrollView: any, event: any) { 53 | if (event.progress > 2) { 54 | if (!(this.footer as any)['playing']) { 55 | this.footerTween = new Tween(this.footer!); 56 | this.footerTween.to(0.518, { 57 | scale: new Vec3(1, 1, 1), 58 | }, { 59 | easing: "elasticOut" 60 | }); 61 | this.footerTween.start(); 62 | (this.footer as any)['playing'] = true 63 | } 64 | } else { 65 | this.footerTween?.stop(); 66 | (this.footer as any)['playing'] = false 67 | this.footer.setScale(new Vec3(1, event.progress, 1)) 68 | } 69 | 70 | let label = this.footer.getComponentInChildren(Label)! 71 | if (event.stage == "touch") { 72 | label.string = "↑ 继续上拉" 73 | } 74 | if (event.stage == "wait") { 75 | label.string = "↓ 松开加载" 76 | } 77 | if (event.stage == "lock") { 78 | label.string = "加载中..." 79 | } 80 | if (event.stage == 'release') { 81 | label.string = "" 82 | } 83 | if (event.action) { 84 | for (let i = 0; i < 6; i++) { 85 | this.datas.push({ 86 | message: `${this.datas.length}` 87 | }) 88 | } 89 | this.scheduleOnce(() => this.layout.total(this.datas.length), 1) 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /assets/prefabs/page.prefab: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "__type__": "cc.Prefab", 4 | "_name": "", 5 | "_objFlags": 0, 6 | "_native": "", 7 | "data": { 8 | "__id__": 1 9 | }, 10 | "optimizationPolicy": 0, 11 | "asyncLoadAssets": false 12 | }, 13 | { 14 | "__type__": "cc.Node", 15 | "_name": "page", 16 | "_objFlags": 0, 17 | "_parent": null, 18 | "_children": [ 19 | { 20 | "__id__": 2 21 | } 22 | ], 23 | "_active": true, 24 | "_components": [ 25 | { 26 | "__id__": 10 27 | }, 28 | { 29 | "__id__": 12 30 | }, 31 | { 32 | "__id__": 14 33 | } 34 | ], 35 | "_prefab": { 36 | "__id__": 16 37 | }, 38 | "_lpos": { 39 | "__type__": "cc.Vec3", 40 | "x": 250, 41 | "y": 0, 42 | "z": 0 43 | }, 44 | "_lrot": { 45 | "__type__": "cc.Quat", 46 | "x": 0, 47 | "y": 0, 48 | "z": 0, 49 | "w": 1 50 | }, 51 | "_lscale": { 52 | "__type__": "cc.Vec3", 53 | "x": 1, 54 | "y": 1, 55 | "z": 1 56 | }, 57 | "_layer": 33554432, 58 | "_euler": { 59 | "__type__": "cc.Vec3", 60 | "x": 0, 61 | "y": 0, 62 | "z": 0 63 | }, 64 | "_id": "" 65 | }, 66 | { 67 | "__type__": "cc.Node", 68 | "_name": "Label", 69 | "_objFlags": 0, 70 | "_parent": { 71 | "__id__": 1 72 | }, 73 | "_children": [], 74 | "_active": true, 75 | "_components": [ 76 | { 77 | "__id__": 3 78 | }, 79 | { 80 | "__id__": 5 81 | }, 82 | { 83 | "__id__": 7 84 | } 85 | ], 86 | "_prefab": { 87 | "__id__": 9 88 | }, 89 | "_lpos": { 90 | "__type__": "cc.Vec3", 91 | "x": 0, 92 | "y": 0, 93 | "z": 0 94 | }, 95 | "_lrot": { 96 | "__type__": "cc.Quat", 97 | "x": 0, 98 | "y": 0, 99 | "z": 0, 100 | "w": 1 101 | }, 102 | "_lscale": { 103 | "__type__": "cc.Vec3", 104 | "x": 1, 105 | "y": 1, 106 | "z": 1 107 | }, 108 | "_layer": 33554432, 109 | "_euler": { 110 | "__type__": "cc.Vec3", 111 | "x": 0, 112 | "y": 0, 113 | "z": 0 114 | }, 115 | "_id": "" 116 | }, 117 | { 118 | "__type__": "cc.UITransform", 119 | "_name": "", 120 | "_objFlags": 0, 121 | "node": { 122 | "__id__": 2 123 | }, 124 | "_enabled": true, 125 | "__prefab": { 126 | "__id__": 4 127 | }, 128 | "_contentSize": { 129 | "__type__": "cc.Size", 130 | "width": 422.56, 131 | "height": 252 132 | }, 133 | "_anchorPoint": { 134 | "__type__": "cc.Vec2", 135 | "x": 0.5, 136 | "y": 0.5 137 | }, 138 | "_id": "" 139 | }, 140 | { 141 | "__type__": "cc.CompPrefabInfo", 142 | "fileId": "c68UOAlNhN171Umca6yVvF" 143 | }, 144 | { 145 | "__type__": "cc.Label", 146 | "_name": "", 147 | "_objFlags": 0, 148 | "node": { 149 | "__id__": 2 150 | }, 151 | "_enabled": true, 152 | "__prefab": { 153 | "__id__": 6 154 | }, 155 | "_visFlags": 0, 156 | "_customMaterial": null, 157 | "_srcBlendFactor": 2, 158 | "_dstBlendFactor": 4, 159 | "_color": { 160 | "__type__": "cc.Color", 161 | "r": 255, 162 | "g": 255, 163 | "b": 255, 164 | "a": 255 165 | }, 166 | "_string": "label", 167 | "_horizontalAlign": 1, 168 | "_verticalAlign": 1, 169 | "_actualFontSize": 200, 170 | "_fontSize": 200, 171 | "_fontFamily": "Arial", 172 | "_lineHeight": 200, 173 | "_overflow": 0, 174 | "_enableWrapText": true, 175 | "_font": null, 176 | "_isSystemFontUsed": true, 177 | "_isItalic": false, 178 | "_isBold": false, 179 | "_isUnderline": false, 180 | "_underlineHeight": 2, 181 | "_cacheMode": 0, 182 | "_id": "" 183 | }, 184 | { 185 | "__type__": "cc.CompPrefabInfo", 186 | "fileId": "2frm37uaJHQr0AEEaYyM82" 187 | }, 188 | { 189 | "__type__": "747fcCLlqVGuLwfCV1CjmZm", 190 | "_name": "", 191 | "_objFlags": 0, 192 | "node": { 193 | "__id__": 2 194 | }, 195 | "_enabled": true, 196 | "__prefab": { 197 | "__id__": 8 198 | }, 199 | "label": { 200 | "__id__": 5 201 | }, 202 | "_id": "" 203 | }, 204 | { 205 | "__type__": "cc.CompPrefabInfo", 206 | "fileId": "b1U1qoDzlL/rxXDYZMnbGY" 207 | }, 208 | { 209 | "__type__": "cc.PrefabInfo", 210 | "root": { 211 | "__id__": 1 212 | }, 213 | "asset": { 214 | "__id__": 0 215 | }, 216 | "fileId": "04vHvd4y5JPpd2gnuAAyC5" 217 | }, 218 | { 219 | "__type__": "cc.UITransform", 220 | "_name": "", 221 | "_objFlags": 0, 222 | "node": { 223 | "__id__": 1 224 | }, 225 | "_enabled": true, 226 | "__prefab": { 227 | "__id__": 11 228 | }, 229 | "_contentSize": { 230 | "__type__": "cc.Size", 231 | "width": 1000, 232 | "height": 300 233 | }, 234 | "_anchorPoint": { 235 | "__type__": "cc.Vec2", 236 | "x": 0.5, 237 | "y": 0.5 238 | }, 239 | "_id": "" 240 | }, 241 | { 242 | "__type__": "cc.CompPrefabInfo", 243 | "fileId": "b5sM9g3kJDEq9eoxtvjd92" 244 | }, 245 | { 246 | "__type__": "cc.Sprite", 247 | "_name": "", 248 | "_objFlags": 0, 249 | "node": { 250 | "__id__": 1 251 | }, 252 | "_enabled": true, 253 | "__prefab": { 254 | "__id__": 13 255 | }, 256 | "_visFlags": 0, 257 | "_customMaterial": null, 258 | "_srcBlendFactor": 2, 259 | "_dstBlendFactor": 4, 260 | "_color": { 261 | "__type__": "cc.Color", 262 | "r": 78, 263 | "g": 156, 264 | "b": 87, 265 | "a": 255 266 | }, 267 | "_spriteFrame": { 268 | "__uuid__": "b730527c-3233-41c2-aaf7-7cdab58f9749@f9941", 269 | "__expectedType__": "cc.SpriteFrame" 270 | }, 271 | "_type": 1, 272 | "_fillType": 0, 273 | "_sizeMode": 0, 274 | "_fillCenter": { 275 | "__type__": "cc.Vec2", 276 | "x": 0, 277 | "y": 0 278 | }, 279 | "_fillStart": 0, 280 | "_fillRange": 0, 281 | "_isTrimmedMode": true, 282 | "_useGrayscale": false, 283 | "_atlas": null, 284 | "_id": "" 285 | }, 286 | { 287 | "__type__": "cc.CompPrefabInfo", 288 | "fileId": "caphIITHFPSpbjE921BKQI" 289 | }, 290 | { 291 | "__type__": "747fcCLlqVGuLwfCV1CjmZm", 292 | "_name": "", 293 | "_objFlags": 0, 294 | "node": { 295 | "__id__": 1 296 | }, 297 | "_enabled": true, 298 | "__prefab": { 299 | "__id__": 15 300 | }, 301 | "label": { 302 | "__id__": 5 303 | }, 304 | "_id": "" 305 | }, 306 | { 307 | "__type__": "cc.CompPrefabInfo", 308 | "fileId": "f63zVjUUFEPbBjasAZpcqi" 309 | }, 310 | { 311 | "__type__": "cc.PrefabInfo", 312 | "root": { 313 | "__id__": 1 314 | }, 315 | "asset": { 316 | "__id__": 0 317 | }, 318 | "fileId": "5dx8C/N6VInL7ieraLnDy+" 319 | } 320 | ] -------------------------------------------------------------------------------- /assets/prefabs/page-scrollview.prefab: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "__type__": "cc.Prefab", 4 | "_name": "", 5 | "_objFlags": 0, 6 | "_native": "", 7 | "data": { 8 | "__id__": 1 9 | }, 10 | "optimizationPolicy": 0, 11 | "asyncLoadAssets": false 12 | }, 13 | { 14 | "__type__": "cc.Node", 15 | "_name": "page-scrollview", 16 | "_objFlags": 0, 17 | "_parent": null, 18 | "_children": [ 19 | { 20 | "__id__": 2 21 | }, 22 | { 23 | "__id__": 12 24 | } 25 | ], 26 | "_active": true, 27 | "_components": [ 28 | { 29 | "__id__": 39 30 | }, 31 | { 32 | "__id__": 41 33 | }, 34 | { 35 | "__id__": 43 36 | } 37 | ], 38 | "_prefab": { 39 | "__id__": 45 40 | }, 41 | "_lpos": { 42 | "__type__": "cc.Vec3", 43 | "x": 250, 44 | "y": 0, 45 | "z": 0 46 | }, 47 | "_lrot": { 48 | "__type__": "cc.Quat", 49 | "x": 0, 50 | "y": 0, 51 | "z": 0, 52 | "w": 1 53 | }, 54 | "_lscale": { 55 | "__type__": "cc.Vec3", 56 | "x": 1, 57 | "y": 1, 58 | "z": 1 59 | }, 60 | "_layer": 33554432, 61 | "_euler": { 62 | "__type__": "cc.Vec3", 63 | "x": 0, 64 | "y": 0, 65 | "z": 0 66 | }, 67 | "_id": "" 68 | }, 69 | { 70 | "__type__": "cc.Node", 71 | "_name": "Label", 72 | "_objFlags": 0, 73 | "_parent": { 74 | "__id__": 1 75 | }, 76 | "_children": [], 77 | "_active": true, 78 | "_components": [ 79 | { 80 | "__id__": 3 81 | }, 82 | { 83 | "__id__": 5 84 | }, 85 | { 86 | "__id__": 7 87 | }, 88 | { 89 | "__id__": 9 90 | } 91 | ], 92 | "_prefab": { 93 | "__id__": 11 94 | }, 95 | "_lpos": { 96 | "__type__": "cc.Vec3", 97 | "x": 0, 98 | "y": 100, 99 | "z": 0 100 | }, 101 | "_lrot": { 102 | "__type__": "cc.Quat", 103 | "x": 0, 104 | "y": 0, 105 | "z": 0, 106 | "w": 1 107 | }, 108 | "_lscale": { 109 | "__type__": "cc.Vec3", 110 | "x": 1, 111 | "y": 1, 112 | "z": 1 113 | }, 114 | "_layer": 33554432, 115 | "_euler": { 116 | "__type__": "cc.Vec3", 117 | "x": 0, 118 | "y": 0, 119 | "z": 0 120 | }, 121 | "_id": "" 122 | }, 123 | { 124 | "__type__": "cc.UITransform", 125 | "_name": "", 126 | "_objFlags": 0, 127 | "node": { 128 | "__id__": 2 129 | }, 130 | "_enabled": true, 131 | "__prefab": { 132 | "__id__": 4 133 | }, 134 | "_contentSize": { 135 | "__type__": "cc.Size", 136 | "width": 211.28, 137 | "height": 126 138 | }, 139 | "_anchorPoint": { 140 | "__type__": "cc.Vec2", 141 | "x": 0.5, 142 | "y": 0.5 143 | }, 144 | "_id": "" 145 | }, 146 | { 147 | "__type__": "cc.CompPrefabInfo", 148 | "fileId": "c68UOAlNhN171Umca6yVvF" 149 | }, 150 | { 151 | "__type__": "cc.Label", 152 | "_name": "", 153 | "_objFlags": 0, 154 | "node": { 155 | "__id__": 2 156 | }, 157 | "_enabled": true, 158 | "__prefab": { 159 | "__id__": 6 160 | }, 161 | "_visFlags": 0, 162 | "_customMaterial": null, 163 | "_srcBlendFactor": 2, 164 | "_dstBlendFactor": 4, 165 | "_color": { 166 | "__type__": "cc.Color", 167 | "r": 255, 168 | "g": 255, 169 | "b": 255, 170 | "a": 255 171 | }, 172 | "_string": "label", 173 | "_horizontalAlign": 1, 174 | "_verticalAlign": 1, 175 | "_actualFontSize": 100, 176 | "_fontSize": 100, 177 | "_fontFamily": "Arial", 178 | "_lineHeight": 100, 179 | "_overflow": 0, 180 | "_enableWrapText": true, 181 | "_font": null, 182 | "_isSystemFontUsed": true, 183 | "_isItalic": false, 184 | "_isBold": false, 185 | "_isUnderline": false, 186 | "_underlineHeight": 2, 187 | "_cacheMode": 0, 188 | "_id": "" 189 | }, 190 | { 191 | "__type__": "cc.CompPrefabInfo", 192 | "fileId": "2frm37uaJHQr0AEEaYyM82" 193 | }, 194 | { 195 | "__type__": "747fcCLlqVGuLwfCV1CjmZm", 196 | "_name": "", 197 | "_objFlags": 0, 198 | "node": { 199 | "__id__": 2 200 | }, 201 | "_enabled": true, 202 | "__prefab": { 203 | "__id__": 8 204 | }, 205 | "label": { 206 | "__id__": 5 207 | }, 208 | "_id": "" 209 | }, 210 | { 211 | "__type__": "cc.CompPrefabInfo", 212 | "fileId": "b1U1qoDzlL/rxXDYZMnbGY" 213 | }, 214 | { 215 | "__type__": "cc.Widget", 216 | "_name": "", 217 | "_objFlags": 0, 218 | "node": { 219 | "__id__": 2 220 | }, 221 | "_enabled": true, 222 | "__prefab": { 223 | "__id__": 10 224 | }, 225 | "_alignFlags": 1, 226 | "_target": null, 227 | "_left": 0, 228 | "_right": 0, 229 | "_top": -13, 230 | "_bottom": 0, 231 | "_horizontalCenter": 0, 232 | "_verticalCenter": 0, 233 | "_isAbsLeft": true, 234 | "_isAbsRight": true, 235 | "_isAbsTop": true, 236 | "_isAbsBottom": true, 237 | "_isAbsHorizontalCenter": true, 238 | "_isAbsVerticalCenter": true, 239 | "_originalWidth": 0, 240 | "_originalHeight": 0, 241 | "_alignMode": 2, 242 | "_lockFlags": 0, 243 | "_id": "" 244 | }, 245 | { 246 | "__type__": "cc.CompPrefabInfo", 247 | "fileId": "471GV6HnxCMb1TyQntdlVA" 248 | }, 249 | { 250 | "__type__": "cc.PrefabInfo", 251 | "root": { 252 | "__id__": 1 253 | }, 254 | "asset": { 255 | "__id__": 0 256 | }, 257 | "fileId": "04vHvd4y5JPpd2gnuAAyC5" 258 | }, 259 | { 260 | "__type__": "cc.Node", 261 | "_name": "ScrollView", 262 | "_objFlags": 0, 263 | "_parent": { 264 | "__id__": 1 265 | }, 266 | "_children": [ 267 | { 268 | "__id__": 13 269 | } 270 | ], 271 | "_active": true, 272 | "_components": [ 273 | { 274 | "__id__": 30 275 | }, 276 | { 277 | "__id__": 32 278 | }, 279 | { 280 | "__id__": 19 281 | }, 282 | { 283 | "__id__": 34 284 | }, 285 | { 286 | "__id__": 36 287 | } 288 | ], 289 | "_prefab": { 290 | "__id__": 38 291 | }, 292 | "_lpos": { 293 | "__type__": "cc.Vec3", 294 | "x": 0, 295 | "y": -40, 296 | "z": 0 297 | }, 298 | "_lrot": { 299 | "__type__": "cc.Quat", 300 | "x": 0, 301 | "y": 0, 302 | "z": 0, 303 | "w": 1 304 | }, 305 | "_lscale": { 306 | "__type__": "cc.Vec3", 307 | "x": 1, 308 | "y": 1, 309 | "z": 1 310 | }, 311 | "_layer": 33554432, 312 | "_euler": { 313 | "__type__": "cc.Vec3", 314 | "x": 0, 315 | "y": 0, 316 | "z": 0 317 | }, 318 | "_id": "" 319 | }, 320 | { 321 | "__type__": "cc.Node", 322 | "_name": "view", 323 | "_objFlags": 0, 324 | "_parent": { 325 | "__id__": 12 326 | }, 327 | "_children": [ 328 | { 329 | "__id__": 14 330 | } 331 | ], 332 | "_active": true, 333 | "_components": [ 334 | { 335 | "__id__": 21 336 | }, 337 | { 338 | "__id__": 25 339 | }, 340 | { 341 | "__id__": 27 342 | } 343 | ], 344 | "_prefab": { 345 | "__id__": 29 346 | }, 347 | "_lpos": { 348 | "__type__": "cc.Vec3", 349 | "x": 0, 350 | "y": 0, 351 | "z": 0 352 | }, 353 | "_lrot": { 354 | "__type__": "cc.Quat", 355 | "x": 0, 356 | "y": 0, 357 | "z": 0, 358 | "w": 1 359 | }, 360 | "_lscale": { 361 | "__type__": "cc.Vec3", 362 | "x": 1, 363 | "y": 1, 364 | "z": 1 365 | }, 366 | "_layer": 33554432, 367 | "_euler": { 368 | "__type__": "cc.Vec3", 369 | "x": 0, 370 | "y": 0, 371 | "z": 0 372 | }, 373 | "_id": "" 374 | }, 375 | { 376 | "__type__": "cc.Node", 377 | "_name": "content", 378 | "_objFlags": 0, 379 | "_parent": { 380 | "__id__": 13 381 | }, 382 | "_children": [], 383 | "_active": true, 384 | "_components": [ 385 | { 386 | "__id__": 15 387 | }, 388 | { 389 | "__id__": 17 390 | } 391 | ], 392 | "_prefab": { 393 | "__id__": 24 394 | }, 395 | "_lpos": { 396 | "__type__": "cc.Vec3", 397 | "x": -10, 398 | "y": 125, 399 | "z": 0 400 | }, 401 | "_lrot": { 402 | "__type__": "cc.Quat", 403 | "x": 0, 404 | "y": 0, 405 | "z": 0, 406 | "w": 1 407 | }, 408 | "_lscale": { 409 | "__type__": "cc.Vec3", 410 | "x": 1, 411 | "y": 1, 412 | "z": 1 413 | }, 414 | "_layer": 33554432, 415 | "_euler": { 416 | "__type__": "cc.Vec3", 417 | "x": 0, 418 | "y": 0, 419 | "z": 0 420 | }, 421 | "_id": "" 422 | }, 423 | { 424 | "__type__": "cc.UITransform", 425 | "_name": "", 426 | "_objFlags": 0, 427 | "node": { 428 | "__id__": 14 429 | }, 430 | "_enabled": true, 431 | "__prefab": { 432 | "__id__": 16 433 | }, 434 | "_contentSize": { 435 | "__type__": "cc.Size", 436 | "width": 220, 437 | "height": 400 438 | }, 439 | "_anchorPoint": { 440 | "__type__": "cc.Vec2", 441 | "x": 0.5, 442 | "y": 1 443 | }, 444 | "_id": "" 445 | }, 446 | { 447 | "__type__": "cc.CompPrefabInfo", 448 | "fileId": "99yn0cfL9MmZYfJbPmK9qL" 449 | }, 450 | { 451 | "__type__": "4430bdPVstIyrMzuiBW+hni", 452 | "_name": "", 453 | "_objFlags": 0, 454 | "node": { 455 | "__id__": 14 456 | }, 457 | "_enabled": true, 458 | "__prefab": { 459 | "__id__": 18 460 | }, 461 | "scrollView": { 462 | "__id__": 19 463 | }, 464 | "view": { 465 | "__id__": 21 466 | }, 467 | "prefab": { 468 | "__uuid__": "5a756b1c-bdd5-478c-a49e-b0bf0ff12dcc", 469 | "__expectedType__": "cc.Prefab" 470 | }, 471 | "layoutType": 1, 472 | "indexVerticalAxisDirection": 0, 473 | "indexHorizontalAxisDirection": 0, 474 | "verticalAxisDirection": 0, 475 | "horizontalAxisDirection": 0, 476 | "groupItemTotal": 1, 477 | "multiple": 2, 478 | "paddingTop": 10, 479 | "paddingBottom": 10, 480 | "paddingLeft": 10, 481 | "paddingRight": 10, 482 | "spacingX": 0, 483 | "spacingY": 10, 484 | "affectedByScale": false, 485 | "isPageView": false, 486 | "pageTurningSpeed": 0.3, 487 | "scrollThreshold": 0.5, 488 | "autoPageTurningThreshold": 100, 489 | "pageEvents": [], 490 | "autoCenter": false, 491 | "centerTime": 1, 492 | "centerAnchor": { 493 | "__type__": "cc.Vec2", 494 | "x": 0.5, 495 | "y": 0.5 496 | }, 497 | "headerLoop": false, 498 | "footerLoop": false, 499 | "refreshItemEvents": [ 500 | { 501 | "__id__": 23 502 | } 503 | ], 504 | "_id": "" 505 | }, 506 | { 507 | "__type__": "cc.CompPrefabInfo", 508 | "fileId": "9aJKbVw8lJdIgiqUwUmkuW" 509 | }, 510 | { 511 | "__type__": "72cf528Z4dK+ofNYmM2Xf22", 512 | "_name": "", 513 | "_objFlags": 0, 514 | "node": { 515 | "__id__": 12 516 | }, 517 | "_enabled": true, 518 | "__prefab": { 519 | "__id__": 20 520 | }, 521 | "bounceDuration": 1, 522 | "brake": 0.5, 523 | "elastic": true, 524 | "inertia": true, 525 | "horizontal": false, 526 | "vertical": true, 527 | "cancelInnerEvents": true, 528 | "scrollEvents": [], 529 | "_content": { 530 | "__id__": 14 531 | }, 532 | "_horizontalScrollBar": null, 533 | "_verticalScrollBar": null, 534 | "isTransmitEvent": true, 535 | "pullRefresh": false, 536 | "headerOutOffset": 200, 537 | "headerMultiple": 2, 538 | "footerOutOffset": 200, 539 | "footerMultiple": 2, 540 | "headerEvents": [], 541 | "footerEvents": [], 542 | "_id": "" 543 | }, 544 | { 545 | "__type__": "cc.CompPrefabInfo", 546 | "fileId": "52BnJbMWxE+7VB6rD6e9Ai" 547 | }, 548 | { 549 | "__type__": "cc.UITransform", 550 | "_name": "", 551 | "_objFlags": 0, 552 | "node": { 553 | "__id__": 13 554 | }, 555 | "_enabled": true, 556 | "__prefab": { 557 | "__id__": 22 558 | }, 559 | "_contentSize": { 560 | "__type__": "cc.Size", 561 | "width": 960, 562 | "height": 180 563 | }, 564 | "_anchorPoint": { 565 | "__type__": "cc.Vec2", 566 | "x": 0.5, 567 | "y": 0.5 568 | }, 569 | "_id": "" 570 | }, 571 | { 572 | "__type__": "cc.CompPrefabInfo", 573 | "fileId": "adVJjE6iNG9YcIKwDKe/zq" 574 | }, 575 | { 576 | "__type__": "cc.ClickEvent", 577 | "target": { 578 | "__id__": 12 579 | }, 580 | "component": "", 581 | "_componentId": "5f170uFuGRCJZCiHTMaOxhs", 582 | "handler": "onRefreshEvent", 583 | "customEventData": "" 584 | }, 585 | { 586 | "__type__": "cc.PrefabInfo", 587 | "root": { 588 | "__id__": 1 589 | }, 590 | "asset": { 591 | "__id__": 0 592 | }, 593 | "fileId": "f15j+q97FM57c/7voTtH7C" 594 | }, 595 | { 596 | "__type__": "cc.Mask", 597 | "_name": "", 598 | "_objFlags": 0, 599 | "node": { 600 | "__id__": 13 601 | }, 602 | "_enabled": true, 603 | "__prefab": { 604 | "__id__": 26 605 | }, 606 | "_visFlags": 0, 607 | "_customMaterial": null, 608 | "_srcBlendFactor": 2, 609 | "_dstBlendFactor": 4, 610 | "_color": { 611 | "__type__": "cc.Color", 612 | "r": 255, 613 | "g": 255, 614 | "b": 255, 615 | "a": 255 616 | }, 617 | "_type": 0, 618 | "_inverted": false, 619 | "_segments": 64, 620 | "_spriteFrame": null, 621 | "_alphaThreshold": 0.1, 622 | "_id": "" 623 | }, 624 | { 625 | "__type__": "cc.CompPrefabInfo", 626 | "fileId": "4eIg29oQZFVLk+NZnwDdlk" 627 | }, 628 | { 629 | "__type__": "cc.Widget", 630 | "_name": "", 631 | "_objFlags": 0, 632 | "node": { 633 | "__id__": 13 634 | }, 635 | "_enabled": true, 636 | "__prefab": { 637 | "__id__": 28 638 | }, 639 | "_alignFlags": 45, 640 | "_target": null, 641 | "_left": 0, 642 | "_right": 0, 643 | "_top": 0, 644 | "_bottom": 0, 645 | "_horizontalCenter": 0, 646 | "_verticalCenter": 0, 647 | "_isAbsLeft": true, 648 | "_isAbsRight": true, 649 | "_isAbsTop": true, 650 | "_isAbsBottom": true, 651 | "_isAbsHorizontalCenter": true, 652 | "_isAbsVerticalCenter": true, 653 | "_originalWidth": 240, 654 | "_originalHeight": 250, 655 | "_alignMode": 2, 656 | "_lockFlags": 0, 657 | "_id": "" 658 | }, 659 | { 660 | "__type__": "cc.CompPrefabInfo", 661 | "fileId": "9eWhbfMqdEgL1s1L4R8iA4" 662 | }, 663 | { 664 | "__type__": "cc.PrefabInfo", 665 | "root": { 666 | "__id__": 1 667 | }, 668 | "asset": { 669 | "__id__": 0 670 | }, 671 | "fileId": "7138cbwpRF3JGckzKMnGYA" 672 | }, 673 | { 674 | "__type__": "cc.UITransform", 675 | "_name": "", 676 | "_objFlags": 0, 677 | "node": { 678 | "__id__": 12 679 | }, 680 | "_enabled": true, 681 | "__prefab": { 682 | "__id__": 31 683 | }, 684 | "_contentSize": { 685 | "__type__": "cc.Size", 686 | "width": 960, 687 | "height": 180 688 | }, 689 | "_anchorPoint": { 690 | "__type__": "cc.Vec2", 691 | "x": 0.5, 692 | "y": 0.5 693 | }, 694 | "_id": "" 695 | }, 696 | { 697 | "__type__": "cc.CompPrefabInfo", 698 | "fileId": "71kmounFRG/K27WWBbH2RB" 699 | }, 700 | { 701 | "__type__": "cc.Sprite", 702 | "_name": "", 703 | "_objFlags": 0, 704 | "node": { 705 | "__id__": 12 706 | }, 707 | "_enabled": true, 708 | "__prefab": { 709 | "__id__": 33 710 | }, 711 | "_visFlags": 0, 712 | "_customMaterial": null, 713 | "_srcBlendFactor": 2, 714 | "_dstBlendFactor": 4, 715 | "_color": { 716 | "__type__": "cc.Color", 717 | "r": 26, 718 | "g": 34, 719 | "b": 44, 720 | "a": 255 721 | }, 722 | "_spriteFrame": { 723 | "__uuid__": "b730527c-3233-41c2-aaf7-7cdab58f9749@f9941", 724 | "__expectedType__": "cc.SpriteFrame" 725 | }, 726 | "_type": 1, 727 | "_fillType": 0, 728 | "_sizeMode": 0, 729 | "_fillCenter": { 730 | "__type__": "cc.Vec2", 731 | "x": 0, 732 | "y": 0 733 | }, 734 | "_fillStart": 0, 735 | "_fillRange": 0, 736 | "_isTrimmedMode": true, 737 | "_useGrayscale": false, 738 | "_atlas": null, 739 | "_id": "" 740 | }, 741 | { 742 | "__type__": "cc.CompPrefabInfo", 743 | "fileId": "8ce2Xg/B9GhY0DNafD/vxa" 744 | }, 745 | { 746 | "__type__": "cc.Widget", 747 | "_name": "", 748 | "_objFlags": 0, 749 | "node": { 750 | "__id__": 12 751 | }, 752 | "_enabled": true, 753 | "__prefab": { 754 | "__id__": 35 755 | }, 756 | "_alignFlags": 45, 757 | "_target": null, 758 | "_left": 20, 759 | "_right": 20, 760 | "_top": 100, 761 | "_bottom": 20, 762 | "_horizontalCenter": 0, 763 | "_verticalCenter": 0, 764 | "_isAbsLeft": true, 765 | "_isAbsRight": true, 766 | "_isAbsTop": true, 767 | "_isAbsBottom": true, 768 | "_isAbsHorizontalCenter": true, 769 | "_isAbsVerticalCenter": true, 770 | "_originalWidth": 240, 771 | "_originalHeight": 250, 772 | "_alignMode": 2, 773 | "_lockFlags": 0, 774 | "_id": "" 775 | }, 776 | { 777 | "__type__": "cc.CompPrefabInfo", 778 | "fileId": "5dhz80CvlKao03uguOobI/" 779 | }, 780 | { 781 | "__type__": "5f170uFuGRCJZCiHTMaOxhs", 782 | "_name": "", 783 | "_objFlags": 0, 784 | "node": { 785 | "__id__": 12 786 | }, 787 | "_enabled": true, 788 | "__prefab": { 789 | "__id__": 37 790 | }, 791 | "layout": { 792 | "__id__": 17 793 | }, 794 | "_id": "" 795 | }, 796 | { 797 | "__type__": "cc.CompPrefabInfo", 798 | "fileId": "84UUJD+g1G16Hw3UkNwoy4" 799 | }, 800 | { 801 | "__type__": "cc.PrefabInfo", 802 | "root": { 803 | "__id__": 1 804 | }, 805 | "asset": { 806 | "__id__": 0 807 | }, 808 | "fileId": "09JySg68tFyLb+hCLJuuQN" 809 | }, 810 | { 811 | "__type__": "cc.UITransform", 812 | "_name": "", 813 | "_objFlags": 0, 814 | "node": { 815 | "__id__": 1 816 | }, 817 | "_enabled": true, 818 | "__prefab": { 819 | "__id__": 40 820 | }, 821 | "_contentSize": { 822 | "__type__": "cc.Size", 823 | "width": 1000, 824 | "height": 300 825 | }, 826 | "_anchorPoint": { 827 | "__type__": "cc.Vec2", 828 | "x": 0.5, 829 | "y": 0.5 830 | }, 831 | "_id": "" 832 | }, 833 | { 834 | "__type__": "cc.CompPrefabInfo", 835 | "fileId": "b5sM9g3kJDEq9eoxtvjd92" 836 | }, 837 | { 838 | "__type__": "cc.Sprite", 839 | "_name": "", 840 | "_objFlags": 0, 841 | "node": { 842 | "__id__": 1 843 | }, 844 | "_enabled": true, 845 | "__prefab": { 846 | "__id__": 42 847 | }, 848 | "_visFlags": 0, 849 | "_customMaterial": null, 850 | "_srcBlendFactor": 2, 851 | "_dstBlendFactor": 4, 852 | "_color": { 853 | "__type__": "cc.Color", 854 | "r": 78, 855 | "g": 156, 856 | "b": 87, 857 | "a": 255 858 | }, 859 | "_spriteFrame": { 860 | "__uuid__": "b730527c-3233-41c2-aaf7-7cdab58f9749@f9941", 861 | "__expectedType__": "cc.SpriteFrame" 862 | }, 863 | "_type": 1, 864 | "_fillType": 0, 865 | "_sizeMode": 0, 866 | "_fillCenter": { 867 | "__type__": "cc.Vec2", 868 | "x": 0, 869 | "y": 0 870 | }, 871 | "_fillStart": 0, 872 | "_fillRange": 0, 873 | "_isTrimmedMode": true, 874 | "_useGrayscale": false, 875 | "_atlas": null, 876 | "_id": "" 877 | }, 878 | { 879 | "__type__": "cc.CompPrefabInfo", 880 | "fileId": "caphIITHFPSpbjE921BKQI" 881 | }, 882 | { 883 | "__type__": "747fcCLlqVGuLwfCV1CjmZm", 884 | "_name": "", 885 | "_objFlags": 0, 886 | "node": { 887 | "__id__": 1 888 | }, 889 | "_enabled": true, 890 | "__prefab": { 891 | "__id__": 44 892 | }, 893 | "label": { 894 | "__id__": 5 895 | }, 896 | "_id": "" 897 | }, 898 | { 899 | "__type__": "cc.CompPrefabInfo", 900 | "fileId": "f63zVjUUFEPbBjasAZpcqi" 901 | }, 902 | { 903 | "__type__": "cc.PrefabInfo", 904 | "root": { 905 | "__id__": 1 906 | }, 907 | "asset": { 908 | "__id__": 0 909 | }, 910 | "fileId": "5dx8C/N6VInL7ieraLnDy+" 911 | } 912 | ] -------------------------------------------------------------------------------- /assets/core/super-scrollview.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: steveJobs 3 | * @Email: icipiqkm@gmail.com 4 | * @Date: 2021-8-1 01:15:04 5 | * @Last Modified by: steveJobs 6 | * @Last Modified time: 2021-8-1 14:35:43 7 | * @Description: 8 | */ 9 | import { _decorator, Node, EventTouch, Vec3, Vec2, ScrollView, EventHandler, PageView, EventMouse } from 'cc'; 10 | import { SuperLayout } from './super-layout'; 11 | const { ccclass, property } = _decorator; 12 | const quintEaseOut = (time: number) => { 13 | time -= 1; 14 | return (time * time * time * time * time + 1) 15 | }; 16 | const EPSILON = 1e-4 17 | const OUT_OF_BOUNDARY_BREAKING_FACTOR = 0.015 18 | const _tempVec2 = new Vec2() 19 | export enum ScrollViewDirection { 20 | HORIZONTAL, 21 | VERTICAL, 22 | NONE, 23 | } 24 | @ccclass('SuperScrollview') 25 | export class SuperScrollview extends ScrollView { 26 | private direction: ScrollViewDirection = ScrollViewDirection.NONE 27 | private _layout!: SuperLayout 28 | @property({ 29 | tooltip: "注意!向上传递事件只会发送当前滑动相反方向,如果开启horizontal则会发送vertical事件。如果开启vertical则会发送horizontal事件。同时开启horizontal和vertical 不会发送任何事件" 30 | }) isTransmitEvent: boolean = false 31 | @property pullRefresh: boolean = false 32 | @property({ 33 | displayName: "顶部偏移量", 34 | tooltip: "下拉时超过此偏移会发送下拉事件", 35 | visible: function () { return (this as any).pullRefresh } 36 | }) headerOutOffset: number = 200 37 | @property({ 38 | displayName: "满足触发Header的倍数", 39 | visible: function () { return (this as any).pullRefresh } 40 | }) headerMultiple: number = 2 41 | @property({ 42 | displayName: "底部偏移量", 43 | tooltip: "上拉时超过此偏移会发送上拉事件", 44 | visible: function () { return (this as any).pullRefresh } 45 | }) footerOutOffset: number = 200 46 | @property({ 47 | displayName: "满足触发Footer的倍数", 48 | visible: function () { return (this as any).pullRefresh } 49 | }) footerMultiple: number = 2 50 | @property({ 51 | type: EventHandler, 52 | visible: function () { return (this as any).pullRefresh } 53 | }) headerEvents: EventHandler[] = [] 54 | @property({ 55 | type: EventHandler, 56 | visible: function () { return (this as any).pullRefresh } 57 | }) footerEvents: EventHandler[] = [] 58 | prevLocation: Vec2 = new Vec2() 59 | location: Vec2 = new Vec2() 60 | set autoScrolling(value: boolean) { this._autoScrolling = value } 61 | private _touchBeganPosition = new Vec2() 62 | private _touchEndPosition = new Vec2() 63 | private isMoveHeader: boolean = false 64 | private isMoveFooter: boolean = false 65 | private isLockHeader: boolean = false 66 | private isLockFooter: boolean = false 67 | private headerProgress: number = 0 68 | private footerProgress: number = 0 69 | onLoad() { 70 | if (this.layout.autoCenter) { 71 | this.brake = 0.7 72 | } 73 | } 74 | public onEnable() { 75 | super.onEnable() 76 | this.node.on(PageView.EventType.SCROLL_ENG_WITH_THRESHOLD, this.dispatchPageTurningEvent, this) 77 | 78 | } 79 | 80 | public onDisable() { 81 | super.onDisable() 82 | this.node.off(PageView.EventType.SCROLL_ENG_WITH_THRESHOLD, this.dispatchPageTurningEvent, this) 83 | 84 | } 85 | get layout() { 86 | if (!this._layout) { this._layout = this.content?.getComponent(SuperLayout)! } 87 | return this._layout 88 | } 89 | private isCallSoonFinish: boolean = false 90 | get curPageIdx() { 91 | return this.layout["_currPageIndex"] 92 | } 93 | getPages() { 94 | return new Array(this.layout.itemTotal) 95 | } 96 | protected _getContentTopBoundary() { 97 | if (!this._content) { 98 | return -1 99 | } 100 | let offset = this.layout.isOfTopBoundary == 0 ? this._topBoundary : this.layout.isOfTopBoundary 101 | return offset 102 | } 103 | protected _getContentBottomBoundary() { 104 | if (!this._content) { 105 | return -1 106 | } 107 | let offset = this.layout.isOfButtomBoundary == 0 ? this._bottomBoundary : this.layout.isOfButtomBoundary 108 | return offset 109 | } 110 | protected _getContentLeftBoundary() { 111 | if (!this._content) { 112 | return -1 113 | } 114 | let offset = this.layout.isOfLeftBoundary == 0 ? this._leftBoundary : this.layout.isOfLeftBoundary 115 | return offset 116 | } 117 | protected _getContentRightBoundary() { 118 | if (!this._content) { 119 | return -1 120 | } 121 | let offset = this.layout.isOfRightBoundary == 0 ? this._rightBoundary : this.layout.isOfRightBoundary 122 | return offset 123 | } 124 | protected _onTouchBegan(event: EventTouch, captureListeners?: Node[]) { 125 | this.isCallSoonFinish = false 126 | this.direction = ScrollViewDirection.NONE 127 | if (this.layout.isPageView) { 128 | event.touch!.getUILocation(_tempVec2) 129 | Vec2.set(this._touchBeganPosition, _tempVec2.x, _tempVec2.y) 130 | } 131 | super._onTouchBegan(event, captureListeners) 132 | if (this.isTransmitEvent) { 133 | this.transmitEvent(event, Node.EventType.TOUCH_START) 134 | } 135 | } 136 | protected _onTouchMoved(event: EventTouch, captureListeners: any) { 137 | if (this.isTransmitEvent) { 138 | 139 | if (this.direction == ScrollViewDirection.NONE) { 140 | var start = event.getStartLocation() 141 | var curre = event.getLocation() 142 | var xOffset = Math.abs(start.x - curre.x) 143 | var yOffset = Math.abs(start.y - curre.y) 144 | if (xOffset > yOffset) { 145 | // 本ScrollView滑动方向过程中达到一定偏移量是也可以向上发送事件 146 | // if (this.vertical) { 147 | // if (xOffset - yOffset > 50) { 148 | // this.direction = UIScrollViewDirection.HORIZONTAL 149 | // } 150 | // } 151 | this.direction = ScrollViewDirection.HORIZONTAL 152 | 153 | } else if (yOffset > xOffset) { 154 | // 本ScrollView滑动方向过程中达到一定偏移量是也可以向上发送事件 155 | // if (this.horizontal) { 156 | // if (yOffset - xOffset > 50) { 157 | // this.direction = UIScrollViewDirection.VERTICAL 158 | // } 159 | // } 160 | this.direction = ScrollViewDirection.VERTICAL 161 | } 162 | } 163 | var canTransmit = (this.vertical && this.direction === ScrollViewDirection.HORIZONTAL) || this.horizontal && this.direction == ScrollViewDirection.VERTICAL 164 | if (canTransmit) { 165 | this.transmitEvent(event, Node.EventType.TOUCH_MOVE) 166 | return 167 | } 168 | } 169 | this.prevLocation = event.touch?.getPreviousLocation()! 170 | this.location = event.touch?.getLocation()! 171 | super._onTouchMoved(event, captureListeners) 172 | if (this.pullRefresh) { 173 | let outOfBoundary = this._getHowMuchOutOfBoundary() 174 | let offset = this.vertical ? outOfBoundary.y : -outOfBoundary.x 175 | if (offset > 0 && !this.isLockHeader && !this.isLockFooter) { 176 | this.headerProgress = offset < EPSILON ? 0 : offset / this.headerOutOffset 177 | this.isMoveHeader = this.headerProgress >= this.headerMultiple 178 | EventHandler.emitEvents(this.headerEvents, this, { action: false, progress: this.headerProgress, stage: this.isMoveHeader ? "wait" : "touch" }) 179 | EventHandler.emitEvents(this.footerEvents, this, { action: false, progress: 0, stage: "release" }) 180 | } else if (offset < 0 && !this.isLockHeader && !this.isLockFooter) { 181 | this.footerProgress = -offset < EPSILON ? 0 : -offset / this.footerOutOffset 182 | this.isMoveFooter = this.footerProgress >= this.footerMultiple 183 | EventHandler.emitEvents(this.footerEvents, this, { action: false, progress: this.footerProgress, stage: this.isMoveFooter ? "wait" : "touch" }) 184 | EventHandler.emitEvents(this.headerEvents, this, { action: false, progress: 0, stage: "release" }) 185 | } else if (offset == 0 && !this.isLockHeader && !this.isLockFooter) { 186 | this.clearProgress() 187 | } 188 | } 189 | } 190 | 191 | protected _onTouchEnded(event: EventTouch, captureListeners: any) { 192 | if (this.layout.isPageView) { 193 | event.touch!.getUILocation(_tempVec2) 194 | Vec2.set(this._touchEndPosition, _tempVec2.x, _tempVec2.y) 195 | } 196 | super._onTouchEnded(event, captureListeners) 197 | if (this.isTransmitEvent) { 198 | this.transmitEvent(event, Node.EventType.TOUCH_END) 199 | } 200 | } 201 | 202 | protected _onTouchCancelled(event: EventTouch, captureListeners: any) { 203 | if (this.layout.isPageView) { 204 | event.touch!.getUILocation(_tempVec2) 205 | Vec2.set(this._touchEndPosition, _tempVec2.x, _tempVec2.y) 206 | } 207 | super._onTouchCancelled(event, captureListeners) 208 | if (this.isTransmitEvent) { 209 | this.transmitEvent(event, Node.EventType.TOUCH_CANCEL) 210 | } 211 | } 212 | protected _processAutoScrolling(dt: number) { 213 | const isAutoScrollBrake = this._isNecessaryAutoScrollBrake() 214 | const brakingFactor = isAutoScrollBrake ? OUT_OF_BOUNDARY_BREAKING_FACTOR : 1 215 | this._autoScrollAccumulatedTime += dt * (1 / brakingFactor); 216 | let percentage = Math.min(1, this._autoScrollAccumulatedTime / this._autoScrollTotalTime) 217 | if (this._autoScrollAttenuate) { 218 | percentage = quintEaseOut(percentage) 219 | } 220 | const clonedAutoScrollTargetDelta = this._autoScrollTargetDelta.clone() 221 | clonedAutoScrollTargetDelta.multiplyScalar(percentage) 222 | const clonedAutoScrollStartPosition = this._autoScrollStartPosition.clone() 223 | clonedAutoScrollStartPosition.add(clonedAutoScrollTargetDelta); 224 | let reachedEnd = Math.abs(percentage - 1) <= EPSILON; 225 | 226 | const fireEvent = Math.abs(percentage - 1) <= this.getScrollEndedEventTiming() 227 | if (fireEvent && !this._isScrollEndedWithThresholdEventFired) { 228 | this._dispatchEvent(ScrollView.EventType.SCROLL_ENG_WITH_THRESHOLD) 229 | this._isScrollEndedWithThresholdEventFired = true; 230 | } 231 | if (this.elastic) { 232 | const brakeOffsetPosition = clonedAutoScrollStartPosition.clone() 233 | brakeOffsetPosition.subtract(this._autoScrollBrakingStartPosition) 234 | if (isAutoScrollBrake) { 235 | brakeOffsetPosition.multiplyScalar(brakingFactor) 236 | } 237 | clonedAutoScrollStartPosition.set(this._autoScrollBrakingStartPosition) 238 | clonedAutoScrollStartPosition.add(brakeOffsetPosition) 239 | } else { 240 | const moveDelta = clonedAutoScrollStartPosition.clone() 241 | moveDelta.subtract(this.getContentPosition()) 242 | const outOfBoundary = this._getHowMuchOutOfBoundary(moveDelta) 243 | if (!outOfBoundary.equals(Vec3.ZERO, EPSILON)) { 244 | clonedAutoScrollStartPosition.add(outOfBoundary) 245 | reachedEnd = true; 246 | } 247 | } 248 | if (reachedEnd) { 249 | this._autoScrolling = false; 250 | } 251 | const deltaMove = clonedAutoScrollStartPosition.clone() 252 | deltaMove.subtract(this.getContentPosition()); 253 | this._clampDelta(deltaMove); 254 | /** 重写这个方法的主要原因是插入以下逻辑 功能用于自动居中 其他并未改动 */ 255 | if (this.layout.vertical && Math.abs(deltaMove.y) <= 2 && !this.isCallSoonFinish) { 256 | this.layout["soonFinish"]() 257 | this.isCallSoonFinish = true 258 | } else if (!this.layout.vertical && Math.abs(deltaMove.x) <= 2 && !this.isCallSoonFinish) { 259 | this.layout["soonFinish"]() 260 | this.isCallSoonFinish = true 261 | } 262 | this._moveContent(deltaMove, reachedEnd); 263 | this._dispatchEvent(ScrollView.EventType.SCROLLING) 264 | if (!this._autoScrolling) { 265 | this._isBouncing = false; 266 | this._scrolling = false; 267 | this._dispatchEvent(ScrollView.EventType.SCROLL_ENDED) 268 | } 269 | } 270 | 271 | scrollToAny(moveDelta: Vec3, timeInSecond?: number, attenuated: boolean = true) { 272 | if (timeInSecond) { 273 | 274 | this._startAutoScroll(moveDelta, timeInSecond, attenuated) 275 | } else { 276 | this._moveContent(moveDelta) 277 | } 278 | } 279 | release() { 280 | this.isMoveHeader = false 281 | this.isMoveFooter = false 282 | if (this.isLockHeader || this.isLockFooter) { 283 | this.vertical && this.isLockHeader && (this._topBoundary += this.headerOutOffset) 284 | this.vertical && this.isLockFooter && (this._bottomBoundary -= this.footerOutOffset) 285 | this.horizontal && this.isLockHeader && (this._leftBoundary -= this.headerOutOffset) 286 | this.horizontal && this.isLockFooter && (this._rightBoundary += this.footerOutOffset) 287 | this.clearProgress() 288 | this.layout["onPositionChanged"]() 289 | this.isLockHeader = false 290 | this.isLockFooter = false 291 | this.startAutoScroll() 292 | } 293 | } 294 | startAutoScroll() { 295 | this._autoScrolling = true 296 | this._outOfBoundaryAmountDirty = true 297 | } 298 | protected _startAutoScroll(deltaMove: any, timeInSecond: any, attenuated: any) { 299 | if (this.pullRefresh) { // 如果没有刷新/加载的监听者 则不计算 300 | if (this.isMoveHeader && !this.isLockHeader) { 301 | if (this.vertical) { 302 | this._topBoundary -= this.headerOutOffset 303 | deltaMove.y -= this.headerOutOffset 304 | } 305 | if (this.horizontal) { 306 | this._leftBoundary += this.headerOutOffset 307 | deltaMove.x += this.headerOutOffset 308 | } 309 | this.isLockHeader = true 310 | EventHandler.emitEvents(this.headerEvents, this, { action: true, progress: this.headerProgress, stage: 'lock' }) 311 | } else if (this.isMoveFooter && !this.isLockFooter) { 312 | if (this.vertical) { 313 | this._bottomBoundary += this.footerOutOffset 314 | deltaMove.y += this.footerOutOffset 315 | } 316 | if (this.horizontal) { 317 | this._rightBoundary -= this.footerOutOffset 318 | deltaMove.x -= this.footerOutOffset 319 | } 320 | this.isLockFooter = true 321 | EventHandler.emitEvents(this.footerEvents, this, { action: true, progress: this.footerProgress, stage: 'lock' }) 322 | } 323 | } 324 | super._startAutoScroll(deltaMove, timeInSecond, attenuated) 325 | } 326 | protected _updateScrollBar(outOfBoundary: any) { 327 | super._updateScrollBar(new Vec2(outOfBoundary.x, outOfBoundary.y)) 328 | if (this._autoScrollBraking) return // 自动回弹时不计算 (非手动) 329 | if (!this._autoScrolling) return // 非自动滚动时不计算 330 | if (!this.pullRefresh) return 331 | let offset = this.vertical ? outOfBoundary.y : -outOfBoundary.x 332 | if (offset > 0) { // 下滑 333 | let progress = offset < EPSILON ? 0 : offset / this.headerOutOffset //根据参数 headerOutOffset 计算当前下滑的办百分比 334 | if (this.isLockHeader) { 335 | this.headerProgress = this.headerProgress == 1 ? this.headerProgress : Math.max(progress, 1) 336 | EventHandler.emitEvents(this.headerEvents, this, { action: false, progress: this.headerProgress, stage: "lock" }) 337 | } else { 338 | this.headerProgress = progress < this.headerProgress ? progress : this.headerProgress 339 | EventHandler.emitEvents(this.headerEvents, this, { action: false, progress: this.headerProgress, stage: "release" }) 340 | } 341 | } else if (offset < 0) { 342 | let progress = -offset < EPSILON ? 0 : -offset / this.footerOutOffset //根据参数 footerOutOffset 计算当前下滑的办百分比 343 | if (this.isLockFooter) { 344 | this.footerProgress = this.footerProgress == 1 ? this.footerProgress : Math.max(progress, 1) 345 | EventHandler.emitEvents(this.footerEvents, this, { action: false, progress: this.footerProgress, stage: "lock" }) 346 | } else { 347 | this.footerProgress = progress < this.footerProgress ? progress : this.footerProgress 348 | EventHandler.emitEvents(this.footerEvents, this, { action: false, progress: this.footerProgress, stage: "release" }) 349 | } 350 | } else if (offset == 0) { 351 | // 正常滑动时 如果没有锁定头和尾时 释放所有进度 352 | if (!this.isLockHeader && !this.isLockFooter) { 353 | this.clearProgress() 354 | } 355 | } 356 | } 357 | private clearProgress() { 358 | EventHandler.emitEvents(this.headerEvents, this, { action: false, progress: 0, stage: "release" }) 359 | EventHandler.emitEvents(this.footerEvents, this, { action: false, progress: 0, stage: "release" }) 360 | } 361 | private dispatchPageTurningEvent() { 362 | if (this.layout["_lastPageIndex"] === this.layout["_currPageIndex"]) return 363 | this.layout["_lastPageIndex"] = this.layout["_currPageIndex"] 364 | EventHandler.emitEvents(this.layout.pageEvents, this, PageView.EventType.PAGE_TURNING) 365 | this.node.emit(PageView.EventType.PAGE_TURNING, this) 366 | } 367 | 368 | protected _handleReleaseLogic(touch: any) { 369 | if (this.layout.isPageView) { 370 | this._autoScrollToPage(); 371 | if (this._scrolling) { 372 | this._scrolling = false; 373 | if (!this._autoScrolling) { 374 | this._dispatchEvent(ScrollView.EventType.SCROLL_ENDED); 375 | } 376 | } 377 | } else { 378 | super._handleReleaseLogic(touch) 379 | } 380 | 381 | } 382 | protected _autoScrollToPage() { 383 | const bounceBackStarted = this._startBounceBackIfNeeded(); 384 | if (bounceBackStarted) { 385 | const bounceBackAmount = this._getHowMuchOutOfBoundary() 386 | this._clampDelta(bounceBackAmount) 387 | if (bounceBackAmount.x > 0 || bounceBackAmount.y < 0) { 388 | if (this.layout.horizontal) { 389 | if (this.layout.horizontalAxisDirection == SuperLayout.HorizontalAxisDirection.LEFT_TO_RIGHT) { 390 | this.layout["_currPageIndex"] = this.layout.itemTotal === 0 ? 0 : this.layout.itemTotal - 1 391 | } else { 392 | this.layout["_currPageIndex"] = 0 393 | } 394 | } else { 395 | if (this.layout.verticalAxisDirection == SuperLayout.VerticalAxisDirection.TOP_TO_BOTTOM) { 396 | this.layout["_currPageIndex"] = this.layout.itemTotal === 0 ? 0 : this.layout.itemTotal - 1 397 | } else { 398 | this.layout["_currPageIndex"] = 0 399 | } 400 | } 401 | } 402 | if (bounceBackAmount.x < 0 || bounceBackAmount.y > 0) { 403 | if (this.layout.horizontal) { 404 | if (this.layout.horizontalAxisDirection == SuperLayout.HorizontalAxisDirection.LEFT_TO_RIGHT) { 405 | this.layout["_currPageIndex"] = 0 406 | } else { 407 | this.layout["_currPageIndex"] = this.layout.itemTotal === 0 ? 0 : this.layout.itemTotal - 1 408 | } 409 | } else { 410 | if (this.layout.verticalAxisDirection == SuperLayout.VerticalAxisDirection.TOP_TO_BOTTOM) { 411 | this.layout["_currPageIndex"] = 0 412 | } else { 413 | this.layout["_currPageIndex"] = this.layout.itemTotal === 0 ? 0 : this.layout.itemTotal - 1 414 | } 415 | } 416 | } 417 | if (this.layout.indicator) { 418 | this.layout.indicator._changedState() 419 | } 420 | } else { 421 | const moveOffset = new Vec2() 422 | Vec2.subtract(moveOffset, this._touchBeganPosition, this._touchEndPosition) 423 | const index = this.layout["_currPageIndex"] 424 | var nextIndex = index + this.getDragDirection(moveOffset) 425 | var timeInSecond = this.layout.pageTurningSpeed * Math.abs(index - nextIndex) 426 | if (this.layout.footerLoop) { 427 | if (nextIndex >= this.layout.itemTotal) { 428 | nextIndex = 0 429 | } 430 | } 431 | if (this.layout.headerLoop) { 432 | if (nextIndex < 0) { 433 | nextIndex = this.layout.itemTotal - 1 434 | } 435 | } 436 | const count = this.layout.itemTotal 437 | if (nextIndex < count) { 438 | if (this.isScrollable(moveOffset, index, nextIndex)) { 439 | this.scrollToPage(nextIndex, timeInSecond) 440 | return; 441 | } else { 442 | const touchMoveVelocity = this._calculateTouchMoveVelocity() 443 | if (this.isQuicklyScrollable(touchMoveVelocity)) { 444 | this.scrollToPage(nextIndex, timeInSecond) 445 | return; 446 | } 447 | } 448 | } 449 | 450 | this.scrollToPage(index, timeInSecond) 451 | 452 | } 453 | } 454 | savePageIndex(idx: number) { 455 | if (idx < 0 || idx >= this.layout.itemTotal) { 456 | return false 457 | } 458 | this.layout["_currPageIndex"] = idx 459 | if (this.layout.indicator) { 460 | this.layout.indicator._changedState() 461 | } 462 | return true 463 | } 464 | protected scrollToPage(idx: number, timeInSecond = 0.3) { 465 | if (idx < 0 || idx >= this.layout.itemTotal) { 466 | return 467 | } 468 | if (this.savePageIndex(idx)) { 469 | this.layout.scrollToIndex(idx, timeInSecond) 470 | } 471 | } 472 | // 快速滑动 473 | protected isQuicklyScrollable(touchMoveVelocity: Vec3) { 474 | if (this.horizontal) { 475 | if (Math.abs(touchMoveVelocity.x) > this.layout.autoPageTurningThreshold) { 476 | return true; 477 | } 478 | } else if (this.vertical) { 479 | if (Math.abs(touchMoveVelocity.y) > this.layout.autoPageTurningThreshold) { 480 | return true; 481 | } 482 | } 483 | return false; 484 | } 485 | protected getDragDirection(moveOffset: Vec2) { 486 | if (this.horizontal) { 487 | if (moveOffset.x === 0) { 488 | return 0; 489 | } 490 | if (this.layout.horizontalAxisDirection == SuperLayout.HorizontalAxisDirection.LEFT_TO_RIGHT) { 491 | return (moveOffset.x > 0 ? this.layout.groupItemTotal : -this.layout.groupItemTotal); 492 | } else { 493 | return (moveOffset.x < 0 ? this.layout.groupItemTotal : -this.layout.groupItemTotal); 494 | } 495 | } else { 496 | // 由于滚动 Y 轴的原点在在右上角所以应该是小于 0 497 | if (moveOffset.y === 0) { 498 | return 0; 499 | } 500 | if (this.layout.verticalAxisDirection == SuperLayout.VerticalAxisDirection.TOP_TO_BOTTOM) { 501 | return (moveOffset.y < 0 ? this.layout.groupItemTotal : -this.layout.groupItemTotal); 502 | } else { 503 | return (moveOffset.y > 0 ? this.layout.groupItemTotal : -this.layout.groupItemTotal); 504 | } 505 | } 506 | } 507 | // 是否超过自动滚动临界值 508 | protected isScrollable(offset: Vec2, index: number, nextIndex: number) { 509 | const viewTrans = this.view 510 | if (!viewTrans) { 511 | return false 512 | } 513 | if (this.horizontal) { 514 | return Math.abs(offset.x) >= viewTrans.width * this.layout.scrollThreshold 515 | } else if (this.vertical) { 516 | return Math.abs(offset.y) >= viewTrans.height * this.layout.scrollThreshold 517 | } 518 | return false; 519 | } 520 | protected transmitEvent(event: EventTouch, eventType: string) { 521 | var e = new EventTouch(event.getTouches(), event.bubbles) 522 | e.type = eventType 523 | e.touch = event.touch 524 | let target: any = event.target! 525 | target.parent.dispatchEvent(e) 526 | } 527 | } 528 | -------------------------------------------------------------------------------- /assets/prefabs/horizontal.prefab: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "__type__": "cc.Prefab", 4 | "_name": "", 5 | "_objFlags": 0, 6 | "_native": "", 7 | "data": { 8 | "__id__": 1 9 | }, 10 | "optimizationPolicy": 0, 11 | "asyncLoadAssets": false 12 | }, 13 | { 14 | "__type__": "cc.Node", 15 | "_name": "horizontal", 16 | "_objFlags": 0, 17 | "_parent": null, 18 | "_children": [ 19 | { 20 | "__id__": 2 21 | }, 22 | { 23 | "__id__": 8 24 | }, 25 | { 26 | "__id__": 25 27 | } 28 | ], 29 | "_active": true, 30 | "_components": [ 31 | { 32 | "__id__": 54 33 | }, 34 | { 35 | "__id__": 56 36 | }, 37 | { 38 | "__id__": 58 39 | } 40 | ], 41 | "_prefab": { 42 | "__id__": 60 43 | }, 44 | "_lpos": { 45 | "__type__": "cc.Vec3", 46 | "x": 0, 47 | "y": 0, 48 | "z": 0 49 | }, 50 | "_lrot": { 51 | "__type__": "cc.Quat", 52 | "x": 0, 53 | "y": 0, 54 | "z": 0, 55 | "w": 1 56 | }, 57 | "_lscale": { 58 | "__type__": "cc.Vec3", 59 | "x": 1, 60 | "y": 1, 61 | "z": 1 62 | }, 63 | "_layer": 33554432, 64 | "_euler": { 65 | "__type__": "cc.Vec3", 66 | "x": 0, 67 | "y": 0, 68 | "z": 0 69 | }, 70 | "_id": "" 71 | }, 72 | { 73 | "__type__": "cc.Node", 74 | "_name": "Label", 75 | "_objFlags": 0, 76 | "_parent": { 77 | "__id__": 1 78 | }, 79 | "_children": [], 80 | "_active": true, 81 | "_components": [ 82 | { 83 | "__id__": 3 84 | }, 85 | { 86 | "__id__": 5 87 | } 88 | ], 89 | "_prefab": { 90 | "__id__": 7 91 | }, 92 | "_lpos": { 93 | "__type__": "cc.Vec3", 94 | "x": 0, 95 | "y": 0, 96 | "z": 0 97 | }, 98 | "_lrot": { 99 | "__type__": "cc.Quat", 100 | "x": 0, 101 | "y": 0, 102 | "z": 0, 103 | "w": 1 104 | }, 105 | "_lscale": { 106 | "__type__": "cc.Vec3", 107 | "x": 0.5, 108 | "y": 0.5, 109 | "z": 1 110 | }, 111 | "_layer": 33554432, 112 | "_euler": { 113 | "__type__": "cc.Vec3", 114 | "x": 0, 115 | "y": 0, 116 | "z": 0 117 | }, 118 | "_id": "" 119 | }, 120 | { 121 | "__type__": "cc.UITransform", 122 | "_name": "", 123 | "_objFlags": 0, 124 | "node": { 125 | "__id__": 2 126 | }, 127 | "_enabled": true, 128 | "__prefab": { 129 | "__id__": 4 130 | }, 131 | "_contentSize": { 132 | "__type__": "cc.Size", 133 | "width": 44.49, 134 | "height": 100.8 135 | }, 136 | "_anchorPoint": { 137 | "__type__": "cc.Vec2", 138 | "x": 0.5, 139 | "y": 0.5 140 | }, 141 | "_id": "" 142 | }, 143 | { 144 | "__type__": "cc.CompPrefabInfo", 145 | "fileId": "c68UOAlNhN171Umca6yVvF" 146 | }, 147 | { 148 | "__type__": "cc.Label", 149 | "_name": "", 150 | "_objFlags": 0, 151 | "node": { 152 | "__id__": 2 153 | }, 154 | "_enabled": true, 155 | "__prefab": { 156 | "__id__": 6 157 | }, 158 | "_visFlags": 0, 159 | "_customMaterial": null, 160 | "_srcBlendFactor": 2, 161 | "_dstBlendFactor": 4, 162 | "_color": { 163 | "__type__": "cc.Color", 164 | "r": 255, 165 | "g": 255, 166 | "b": 255, 167 | "a": 255 168 | }, 169 | "_string": "1", 170 | "_horizontalAlign": 1, 171 | "_verticalAlign": 1, 172 | "_actualFontSize": 80, 173 | "_fontSize": 80, 174 | "_fontFamily": "Arial", 175 | "_lineHeight": 80, 176 | "_overflow": 0, 177 | "_enableWrapText": true, 178 | "_font": null, 179 | "_isSystemFontUsed": true, 180 | "_isItalic": false, 181 | "_isBold": false, 182 | "_isUnderline": false, 183 | "_underlineHeight": 2, 184 | "_cacheMode": 0, 185 | "_id": "" 186 | }, 187 | { 188 | "__type__": "cc.CompPrefabInfo", 189 | "fileId": "2frm37uaJHQr0AEEaYyM82" 190 | }, 191 | { 192 | "__type__": "cc.PrefabInfo", 193 | "root": { 194 | "__id__": 1 195 | }, 196 | "asset": { 197 | "__id__": 0 198 | }, 199 | "fileId": "07kE/SDnBL35seppsSi/SU" 200 | }, 201 | { 202 | "__type__": "cc.Node", 203 | "_name": "Button", 204 | "_objFlags": 0, 205 | "_parent": { 206 | "__id__": 1 207 | }, 208 | "_children": [ 209 | { 210 | "__id__": 9 211 | } 212 | ], 213 | "_active": true, 214 | "_components": [ 215 | { 216 | "__id__": 15 217 | }, 218 | { 219 | "__id__": 17 220 | }, 221 | { 222 | "__id__": 19 223 | }, 224 | { 225 | "__id__": 22 226 | } 227 | ], 228 | "_prefab": { 229 | "__id__": 24 230 | }, 231 | "_lpos": { 232 | "__type__": "cc.Vec3", 233 | "x": 82.6685, 234 | "y": 84.699, 235 | "z": 0 236 | }, 237 | "_lrot": { 238 | "__type__": "cc.Quat", 239 | "x": 0, 240 | "y": 0, 241 | "z": 0, 242 | "w": 1 243 | }, 244 | "_lscale": { 245 | "__type__": "cc.Vec3", 246 | "x": 1, 247 | "y": 1, 248 | "z": 1 249 | }, 250 | "_layer": 33554432, 251 | "_euler": { 252 | "__type__": "cc.Vec3", 253 | "x": 0, 254 | "y": 0, 255 | "z": 0 256 | }, 257 | "_id": "" 258 | }, 259 | { 260 | "__type__": "cc.Node", 261 | "_name": "Label", 262 | "_objFlags": 512, 263 | "_parent": { 264 | "__id__": 8 265 | }, 266 | "_children": [], 267 | "_active": true, 268 | "_components": [ 269 | { 270 | "__id__": 10 271 | }, 272 | { 273 | "__id__": 12 274 | } 275 | ], 276 | "_prefab": { 277 | "__id__": 14 278 | }, 279 | "_lpos": { 280 | "__type__": "cc.Vec3", 281 | "x": 0, 282 | "y": 0, 283 | "z": 0 284 | }, 285 | "_lrot": { 286 | "__type__": "cc.Quat", 287 | "x": 0, 288 | "y": 0, 289 | "z": 0, 290 | "w": 1 291 | }, 292 | "_lscale": { 293 | "__type__": "cc.Vec3", 294 | "x": 1, 295 | "y": 1, 296 | "z": 1 297 | }, 298 | "_layer": 33554432, 299 | "_euler": { 300 | "__type__": "cc.Vec3", 301 | "x": 0, 302 | "y": 0, 303 | "z": 0 304 | }, 305 | "_id": "" 306 | }, 307 | { 308 | "__type__": "cc.UITransform", 309 | "_name": "", 310 | "_objFlags": 0, 311 | "node": { 312 | "__id__": 9 313 | }, 314 | "_enabled": true, 315 | "__prefab": { 316 | "__id__": 11 317 | }, 318 | "_contentSize": { 319 | "__type__": "cc.Size", 320 | "width": 100, 321 | "height": 40 322 | }, 323 | "_anchorPoint": { 324 | "__type__": "cc.Vec2", 325 | "x": 0.5, 326 | "y": 0.5 327 | }, 328 | "_id": "" 329 | }, 330 | { 331 | "__type__": "cc.CompPrefabInfo", 332 | "fileId": "07QMd0h1dLcYd/vjigaip6" 333 | }, 334 | { 335 | "__type__": "cc.Label", 336 | "_name": "", 337 | "_objFlags": 0, 338 | "node": { 339 | "__id__": 9 340 | }, 341 | "_enabled": true, 342 | "__prefab": { 343 | "__id__": 13 344 | }, 345 | "_visFlags": 0, 346 | "_customMaterial": null, 347 | "_srcBlendFactor": 2, 348 | "_dstBlendFactor": 4, 349 | "_color": { 350 | "__type__": "cc.Color", 351 | "r": 255, 352 | "g": 255, 353 | "b": 255, 354 | "a": 255 355 | }, 356 | "_string": "X", 357 | "_horizontalAlign": 1, 358 | "_verticalAlign": 1, 359 | "_actualFontSize": 20, 360 | "_fontSize": 20, 361 | "_fontFamily": "Arial", 362 | "_lineHeight": 40, 363 | "_overflow": 1, 364 | "_enableWrapText": false, 365 | "_font": null, 366 | "_isSystemFontUsed": true, 367 | "_isItalic": false, 368 | "_isBold": false, 369 | "_isUnderline": false, 370 | "_underlineHeight": 2, 371 | "_cacheMode": 0, 372 | "_id": "" 373 | }, 374 | { 375 | "__type__": "cc.CompPrefabInfo", 376 | "fileId": "ee3IZdy2dLIaAWpjI7P0FL" 377 | }, 378 | { 379 | "__type__": "cc.PrefabInfo", 380 | "root": { 381 | "__id__": 1 382 | }, 383 | "asset": { 384 | "__id__": 0 385 | }, 386 | "fileId": "a4pmmyqZtOeZ2QGSTNcNBc" 387 | }, 388 | { 389 | "__type__": "cc.UITransform", 390 | "_name": "", 391 | "_objFlags": 0, 392 | "node": { 393 | "__id__": 8 394 | }, 395 | "_enabled": true, 396 | "__prefab": { 397 | "__id__": 16 398 | }, 399 | "_contentSize": { 400 | "__type__": "cc.Size", 401 | "width": 34.663, 402 | "height": 30.602 403 | }, 404 | "_anchorPoint": { 405 | "__type__": "cc.Vec2", 406 | "x": 0.5, 407 | "y": 0.5 408 | }, 409 | "_id": "" 410 | }, 411 | { 412 | "__type__": "cc.CompPrefabInfo", 413 | "fileId": "98TYGMtwRBTYZZn4EZmhzJ" 414 | }, 415 | { 416 | "__type__": "cc.Sprite", 417 | "_name": "", 418 | "_objFlags": 0, 419 | "node": { 420 | "__id__": 8 421 | }, 422 | "_enabled": true, 423 | "__prefab": { 424 | "__id__": 18 425 | }, 426 | "_visFlags": 0, 427 | "_customMaterial": null, 428 | "_srcBlendFactor": 2, 429 | "_dstBlendFactor": 4, 430 | "_color": { 431 | "__type__": "cc.Color", 432 | "r": 196, 433 | "g": 66, 434 | "b": 70, 435 | "a": 255 436 | }, 437 | "_spriteFrame": { 438 | "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941", 439 | "__expectedType__": "cc.SpriteFrame" 440 | }, 441 | "_type": 1, 442 | "_fillType": 0, 443 | "_sizeMode": 0, 444 | "_fillCenter": { 445 | "__type__": "cc.Vec2", 446 | "x": 0, 447 | "y": 0 448 | }, 449 | "_fillStart": 0, 450 | "_fillRange": 0, 451 | "_isTrimmedMode": true, 452 | "_useGrayscale": false, 453 | "_atlas": null, 454 | "_id": "" 455 | }, 456 | { 457 | "__type__": "cc.CompPrefabInfo", 458 | "fileId": "77BcV1zfNHo4LI4KRqZupe" 459 | }, 460 | { 461 | "__type__": "cc.Button", 462 | "_name": "", 463 | "_objFlags": 0, 464 | "node": { 465 | "__id__": 8 466 | }, 467 | "_enabled": true, 468 | "__prefab": { 469 | "__id__": 20 470 | }, 471 | "clickEvents": [ 472 | { 473 | "__id__": 21 474 | } 475 | ], 476 | "_interactable": true, 477 | "_transition": 0, 478 | "_normalColor": { 479 | "__type__": "cc.Color", 480 | "r": 214, 481 | "g": 214, 482 | "b": 214, 483 | "a": 255 484 | }, 485 | "_hoverColor": { 486 | "__type__": "cc.Color", 487 | "r": 211, 488 | "g": 211, 489 | "b": 211, 490 | "a": 255 491 | }, 492 | "_pressedColor": { 493 | "__type__": "cc.Color", 494 | "r": 255, 495 | "g": 255, 496 | "b": 255, 497 | "a": 255 498 | }, 499 | "_disabledColor": { 500 | "__type__": "cc.Color", 501 | "r": 124, 502 | "g": 124, 503 | "b": 124, 504 | "a": 255 505 | }, 506 | "_normalSprite": { 507 | "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941", 508 | "__expectedType__": "cc.SpriteFrame" 509 | }, 510 | "_hoverSprite": { 511 | "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941", 512 | "__expectedType__": "cc.SpriteFrame" 513 | }, 514 | "_pressedSprite": { 515 | "__uuid__": "544e49d6-3f05-4fa8-9a9e-091f98fc2ce8@f9941", 516 | "__expectedType__": "cc.SpriteFrame" 517 | }, 518 | "_disabledSprite": { 519 | "__uuid__": "951249e0-9f16-456d-8b85-a6ca954da16b@f9941", 520 | "__expectedType__": "cc.SpriteFrame" 521 | }, 522 | "_duration": 0.1, 523 | "_zoomScale": 1.2, 524 | "_target": { 525 | "__id__": 8 526 | }, 527 | "_id": "" 528 | }, 529 | { 530 | "__type__": "cc.CompPrefabInfo", 531 | "fileId": "2fOwBXUwBNvaJ4NyyrOq4C" 532 | }, 533 | { 534 | "__type__": "cc.ClickEvent", 535 | "target": { 536 | "__id__": 1 537 | }, 538 | "component": "", 539 | "_componentId": "a3055FDRN9Nd4hD6P55dVQN", 540 | "handler": "onClick", 541 | "customEventData": "" 542 | }, 543 | { 544 | "__type__": "cc.Widget", 545 | "_name": "", 546 | "_objFlags": 0, 547 | "node": { 548 | "__id__": 8 549 | }, 550 | "_enabled": true, 551 | "__prefab": { 552 | "__id__": 23 553 | }, 554 | "_alignFlags": 33, 555 | "_target": null, 556 | "_left": 0, 557 | "_right": 0, 558 | "_top": 1.7763568394002505e-15, 559 | "_bottom": 0, 560 | "_horizontalCenter": 0, 561 | "_verticalCenter": 0, 562 | "_isAbsLeft": true, 563 | "_isAbsRight": true, 564 | "_isAbsTop": true, 565 | "_isAbsBottom": true, 566 | "_isAbsHorizontalCenter": true, 567 | "_isAbsVerticalCenter": true, 568 | "_originalWidth": 0, 569 | "_originalHeight": 0, 570 | "_alignMode": 1, 571 | "_lockFlags": 0, 572 | "_id": "" 573 | }, 574 | { 575 | "__type__": "cc.CompPrefabInfo", 576 | "fileId": "6053OAEulLWL9unHEFIxwP" 577 | }, 578 | { 579 | "__type__": "cc.PrefabInfo", 580 | "root": { 581 | "__id__": 1 582 | }, 583 | "asset": { 584 | "__id__": 0 585 | }, 586 | "fileId": "6dCPjWO41NRKGrj0i+fazs" 587 | }, 588 | { 589 | "__type__": "cc.Node", 590 | "_name": "EditBox", 591 | "_objFlags": 0, 592 | "_parent": { 593 | "__id__": 1 594 | }, 595 | "_children": [ 596 | { 597 | "__id__": 26 598 | }, 599 | { 600 | "__id__": 32 601 | }, 602 | { 603 | "__id__": 38 604 | } 605 | ], 606 | "_active": true, 607 | "_components": [ 608 | { 609 | "__id__": 44 610 | }, 611 | { 612 | "__id__": 46 613 | }, 614 | { 615 | "__id__": 48 616 | }, 617 | { 618 | "__id__": 51 619 | } 620 | ], 621 | "_prefab": { 622 | "__id__": 53 623 | }, 624 | "_lpos": { 625 | "__type__": "cc.Vec3", 626 | "x": 1.6629999999999967, 627 | "y": -72, 628 | "z": 0 629 | }, 630 | "_lrot": { 631 | "__type__": "cc.Quat", 632 | "x": 0, 633 | "y": 0, 634 | "z": 0, 635 | "w": 1 636 | }, 637 | "_lscale": { 638 | "__type__": "cc.Vec3", 639 | "x": 1, 640 | "y": 1, 641 | "z": 1 642 | }, 643 | "_layer": 33554432, 644 | "_euler": { 645 | "__type__": "cc.Vec3", 646 | "x": 0, 647 | "y": 0, 648 | "z": 0 649 | }, 650 | "_id": "" 651 | }, 652 | { 653 | "__type__": "cc.Node", 654 | "_name": "TEXT_LABEL", 655 | "_objFlags": 0, 656 | "_parent": { 657 | "__id__": 25 658 | }, 659 | "_children": [], 660 | "_active": false, 661 | "_components": [ 662 | { 663 | "__id__": 27 664 | }, 665 | { 666 | "__id__": 29 667 | } 668 | ], 669 | "_prefab": { 670 | "__id__": 31 671 | }, 672 | "_lpos": { 673 | "__type__": "cc.Vec3", 674 | "x": -32.5, 675 | "y": 20, 676 | "z": 0 677 | }, 678 | "_lrot": { 679 | "__type__": "cc.Quat", 680 | "x": 0, 681 | "y": 0, 682 | "z": 0, 683 | "w": 1 684 | }, 685 | "_lscale": { 686 | "__type__": "cc.Vec3", 687 | "x": 1, 688 | "y": 1, 689 | "z": 1 690 | }, 691 | "_layer": 33554432, 692 | "_euler": { 693 | "__type__": "cc.Vec3", 694 | "x": 0, 695 | "y": 0, 696 | "z": 0 697 | }, 698 | "_id": "" 699 | }, 700 | { 701 | "__type__": "cc.UITransform", 702 | "_name": "", 703 | "_objFlags": 0, 704 | "node": { 705 | "__id__": 26 706 | }, 707 | "_enabled": true, 708 | "__prefab": { 709 | "__id__": 28 710 | }, 711 | "_contentSize": { 712 | "__type__": "cc.Size", 713 | "width": 67, 714 | "height": 40 715 | }, 716 | "_anchorPoint": { 717 | "__type__": "cc.Vec2", 718 | "x": 0, 719 | "y": 1 720 | }, 721 | "_id": "" 722 | }, 723 | { 724 | "__type__": "cc.CompPrefabInfo", 725 | "fileId": "779kAXGTtMZKXfYlOg0Tfd" 726 | }, 727 | { 728 | "__type__": "cc.Label", 729 | "_name": "", 730 | "_objFlags": 0, 731 | "node": { 732 | "__id__": 26 733 | }, 734 | "_enabled": true, 735 | "__prefab": { 736 | "__id__": 30 737 | }, 738 | "_visFlags": 0, 739 | "_customMaterial": null, 740 | "_srcBlendFactor": 2, 741 | "_dstBlendFactor": 4, 742 | "_color": { 743 | "__type__": "cc.Color", 744 | "r": 255, 745 | "g": 255, 746 | "b": 255, 747 | "a": 255 748 | }, 749 | "_string": "", 750 | "_horizontalAlign": 0, 751 | "_verticalAlign": 1, 752 | "_actualFontSize": 40, 753 | "_fontSize": 20, 754 | "_fontFamily": "Arial", 755 | "_lineHeight": 40, 756 | "_overflow": 1, 757 | "_enableWrapText": false, 758 | "_font": null, 759 | "_isSystemFontUsed": true, 760 | "_isItalic": false, 761 | "_isBold": false, 762 | "_isUnderline": false, 763 | "_underlineHeight": 2, 764 | "_cacheMode": 0, 765 | "_id": "" 766 | }, 767 | { 768 | "__type__": "cc.CompPrefabInfo", 769 | "fileId": "ddIY+NJvlDTIQAg7PLVrGo" 770 | }, 771 | { 772 | "__type__": "cc.PrefabInfo", 773 | "root": { 774 | "__id__": 1 775 | }, 776 | "asset": { 777 | "__id__": 0 778 | }, 779 | "fileId": "dabJjkBE5PJIvEA+XQl2e+" 780 | }, 781 | { 782 | "__type__": "cc.Node", 783 | "_name": "PLACEHOLDER_LABEL", 784 | "_objFlags": 0, 785 | "_parent": { 786 | "__id__": 25 787 | }, 788 | "_children": [], 789 | "_active": true, 790 | "_components": [ 791 | { 792 | "__id__": 33 793 | }, 794 | { 795 | "__id__": 35 796 | } 797 | ], 798 | "_prefab": { 799 | "__id__": 37 800 | }, 801 | "_lpos": { 802 | "__type__": "cc.Vec3", 803 | "x": -32.5, 804 | "y": 20, 805 | "z": 0 806 | }, 807 | "_lrot": { 808 | "__type__": "cc.Quat", 809 | "x": 0, 810 | "y": 0, 811 | "z": 0, 812 | "w": 1 813 | }, 814 | "_lscale": { 815 | "__type__": "cc.Vec3", 816 | "x": 1, 817 | "y": 1, 818 | "z": 1 819 | }, 820 | "_layer": 33554432, 821 | "_euler": { 822 | "__type__": "cc.Vec3", 823 | "x": 0, 824 | "y": 0, 825 | "z": 0 826 | }, 827 | "_id": "" 828 | }, 829 | { 830 | "__type__": "cc.UITransform", 831 | "_name": "", 832 | "_objFlags": 0, 833 | "node": { 834 | "__id__": 32 835 | }, 836 | "_enabled": true, 837 | "__prefab": { 838 | "__id__": 34 839 | }, 840 | "_contentSize": { 841 | "__type__": "cc.Size", 842 | "width": 67, 843 | "height": 40 844 | }, 845 | "_anchorPoint": { 846 | "__type__": "cc.Vec2", 847 | "x": 0, 848 | "y": 1 849 | }, 850 | "_id": "" 851 | }, 852 | { 853 | "__type__": "cc.CompPrefabInfo", 854 | "fileId": "d07wQj4whCUqYGJH1lEpVp" 855 | }, 856 | { 857 | "__type__": "cc.Label", 858 | "_name": "", 859 | "_objFlags": 0, 860 | "node": { 861 | "__id__": 32 862 | }, 863 | "_enabled": true, 864 | "__prefab": { 865 | "__id__": 36 866 | }, 867 | "_visFlags": 0, 868 | "_customMaterial": null, 869 | "_srcBlendFactor": 2, 870 | "_dstBlendFactor": 4, 871 | "_color": { 872 | "__type__": "cc.Color", 873 | "r": 187, 874 | "g": 187, 875 | "b": 187, 876 | "a": 255 877 | }, 878 | "_string": "width", 879 | "_horizontalAlign": 0, 880 | "_verticalAlign": 1, 881 | "_actualFontSize": 20, 882 | "_fontSize": 20, 883 | "_fontFamily": "Arial", 884 | "_lineHeight": 40, 885 | "_overflow": 1, 886 | "_enableWrapText": false, 887 | "_font": null, 888 | "_isSystemFontUsed": true, 889 | "_isItalic": false, 890 | "_isBold": false, 891 | "_isUnderline": false, 892 | "_underlineHeight": 2, 893 | "_cacheMode": 0, 894 | "_id": "" 895 | }, 896 | { 897 | "__type__": "cc.CompPrefabInfo", 898 | "fileId": "8fhi7qRLFJbK0abIJuXmCW" 899 | }, 900 | { 901 | "__type__": "cc.PrefabInfo", 902 | "root": { 903 | "__id__": 1 904 | }, 905 | "asset": { 906 | "__id__": 0 907 | }, 908 | "fileId": "64ygsKD0BEIaDZyxXEkoqs" 909 | }, 910 | { 911 | "__type__": "cc.Node", 912 | "_name": "Label", 913 | "_objFlags": 0, 914 | "_parent": { 915 | "__id__": 25 916 | }, 917 | "_children": [], 918 | "_active": true, 919 | "_components": [ 920 | { 921 | "__id__": 39 922 | }, 923 | { 924 | "__id__": 41 925 | } 926 | ], 927 | "_prefab": { 928 | "__id__": 43 929 | }, 930 | "_lpos": { 931 | "__type__": "cc.Vec3", 932 | "x": -64, 933 | "y": 0, 934 | "z": 0 935 | }, 936 | "_lrot": { 937 | "__type__": "cc.Quat", 938 | "x": 0, 939 | "y": 0, 940 | "z": 0, 941 | "w": 1 942 | }, 943 | "_lscale": { 944 | "__type__": "cc.Vec3", 945 | "x": 1, 946 | "y": 1, 947 | "z": 1 948 | }, 949 | "_layer": 33554432, 950 | "_euler": { 951 | "__type__": "cc.Vec3", 952 | "x": 0, 953 | "y": 0, 954 | "z": 0 955 | }, 956 | "_id": "" 957 | }, 958 | { 959 | "__type__": "cc.UITransform", 960 | "_name": "", 961 | "_objFlags": 0, 962 | "node": { 963 | "__id__": 38 964 | }, 965 | "_enabled": true, 966 | "__prefab": { 967 | "__id__": 40 968 | }, 969 | "_contentSize": { 970 | "__type__": "cc.Size", 971 | "width": 45.56, 972 | "height": 50.4 973 | }, 974 | "_anchorPoint": { 975 | "__type__": "cc.Vec2", 976 | "x": 0.5, 977 | "y": 0.5 978 | }, 979 | "_id": "" 980 | }, 981 | { 982 | "__type__": "cc.CompPrefabInfo", 983 | "fileId": "c68UOAlNhN171Umca6yVvF" 984 | }, 985 | { 986 | "__type__": "cc.Label", 987 | "_name": "", 988 | "_objFlags": 0, 989 | "node": { 990 | "__id__": 38 991 | }, 992 | "_enabled": true, 993 | "__prefab": { 994 | "__id__": 42 995 | }, 996 | "_visFlags": 0, 997 | "_customMaterial": null, 998 | "_srcBlendFactor": 2, 999 | "_dstBlendFactor": 4, 1000 | "_color": { 1001 | "__type__": "cc.Color", 1002 | "r": 255, 1003 | "g": 255, 1004 | "b": 255, 1005 | "a": 255 1006 | }, 1007 | "_string": "宽度:", 1008 | "_horizontalAlign": 1, 1009 | "_verticalAlign": 1, 1010 | "_actualFontSize": 20, 1011 | "_fontSize": 20, 1012 | "_fontFamily": "Arial", 1013 | "_lineHeight": 40, 1014 | "_overflow": 0, 1015 | "_enableWrapText": true, 1016 | "_font": null, 1017 | "_isSystemFontUsed": true, 1018 | "_isItalic": false, 1019 | "_isBold": false, 1020 | "_isUnderline": false, 1021 | "_underlineHeight": 2, 1022 | "_cacheMode": 0, 1023 | "_id": "" 1024 | }, 1025 | { 1026 | "__type__": "cc.CompPrefabInfo", 1027 | "fileId": "2frm37uaJHQr0AEEaYyM82" 1028 | }, 1029 | { 1030 | "__type__": "cc.PrefabInfo", 1031 | "root": { 1032 | "__id__": 1 1033 | }, 1034 | "asset": { 1035 | "__id__": 0 1036 | }, 1037 | "fileId": "2bo3bcN65P7anPPAbGgl7p" 1038 | }, 1039 | { 1040 | "__type__": "cc.UITransform", 1041 | "_name": "", 1042 | "_objFlags": 0, 1043 | "node": { 1044 | "__id__": 25 1045 | }, 1046 | "_enabled": true, 1047 | "__prefab": { 1048 | "__id__": 45 1049 | }, 1050 | "_contentSize": { 1051 | "__type__": "cc.Size", 1052 | "width": 69, 1053 | "height": 40 1054 | }, 1055 | "_anchorPoint": { 1056 | "__type__": "cc.Vec2", 1057 | "x": 0.5, 1058 | "y": 0.5 1059 | }, 1060 | "_id": "" 1061 | }, 1062 | { 1063 | "__type__": "cc.CompPrefabInfo", 1064 | "fileId": "1fhJOVuOVAGYSYZoiE25Uz" 1065 | }, 1066 | { 1067 | "__type__": "cc.Sprite", 1068 | "_name": "", 1069 | "_objFlags": 0, 1070 | "node": { 1071 | "__id__": 25 1072 | }, 1073 | "_enabled": true, 1074 | "__prefab": { 1075 | "__id__": 47 1076 | }, 1077 | "_visFlags": 0, 1078 | "_customMaterial": null, 1079 | "_srcBlendFactor": 2, 1080 | "_dstBlendFactor": 4, 1081 | "_color": { 1082 | "__type__": "cc.Color", 1083 | "r": 155, 1084 | "g": 212, 1085 | "b": 148, 1086 | "a": 255 1087 | }, 1088 | "_spriteFrame": { 1089 | "__uuid__": "bd1bcaba-bd7d-4a71-b143-997c882383e4@f9941", 1090 | "__expectedType__": "cc.SpriteFrame" 1091 | }, 1092 | "_type": 1, 1093 | "_fillType": 0, 1094 | "_sizeMode": 0, 1095 | "_fillCenter": { 1096 | "__type__": "cc.Vec2", 1097 | "x": 0, 1098 | "y": 0 1099 | }, 1100 | "_fillStart": 0, 1101 | "_fillRange": 0, 1102 | "_isTrimmedMode": true, 1103 | "_useGrayscale": false, 1104 | "_atlas": null, 1105 | "_id": "" 1106 | }, 1107 | { 1108 | "__type__": "cc.CompPrefabInfo", 1109 | "fileId": "43qH95z3VGeYelCElKd6FW" 1110 | }, 1111 | { 1112 | "__type__": "cc.EditBox", 1113 | "_name": "", 1114 | "_objFlags": 0, 1115 | "node": { 1116 | "__id__": 25 1117 | }, 1118 | "_enabled": true, 1119 | "__prefab": { 1120 | "__id__": 49 1121 | }, 1122 | "editingDidBegan": [], 1123 | "textChanged": [], 1124 | "editingDidEnded": [ 1125 | { 1126 | "__id__": 50 1127 | } 1128 | ], 1129 | "editingReturn": [], 1130 | "_textLabel": { 1131 | "__id__": 29 1132 | }, 1133 | "_placeholderLabel": { 1134 | "__id__": 35 1135 | }, 1136 | "_returnType": 0, 1137 | "_string": "", 1138 | "_tabIndex": 0, 1139 | "_backgroundImage": { 1140 | "__uuid__": "bd1bcaba-bd7d-4a71-b143-997c882383e4@f9941", 1141 | "__expectedType__": "cc.SpriteFrame" 1142 | }, 1143 | "_inputFlag": 5, 1144 | "_inputMode": 6, 1145 | "_maxLength": 8, 1146 | "_id": "" 1147 | }, 1148 | { 1149 | "__type__": "cc.CompPrefabInfo", 1150 | "fileId": "1bCHrwPGZOPrbmPh93kwpe" 1151 | }, 1152 | { 1153 | "__type__": "cc.ClickEvent", 1154 | "target": { 1155 | "__id__": 1 1156 | }, 1157 | "component": "", 1158 | "_componentId": "a3055FDRN9Nd4hD6P55dVQN", 1159 | "handler": "onInput", 1160 | "customEventData": "" 1161 | }, 1162 | { 1163 | "__type__": "cc.Widget", 1164 | "_name": "", 1165 | "_objFlags": 0, 1166 | "node": { 1167 | "__id__": 25 1168 | }, 1169 | "_enabled": true, 1170 | "__prefab": { 1171 | "__id__": 52 1172 | }, 1173 | "_alignFlags": 12, 1174 | "_target": null, 1175 | "_left": 67.163, 1176 | "_right": 0, 1177 | "_top": 252, 1178 | "_bottom": 8, 1179 | "_horizontalCenter": 0, 1180 | "_verticalCenter": 0, 1181 | "_isAbsLeft": true, 1182 | "_isAbsRight": true, 1183 | "_isAbsTop": true, 1184 | "_isAbsBottom": true, 1185 | "_isAbsHorizontalCenter": true, 1186 | "_isAbsVerticalCenter": true, 1187 | "_originalWidth": 69, 1188 | "_originalHeight": 40, 1189 | "_alignMode": 1, 1190 | "_lockFlags": 0, 1191 | "_id": "" 1192 | }, 1193 | { 1194 | "__type__": "cc.CompPrefabInfo", 1195 | "fileId": "1anBR8XftMY7O/0+jxD2jp" 1196 | }, 1197 | { 1198 | "__type__": "cc.PrefabInfo", 1199 | "root": { 1200 | "__id__": 1 1201 | }, 1202 | "asset": { 1203 | "__id__": 0 1204 | }, 1205 | "fileId": "f4VXqVWkdIMJ0bUItyTR8W" 1206 | }, 1207 | { 1208 | "__type__": "cc.UITransform", 1209 | "_name": "", 1210 | "_objFlags": 0, 1211 | "node": { 1212 | "__id__": 1 1213 | }, 1214 | "_enabled": true, 1215 | "__prefab": { 1216 | "__id__": 55 1217 | }, 1218 | "_contentSize": { 1219 | "__type__": "cc.Size", 1220 | "width": 200, 1221 | "height": 200 1222 | }, 1223 | "_anchorPoint": { 1224 | "__type__": "cc.Vec2", 1225 | "x": 0.5, 1226 | "y": 0.5 1227 | }, 1228 | "_id": "" 1229 | }, 1230 | { 1231 | "__type__": "cc.CompPrefabInfo", 1232 | "fileId": "55pCbtzR5GbojKMArZkfim" 1233 | }, 1234 | { 1235 | "__type__": "cc.Sprite", 1236 | "_name": "", 1237 | "_objFlags": 0, 1238 | "node": { 1239 | "__id__": 1 1240 | }, 1241 | "_enabled": true, 1242 | "__prefab": { 1243 | "__id__": 57 1244 | }, 1245 | "_visFlags": 0, 1246 | "_customMaterial": null, 1247 | "_srcBlendFactor": 2, 1248 | "_dstBlendFactor": 4, 1249 | "_color": { 1250 | "__type__": "cc.Color", 1251 | "r": 78, 1252 | "g": 156, 1253 | "b": 87, 1254 | "a": 255 1255 | }, 1256 | "_spriteFrame": { 1257 | "__uuid__": "7d8f9b89-4fd1-4c9f-a3ab-38ec7cded7ca@f9941", 1258 | "__expectedType__": "cc.SpriteFrame" 1259 | }, 1260 | "_type": 0, 1261 | "_fillType": 0, 1262 | "_sizeMode": 0, 1263 | "_fillCenter": { 1264 | "__type__": "cc.Vec2", 1265 | "x": 0, 1266 | "y": 0 1267 | }, 1268 | "_fillStart": 0, 1269 | "_fillRange": 0, 1270 | "_isTrimmedMode": true, 1271 | "_useGrayscale": false, 1272 | "_atlas": null, 1273 | "_id": "" 1274 | }, 1275 | { 1276 | "__type__": "cc.CompPrefabInfo", 1277 | "fileId": "20UGQn4U9GUoln0NJQTkbG" 1278 | }, 1279 | { 1280 | "__type__": "a3055FDRN9Nd4hD6P55dVQN", 1281 | "_name": "", 1282 | "_objFlags": 0, 1283 | "node": { 1284 | "__id__": 1 1285 | }, 1286 | "_enabled": true, 1287 | "__prefab": { 1288 | "__id__": 59 1289 | }, 1290 | "label": { 1291 | "__id__": 5 1292 | }, 1293 | "input": { 1294 | "__id__": 48 1295 | }, 1296 | "_id": "" 1297 | }, 1298 | { 1299 | "__type__": "cc.CompPrefabInfo", 1300 | "fileId": "9f/MgSmcpHG6Qnq3kieqP4" 1301 | }, 1302 | { 1303 | "__type__": "cc.PrefabInfo", 1304 | "root": { 1305 | "__id__": 1 1306 | }, 1307 | "asset": { 1308 | "__id__": 0 1309 | }, 1310 | "fileId": "89ethdRvdHL6gxOx3A4hp+" 1311 | } 1312 | ] -------------------------------------------------------------------------------- /assets/prefabs/vertical.prefab: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "__type__": "cc.Prefab", 4 | "_name": "", 5 | "_objFlags": 0, 6 | "_native": "", 7 | "data": { 8 | "__id__": 1 9 | }, 10 | "optimizationPolicy": 0, 11 | "asyncLoadAssets": false 12 | }, 13 | { 14 | "__type__": "cc.Node", 15 | "_name": "vertical", 16 | "_objFlags": 0, 17 | "_parent": null, 18 | "_children": [ 19 | { 20 | "__id__": 2 21 | }, 22 | { 23 | "__id__": 8 24 | }, 25 | { 26 | "__id__": 25 27 | } 28 | ], 29 | "_active": true, 30 | "_components": [ 31 | { 32 | "__id__": 54 33 | }, 34 | { 35 | "__id__": 56 36 | }, 37 | { 38 | "__id__": 58 39 | } 40 | ], 41 | "_prefab": { 42 | "__id__": 60 43 | }, 44 | "_lpos": { 45 | "__type__": "cc.Vec3", 46 | "x": 0, 47 | "y": 0, 48 | "z": 0 49 | }, 50 | "_lrot": { 51 | "__type__": "cc.Quat", 52 | "x": 0, 53 | "y": 0, 54 | "z": 0, 55 | "w": 1 56 | }, 57 | "_lscale": { 58 | "__type__": "cc.Vec3", 59 | "x": 1, 60 | "y": 1, 61 | "z": 1 62 | }, 63 | "_layer": 33554432, 64 | "_euler": { 65 | "__type__": "cc.Vec3", 66 | "x": 0, 67 | "y": 0, 68 | "z": 0 69 | }, 70 | "_id": "" 71 | }, 72 | { 73 | "__type__": "cc.Node", 74 | "_name": "Label", 75 | "_objFlags": 0, 76 | "_parent": { 77 | "__id__": 1 78 | }, 79 | "_children": [], 80 | "_active": true, 81 | "_components": [ 82 | { 83 | "__id__": 3 84 | }, 85 | { 86 | "__id__": 5 87 | } 88 | ], 89 | "_prefab": { 90 | "__id__": 7 91 | }, 92 | "_lpos": { 93 | "__type__": "cc.Vec3", 94 | "x": 0, 95 | "y": 0, 96 | "z": 0 97 | }, 98 | "_lrot": { 99 | "__type__": "cc.Quat", 100 | "x": 0, 101 | "y": 0, 102 | "z": 0, 103 | "w": 1 104 | }, 105 | "_lscale": { 106 | "__type__": "cc.Vec3", 107 | "x": 0.5, 108 | "y": 0.5, 109 | "z": 1 110 | }, 111 | "_layer": 33554432, 112 | "_euler": { 113 | "__type__": "cc.Vec3", 114 | "x": 0, 115 | "y": 0, 116 | "z": 0 117 | }, 118 | "_id": "" 119 | }, 120 | { 121 | "__type__": "cc.UITransform", 122 | "_name": "", 123 | "_objFlags": 0, 124 | "node": { 125 | "__id__": 2 126 | }, 127 | "_enabled": true, 128 | "__prefab": { 129 | "__id__": 4 130 | }, 131 | "_contentSize": { 132 | "__type__": "cc.Size", 133 | "width": 44.49, 134 | "height": 100.8 135 | }, 136 | "_anchorPoint": { 137 | "__type__": "cc.Vec2", 138 | "x": 0.5, 139 | "y": 0.5 140 | }, 141 | "_id": "" 142 | }, 143 | { 144 | "__type__": "cc.CompPrefabInfo", 145 | "fileId": "c68UOAlNhN171Umca6yVvF" 146 | }, 147 | { 148 | "__type__": "cc.Label", 149 | "_name": "", 150 | "_objFlags": 0, 151 | "node": { 152 | "__id__": 2 153 | }, 154 | "_enabled": true, 155 | "__prefab": { 156 | "__id__": 6 157 | }, 158 | "_visFlags": 0, 159 | "_customMaterial": null, 160 | "_srcBlendFactor": 2, 161 | "_dstBlendFactor": 4, 162 | "_color": { 163 | "__type__": "cc.Color", 164 | "r": 255, 165 | "g": 255, 166 | "b": 255, 167 | "a": 255 168 | }, 169 | "_string": "1", 170 | "_horizontalAlign": 1, 171 | "_verticalAlign": 1, 172 | "_actualFontSize": 80, 173 | "_fontSize": 80, 174 | "_fontFamily": "Arial", 175 | "_lineHeight": 80, 176 | "_overflow": 0, 177 | "_enableWrapText": true, 178 | "_font": null, 179 | "_isSystemFontUsed": true, 180 | "_isItalic": false, 181 | "_isBold": false, 182 | "_isUnderline": false, 183 | "_underlineHeight": 2, 184 | "_cacheMode": 0, 185 | "_id": "" 186 | }, 187 | { 188 | "__type__": "cc.CompPrefabInfo", 189 | "fileId": "2frm37uaJHQr0AEEaYyM82" 190 | }, 191 | { 192 | "__type__": "cc.PrefabInfo", 193 | "root": { 194 | "__id__": 1 195 | }, 196 | "asset": { 197 | "__id__": 0 198 | }, 199 | "fileId": "07kE/SDnBL35seppsSi/SU" 200 | }, 201 | { 202 | "__type__": "cc.Node", 203 | "_name": "Button", 204 | "_objFlags": 0, 205 | "_parent": { 206 | "__id__": 1 207 | }, 208 | "_children": [ 209 | { 210 | "__id__": 9 211 | } 212 | ], 213 | "_active": true, 214 | "_components": [ 215 | { 216 | "__id__": 15 217 | }, 218 | { 219 | "__id__": 17 220 | }, 221 | { 222 | "__id__": 19 223 | }, 224 | { 225 | "__id__": 22 226 | } 227 | ], 228 | "_prefab": { 229 | "__id__": 24 230 | }, 231 | "_lpos": { 232 | "__type__": "cc.Vec3", 233 | "x": 132.6685, 234 | "y": 34.699, 235 | "z": 0 236 | }, 237 | "_lrot": { 238 | "__type__": "cc.Quat", 239 | "x": 0, 240 | "y": 0, 241 | "z": 0, 242 | "w": 1 243 | }, 244 | "_lscale": { 245 | "__type__": "cc.Vec3", 246 | "x": 1, 247 | "y": 1, 248 | "z": 1 249 | }, 250 | "_layer": 33554432, 251 | "_euler": { 252 | "__type__": "cc.Vec3", 253 | "x": 0, 254 | "y": 0, 255 | "z": 0 256 | }, 257 | "_id": "" 258 | }, 259 | { 260 | "__type__": "cc.Node", 261 | "_name": "Label", 262 | "_objFlags": 512, 263 | "_parent": { 264 | "__id__": 8 265 | }, 266 | "_children": [], 267 | "_active": true, 268 | "_components": [ 269 | { 270 | "__id__": 10 271 | }, 272 | { 273 | "__id__": 12 274 | } 275 | ], 276 | "_prefab": { 277 | "__id__": 14 278 | }, 279 | "_lpos": { 280 | "__type__": "cc.Vec3", 281 | "x": 0, 282 | "y": 0, 283 | "z": 0 284 | }, 285 | "_lrot": { 286 | "__type__": "cc.Quat", 287 | "x": 0, 288 | "y": 0, 289 | "z": 0, 290 | "w": 1 291 | }, 292 | "_lscale": { 293 | "__type__": "cc.Vec3", 294 | "x": 1, 295 | "y": 1, 296 | "z": 1 297 | }, 298 | "_layer": 33554432, 299 | "_euler": { 300 | "__type__": "cc.Vec3", 301 | "x": 0, 302 | "y": 0, 303 | "z": 0 304 | }, 305 | "_id": "" 306 | }, 307 | { 308 | "__type__": "cc.UITransform", 309 | "_name": "", 310 | "_objFlags": 0, 311 | "node": { 312 | "__id__": 9 313 | }, 314 | "_enabled": true, 315 | "__prefab": { 316 | "__id__": 11 317 | }, 318 | "_contentSize": { 319 | "__type__": "cc.Size", 320 | "width": 100, 321 | "height": 40 322 | }, 323 | "_anchorPoint": { 324 | "__type__": "cc.Vec2", 325 | "x": 0.5, 326 | "y": 0.5 327 | }, 328 | "_id": "" 329 | }, 330 | { 331 | "__type__": "cc.CompPrefabInfo", 332 | "fileId": "07QMd0h1dLcYd/vjigaip6" 333 | }, 334 | { 335 | "__type__": "cc.Label", 336 | "_name": "", 337 | "_objFlags": 0, 338 | "node": { 339 | "__id__": 9 340 | }, 341 | "_enabled": true, 342 | "__prefab": { 343 | "__id__": 13 344 | }, 345 | "_visFlags": 0, 346 | "_customMaterial": null, 347 | "_srcBlendFactor": 2, 348 | "_dstBlendFactor": 4, 349 | "_color": { 350 | "__type__": "cc.Color", 351 | "r": 255, 352 | "g": 255, 353 | "b": 255, 354 | "a": 255 355 | }, 356 | "_string": "X", 357 | "_horizontalAlign": 1, 358 | "_verticalAlign": 1, 359 | "_actualFontSize": 20, 360 | "_fontSize": 20, 361 | "_fontFamily": "Arial", 362 | "_lineHeight": 40, 363 | "_overflow": 1, 364 | "_enableWrapText": false, 365 | "_font": null, 366 | "_isSystemFontUsed": true, 367 | "_isItalic": false, 368 | "_isBold": false, 369 | "_isUnderline": false, 370 | "_underlineHeight": 2, 371 | "_cacheMode": 0, 372 | "_id": "" 373 | }, 374 | { 375 | "__type__": "cc.CompPrefabInfo", 376 | "fileId": "ee3IZdy2dLIaAWpjI7P0FL" 377 | }, 378 | { 379 | "__type__": "cc.PrefabInfo", 380 | "root": { 381 | "__id__": 1 382 | }, 383 | "asset": { 384 | "__id__": 0 385 | }, 386 | "fileId": "a4pmmyqZtOeZ2QGSTNcNBc" 387 | }, 388 | { 389 | "__type__": "cc.UITransform", 390 | "_name": "", 391 | "_objFlags": 0, 392 | "node": { 393 | "__id__": 8 394 | }, 395 | "_enabled": true, 396 | "__prefab": { 397 | "__id__": 16 398 | }, 399 | "_contentSize": { 400 | "__type__": "cc.Size", 401 | "width": 34.663, 402 | "height": 30.602 403 | }, 404 | "_anchorPoint": { 405 | "__type__": "cc.Vec2", 406 | "x": 0.5, 407 | "y": 0.5 408 | }, 409 | "_id": "" 410 | }, 411 | { 412 | "__type__": "cc.CompPrefabInfo", 413 | "fileId": "98TYGMtwRBTYZZn4EZmhzJ" 414 | }, 415 | { 416 | "__type__": "cc.Sprite", 417 | "_name": "", 418 | "_objFlags": 0, 419 | "node": { 420 | "__id__": 8 421 | }, 422 | "_enabled": true, 423 | "__prefab": { 424 | "__id__": 18 425 | }, 426 | "_visFlags": 0, 427 | "_customMaterial": null, 428 | "_srcBlendFactor": 2, 429 | "_dstBlendFactor": 4, 430 | "_color": { 431 | "__type__": "cc.Color", 432 | "r": 196, 433 | "g": 66, 434 | "b": 70, 435 | "a": 255 436 | }, 437 | "_spriteFrame": { 438 | "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941", 439 | "__expectedType__": "cc.SpriteFrame" 440 | }, 441 | "_type": 1, 442 | "_fillType": 0, 443 | "_sizeMode": 0, 444 | "_fillCenter": { 445 | "__type__": "cc.Vec2", 446 | "x": 0, 447 | "y": 0 448 | }, 449 | "_fillStart": 0, 450 | "_fillRange": 0, 451 | "_isTrimmedMode": true, 452 | "_useGrayscale": false, 453 | "_atlas": null, 454 | "_id": "" 455 | }, 456 | { 457 | "__type__": "cc.CompPrefabInfo", 458 | "fileId": "77BcV1zfNHo4LI4KRqZupe" 459 | }, 460 | { 461 | "__type__": "cc.Button", 462 | "_name": "", 463 | "_objFlags": 0, 464 | "node": { 465 | "__id__": 8 466 | }, 467 | "_enabled": true, 468 | "__prefab": { 469 | "__id__": 20 470 | }, 471 | "clickEvents": [ 472 | { 473 | "__id__": 21 474 | } 475 | ], 476 | "_interactable": true, 477 | "_transition": 0, 478 | "_normalColor": { 479 | "__type__": "cc.Color", 480 | "r": 214, 481 | "g": 214, 482 | "b": 214, 483 | "a": 255 484 | }, 485 | "_hoverColor": { 486 | "__type__": "cc.Color", 487 | "r": 211, 488 | "g": 211, 489 | "b": 211, 490 | "a": 255 491 | }, 492 | "_pressedColor": { 493 | "__type__": "cc.Color", 494 | "r": 255, 495 | "g": 255, 496 | "b": 255, 497 | "a": 255 498 | }, 499 | "_disabledColor": { 500 | "__type__": "cc.Color", 501 | "r": 124, 502 | "g": 124, 503 | "b": 124, 504 | "a": 255 505 | }, 506 | "_normalSprite": { 507 | "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941", 508 | "__expectedType__": "cc.SpriteFrame" 509 | }, 510 | "_hoverSprite": { 511 | "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941", 512 | "__expectedType__": "cc.SpriteFrame" 513 | }, 514 | "_pressedSprite": { 515 | "__uuid__": "544e49d6-3f05-4fa8-9a9e-091f98fc2ce8@f9941", 516 | "__expectedType__": "cc.SpriteFrame" 517 | }, 518 | "_disabledSprite": { 519 | "__uuid__": "951249e0-9f16-456d-8b85-a6ca954da16b@f9941", 520 | "__expectedType__": "cc.SpriteFrame" 521 | }, 522 | "_duration": 0.1, 523 | "_zoomScale": 1.2, 524 | "_target": { 525 | "__id__": 8 526 | }, 527 | "_id": "" 528 | }, 529 | { 530 | "__type__": "cc.CompPrefabInfo", 531 | "fileId": "2fOwBXUwBNvaJ4NyyrOq4C" 532 | }, 533 | { 534 | "__type__": "cc.ClickEvent", 535 | "target": { 536 | "__id__": 1 537 | }, 538 | "component": "", 539 | "_componentId": "ea9d1sCNmFIY78k1DtEu0xO", 540 | "handler": "onClick", 541 | "customEventData": "" 542 | }, 543 | { 544 | "__type__": "cc.Widget", 545 | "_name": "", 546 | "_objFlags": 0, 547 | "node": { 548 | "__id__": 8 549 | }, 550 | "_enabled": true, 551 | "__prefab": { 552 | "__id__": 23 553 | }, 554 | "_alignFlags": 33, 555 | "_target": null, 556 | "_left": 0, 557 | "_right": 0, 558 | "_top": 1.7763568394002505e-15, 559 | "_bottom": 0, 560 | "_horizontalCenter": 0, 561 | "_verticalCenter": 0, 562 | "_isAbsLeft": true, 563 | "_isAbsRight": true, 564 | "_isAbsTop": true, 565 | "_isAbsBottom": true, 566 | "_isAbsHorizontalCenter": true, 567 | "_isAbsVerticalCenter": true, 568 | "_originalWidth": 0, 569 | "_originalHeight": 0, 570 | "_alignMode": 1, 571 | "_lockFlags": 0, 572 | "_id": "" 573 | }, 574 | { 575 | "__type__": "cc.CompPrefabInfo", 576 | "fileId": "6053OAEulLWL9unHEFIxwP" 577 | }, 578 | { 579 | "__type__": "cc.PrefabInfo", 580 | "root": { 581 | "__id__": 1 582 | }, 583 | "asset": { 584 | "__id__": 0 585 | }, 586 | "fileId": "6dCPjWO41NRKGrj0i+fazs" 587 | }, 588 | { 589 | "__type__": "cc.Node", 590 | "_name": "EditBox", 591 | "_objFlags": 0, 592 | "_parent": { 593 | "__id__": 1 594 | }, 595 | "_children": [ 596 | { 597 | "__id__": 26 598 | }, 599 | { 600 | "__id__": 32 601 | }, 602 | { 603 | "__id__": 38 604 | } 605 | ], 606 | "_active": true, 607 | "_components": [ 608 | { 609 | "__id__": 44 610 | }, 611 | { 612 | "__id__": 46 613 | }, 614 | { 615 | "__id__": 48 616 | }, 617 | { 618 | "__id__": 51 619 | } 620 | ], 621 | "_prefab": { 622 | "__id__": 53 623 | }, 624 | "_lpos": { 625 | "__type__": "cc.Vec3", 626 | "x": -58.88499999999999, 627 | "y": 20, 628 | "z": 0 629 | }, 630 | "_lrot": { 631 | "__type__": "cc.Quat", 632 | "x": 0, 633 | "y": 0, 634 | "z": 0, 635 | "w": 1 636 | }, 637 | "_lscale": { 638 | "__type__": "cc.Vec3", 639 | "x": 1, 640 | "y": 1, 641 | "z": 1 642 | }, 643 | "_layer": 33554432, 644 | "_euler": { 645 | "__type__": "cc.Vec3", 646 | "x": 0, 647 | "y": 0, 648 | "z": 0 649 | }, 650 | "_id": "" 651 | }, 652 | { 653 | "__type__": "cc.Node", 654 | "_name": "TEXT_LABEL", 655 | "_objFlags": 0, 656 | "_parent": { 657 | "__id__": 25 658 | }, 659 | "_children": [], 660 | "_active": false, 661 | "_components": [ 662 | { 663 | "__id__": 27 664 | }, 665 | { 666 | "__id__": 29 667 | } 668 | ], 669 | "_prefab": { 670 | "__id__": 31 671 | }, 672 | "_lpos": { 673 | "__type__": "cc.Vec3", 674 | "x": -32.5, 675 | "y": 20, 676 | "z": 0 677 | }, 678 | "_lrot": { 679 | "__type__": "cc.Quat", 680 | "x": 0, 681 | "y": 0, 682 | "z": 0, 683 | "w": 1 684 | }, 685 | "_lscale": { 686 | "__type__": "cc.Vec3", 687 | "x": 1, 688 | "y": 1, 689 | "z": 1 690 | }, 691 | "_layer": 33554432, 692 | "_euler": { 693 | "__type__": "cc.Vec3", 694 | "x": 0, 695 | "y": 0, 696 | "z": 0 697 | }, 698 | "_id": "" 699 | }, 700 | { 701 | "__type__": "cc.UITransform", 702 | "_name": "", 703 | "_objFlags": 0, 704 | "node": { 705 | "__id__": 26 706 | }, 707 | "_enabled": true, 708 | "__prefab": { 709 | "__id__": 28 710 | }, 711 | "_contentSize": { 712 | "__type__": "cc.Size", 713 | "width": 67, 714 | "height": 40 715 | }, 716 | "_anchorPoint": { 717 | "__type__": "cc.Vec2", 718 | "x": 0, 719 | "y": 1 720 | }, 721 | "_id": "" 722 | }, 723 | { 724 | "__type__": "cc.CompPrefabInfo", 725 | "fileId": "779kAXGTtMZKXfYlOg0Tfd" 726 | }, 727 | { 728 | "__type__": "cc.Label", 729 | "_name": "", 730 | "_objFlags": 0, 731 | "node": { 732 | "__id__": 26 733 | }, 734 | "_enabled": true, 735 | "__prefab": { 736 | "__id__": 30 737 | }, 738 | "_visFlags": 0, 739 | "_customMaterial": null, 740 | "_srcBlendFactor": 2, 741 | "_dstBlendFactor": 4, 742 | "_color": { 743 | "__type__": "cc.Color", 744 | "r": 255, 745 | "g": 255, 746 | "b": 255, 747 | "a": 255 748 | }, 749 | "_string": "", 750 | "_horizontalAlign": 0, 751 | "_verticalAlign": 1, 752 | "_actualFontSize": 40, 753 | "_fontSize": 20, 754 | "_fontFamily": "Arial", 755 | "_lineHeight": 40, 756 | "_overflow": 1, 757 | "_enableWrapText": false, 758 | "_font": null, 759 | "_isSystemFontUsed": true, 760 | "_isItalic": false, 761 | "_isBold": false, 762 | "_isUnderline": false, 763 | "_underlineHeight": 2, 764 | "_cacheMode": 0, 765 | "_id": "" 766 | }, 767 | { 768 | "__type__": "cc.CompPrefabInfo", 769 | "fileId": "ddIY+NJvlDTIQAg7PLVrGo" 770 | }, 771 | { 772 | "__type__": "cc.PrefabInfo", 773 | "root": { 774 | "__id__": 1 775 | }, 776 | "asset": { 777 | "__id__": 0 778 | }, 779 | "fileId": "dabJjkBE5PJIvEA+XQl2e+" 780 | }, 781 | { 782 | "__type__": "cc.Node", 783 | "_name": "PLACEHOLDER_LABEL", 784 | "_objFlags": 0, 785 | "_parent": { 786 | "__id__": 25 787 | }, 788 | "_children": [], 789 | "_active": true, 790 | "_components": [ 791 | { 792 | "__id__": 33 793 | }, 794 | { 795 | "__id__": 35 796 | } 797 | ], 798 | "_prefab": { 799 | "__id__": 37 800 | }, 801 | "_lpos": { 802 | "__type__": "cc.Vec3", 803 | "x": -32.5, 804 | "y": 20, 805 | "z": 0 806 | }, 807 | "_lrot": { 808 | "__type__": "cc.Quat", 809 | "x": 0, 810 | "y": 0, 811 | "z": 0, 812 | "w": 1 813 | }, 814 | "_lscale": { 815 | "__type__": "cc.Vec3", 816 | "x": 1, 817 | "y": 1, 818 | "z": 1 819 | }, 820 | "_layer": 33554432, 821 | "_euler": { 822 | "__type__": "cc.Vec3", 823 | "x": 0, 824 | "y": 0, 825 | "z": 0 826 | }, 827 | "_id": "" 828 | }, 829 | { 830 | "__type__": "cc.UITransform", 831 | "_name": "", 832 | "_objFlags": 0, 833 | "node": { 834 | "__id__": 32 835 | }, 836 | "_enabled": true, 837 | "__prefab": { 838 | "__id__": 34 839 | }, 840 | "_contentSize": { 841 | "__type__": "cc.Size", 842 | "width": 67, 843 | "height": 40 844 | }, 845 | "_anchorPoint": { 846 | "__type__": "cc.Vec2", 847 | "x": 0, 848 | "y": 1 849 | }, 850 | "_id": "" 851 | }, 852 | { 853 | "__type__": "cc.CompPrefabInfo", 854 | "fileId": "d07wQj4whCUqYGJH1lEpVp" 855 | }, 856 | { 857 | "__type__": "cc.Label", 858 | "_name": "", 859 | "_objFlags": 0, 860 | "node": { 861 | "__id__": 32 862 | }, 863 | "_enabled": true, 864 | "__prefab": { 865 | "__id__": 36 866 | }, 867 | "_visFlags": 0, 868 | "_customMaterial": null, 869 | "_srcBlendFactor": 2, 870 | "_dstBlendFactor": 4, 871 | "_color": { 872 | "__type__": "cc.Color", 873 | "r": 187, 874 | "g": 187, 875 | "b": 187, 876 | "a": 255 877 | }, 878 | "_string": "height", 879 | "_horizontalAlign": 0, 880 | "_verticalAlign": 1, 881 | "_actualFontSize": 20, 882 | "_fontSize": 20, 883 | "_fontFamily": "Arial", 884 | "_lineHeight": 40, 885 | "_overflow": 1, 886 | "_enableWrapText": false, 887 | "_font": null, 888 | "_isSystemFontUsed": true, 889 | "_isItalic": false, 890 | "_isBold": false, 891 | "_isUnderline": false, 892 | "_underlineHeight": 2, 893 | "_cacheMode": 0, 894 | "_id": "" 895 | }, 896 | { 897 | "__type__": "cc.CompPrefabInfo", 898 | "fileId": "8fhi7qRLFJbK0abIJuXmCW" 899 | }, 900 | { 901 | "__type__": "cc.PrefabInfo", 902 | "root": { 903 | "__id__": 1 904 | }, 905 | "asset": { 906 | "__id__": 0 907 | }, 908 | "fileId": "64ygsKD0BEIaDZyxXEkoqs" 909 | }, 910 | { 911 | "__type__": "cc.Node", 912 | "_name": "Label", 913 | "_objFlags": 0, 914 | "_parent": { 915 | "__id__": 25 916 | }, 917 | "_children": [], 918 | "_active": true, 919 | "_components": [ 920 | { 921 | "__id__": 39 922 | }, 923 | { 924 | "__id__": 41 925 | } 926 | ], 927 | "_prefab": { 928 | "__id__": 43 929 | }, 930 | "_lpos": { 931 | "__type__": "cc.Vec3", 932 | "x": -58, 933 | "y": 0, 934 | "z": 0 935 | }, 936 | "_lrot": { 937 | "__type__": "cc.Quat", 938 | "x": 0, 939 | "y": 0, 940 | "z": 0, 941 | "w": 1 942 | }, 943 | "_lscale": { 944 | "__type__": "cc.Vec3", 945 | "x": 1, 946 | "y": 1, 947 | "z": 1 948 | }, 949 | "_layer": 33554432, 950 | "_euler": { 951 | "__type__": "cc.Vec3", 952 | "x": 0, 953 | "y": 0, 954 | "z": 0 955 | }, 956 | "_id": "" 957 | }, 958 | { 959 | "__type__": "cc.UITransform", 960 | "_name": "", 961 | "_objFlags": 0, 962 | "node": { 963 | "__id__": 38 964 | }, 965 | "_enabled": true, 966 | "__prefab": { 967 | "__id__": 40 968 | }, 969 | "_contentSize": { 970 | "__type__": "cc.Size", 971 | "width": 60, 972 | "height": 50.4 973 | }, 974 | "_anchorPoint": { 975 | "__type__": "cc.Vec2", 976 | "x": 0.5, 977 | "y": 0.5 978 | }, 979 | "_id": "" 980 | }, 981 | { 982 | "__type__": "cc.CompPrefabInfo", 983 | "fileId": "c68UOAlNhN171Umca6yVvF" 984 | }, 985 | { 986 | "__type__": "cc.Label", 987 | "_name": "", 988 | "_objFlags": 0, 989 | "node": { 990 | "__id__": 38 991 | }, 992 | "_enabled": true, 993 | "__prefab": { 994 | "__id__": 42 995 | }, 996 | "_visFlags": 0, 997 | "_customMaterial": null, 998 | "_srcBlendFactor": 2, 999 | "_dstBlendFactor": 4, 1000 | "_color": { 1001 | "__type__": "cc.Color", 1002 | "r": 255, 1003 | "g": 255, 1004 | "b": 255, 1005 | "a": 255 1006 | }, 1007 | "_string": "高度:", 1008 | "_horizontalAlign": 1, 1009 | "_verticalAlign": 1, 1010 | "_actualFontSize": 20, 1011 | "_fontSize": 20, 1012 | "_fontFamily": "Arial", 1013 | "_lineHeight": 40, 1014 | "_overflow": 0, 1015 | "_enableWrapText": true, 1016 | "_font": null, 1017 | "_isSystemFontUsed": true, 1018 | "_isItalic": false, 1019 | "_isBold": false, 1020 | "_isUnderline": false, 1021 | "_underlineHeight": 2, 1022 | "_cacheMode": 0, 1023 | "_id": "" 1024 | }, 1025 | { 1026 | "__type__": "cc.CompPrefabInfo", 1027 | "fileId": "2frm37uaJHQr0AEEaYyM82" 1028 | }, 1029 | { 1030 | "__type__": "cc.PrefabInfo", 1031 | "root": { 1032 | "__id__": 1 1033 | }, 1034 | "asset": { 1035 | "__id__": 0 1036 | }, 1037 | "fileId": "2bo3bcN65P7anPPAbGgl7p" 1038 | }, 1039 | { 1040 | "__type__": "cc.UITransform", 1041 | "_name": "", 1042 | "_objFlags": 0, 1043 | "node": { 1044 | "__id__": 25 1045 | }, 1046 | "_enabled": true, 1047 | "__prefab": { 1048 | "__id__": 45 1049 | }, 1050 | "_contentSize": { 1051 | "__type__": "cc.Size", 1052 | "width": 69, 1053 | "height": 40 1054 | }, 1055 | "_anchorPoint": { 1056 | "__type__": "cc.Vec2", 1057 | "x": 0.5, 1058 | "y": 0.5 1059 | }, 1060 | "_id": "" 1061 | }, 1062 | { 1063 | "__type__": "cc.CompPrefabInfo", 1064 | "fileId": "1fhJOVuOVAGYSYZoiE25Uz" 1065 | }, 1066 | { 1067 | "__type__": "cc.Sprite", 1068 | "_name": "", 1069 | "_objFlags": 0, 1070 | "node": { 1071 | "__id__": 25 1072 | }, 1073 | "_enabled": true, 1074 | "__prefab": { 1075 | "__id__": 47 1076 | }, 1077 | "_visFlags": 0, 1078 | "_customMaterial": null, 1079 | "_srcBlendFactor": 2, 1080 | "_dstBlendFactor": 4, 1081 | "_color": { 1082 | "__type__": "cc.Color", 1083 | "r": 155, 1084 | "g": 212, 1085 | "b": 148, 1086 | "a": 255 1087 | }, 1088 | "_spriteFrame": { 1089 | "__uuid__": "bd1bcaba-bd7d-4a71-b143-997c882383e4@f9941", 1090 | "__expectedType__": "cc.SpriteFrame" 1091 | }, 1092 | "_type": 1, 1093 | "_fillType": 0, 1094 | "_sizeMode": 0, 1095 | "_fillCenter": { 1096 | "__type__": "cc.Vec2", 1097 | "x": 0, 1098 | "y": 0 1099 | }, 1100 | "_fillStart": 0, 1101 | "_fillRange": 0, 1102 | "_isTrimmedMode": true, 1103 | "_useGrayscale": false, 1104 | "_atlas": null, 1105 | "_id": "" 1106 | }, 1107 | { 1108 | "__type__": "cc.CompPrefabInfo", 1109 | "fileId": "43qH95z3VGeYelCElKd6FW" 1110 | }, 1111 | { 1112 | "__type__": "cc.EditBox", 1113 | "_name": "", 1114 | "_objFlags": 0, 1115 | "node": { 1116 | "__id__": 25 1117 | }, 1118 | "_enabled": true, 1119 | "__prefab": { 1120 | "__id__": 49 1121 | }, 1122 | "editingDidBegan": [], 1123 | "textChanged": [], 1124 | "editingDidEnded": [ 1125 | { 1126 | "__id__": 50 1127 | } 1128 | ], 1129 | "editingReturn": [], 1130 | "_textLabel": { 1131 | "__id__": 29 1132 | }, 1133 | "_placeholderLabel": { 1134 | "__id__": 35 1135 | }, 1136 | "_returnType": 0, 1137 | "_string": "", 1138 | "_tabIndex": 0, 1139 | "_backgroundImage": { 1140 | "__uuid__": "bd1bcaba-bd7d-4a71-b143-997c882383e4@f9941", 1141 | "__expectedType__": "cc.SpriteFrame" 1142 | }, 1143 | "_inputFlag": 5, 1144 | "_inputMode": 6, 1145 | "_maxLength": 8, 1146 | "_id": "" 1147 | }, 1148 | { 1149 | "__type__": "cc.CompPrefabInfo", 1150 | "fileId": "1bCHrwPGZOPrbmPh93kwpe" 1151 | }, 1152 | { 1153 | "__type__": "cc.ClickEvent", 1154 | "target": { 1155 | "__id__": 1 1156 | }, 1157 | "component": "", 1158 | "_componentId": "ea9d1sCNmFIY78k1DtEu0xO", 1159 | "handler": "onInput", 1160 | "customEventData": "" 1161 | }, 1162 | { 1163 | "__type__": "cc.Widget", 1164 | "_name": "", 1165 | "_objFlags": 0, 1166 | "node": { 1167 | "__id__": 25 1168 | }, 1169 | "_enabled": true, 1170 | "__prefab": { 1171 | "__id__": 52 1172 | }, 1173 | "_alignFlags": 9, 1174 | "_target": null, 1175 | "_left": 56.61500000000001, 1176 | "_right": 0, 1177 | "_top": 10, 1178 | "_bottom": 0, 1179 | "_horizontalCenter": 0, 1180 | "_verticalCenter": 0, 1181 | "_isAbsLeft": true, 1182 | "_isAbsRight": true, 1183 | "_isAbsTop": true, 1184 | "_isAbsBottom": true, 1185 | "_isAbsHorizontalCenter": true, 1186 | "_isAbsVerticalCenter": true, 1187 | "_originalWidth": 69, 1188 | "_originalHeight": 40, 1189 | "_alignMode": 1, 1190 | "_lockFlags": 0, 1191 | "_id": "" 1192 | }, 1193 | { 1194 | "__type__": "cc.CompPrefabInfo", 1195 | "fileId": "1anBR8XftMY7O/0+jxD2jp" 1196 | }, 1197 | { 1198 | "__type__": "cc.PrefabInfo", 1199 | "root": { 1200 | "__id__": 1 1201 | }, 1202 | "asset": { 1203 | "__id__": 0 1204 | }, 1205 | "fileId": "f4VXqVWkdIMJ0bUItyTR8W" 1206 | }, 1207 | { 1208 | "__type__": "cc.UITransform", 1209 | "_name": "", 1210 | "_objFlags": 0, 1211 | "node": { 1212 | "__id__": 1 1213 | }, 1214 | "_enabled": true, 1215 | "__prefab": { 1216 | "__id__": 55 1217 | }, 1218 | "_contentSize": { 1219 | "__type__": "cc.Size", 1220 | "width": 300, 1221 | "height": 100 1222 | }, 1223 | "_anchorPoint": { 1224 | "__type__": "cc.Vec2", 1225 | "x": 0.5, 1226 | "y": 0.5 1227 | }, 1228 | "_id": "" 1229 | }, 1230 | { 1231 | "__type__": "cc.CompPrefabInfo", 1232 | "fileId": "55pCbtzR5GbojKMArZkfim" 1233 | }, 1234 | { 1235 | "__type__": "cc.Sprite", 1236 | "_name": "", 1237 | "_objFlags": 0, 1238 | "node": { 1239 | "__id__": 1 1240 | }, 1241 | "_enabled": true, 1242 | "__prefab": { 1243 | "__id__": 57 1244 | }, 1245 | "_visFlags": 0, 1246 | "_customMaterial": null, 1247 | "_srcBlendFactor": 2, 1248 | "_dstBlendFactor": 4, 1249 | "_color": { 1250 | "__type__": "cc.Color", 1251 | "r": 78, 1252 | "g": 156, 1253 | "b": 87, 1254 | "a": 255 1255 | }, 1256 | "_spriteFrame": { 1257 | "__uuid__": "7d8f9b89-4fd1-4c9f-a3ab-38ec7cded7ca@f9941", 1258 | "__expectedType__": "cc.SpriteFrame" 1259 | }, 1260 | "_type": 0, 1261 | "_fillType": 0, 1262 | "_sizeMode": 0, 1263 | "_fillCenter": { 1264 | "__type__": "cc.Vec2", 1265 | "x": 0, 1266 | "y": 0 1267 | }, 1268 | "_fillStart": 0, 1269 | "_fillRange": 0, 1270 | "_isTrimmedMode": true, 1271 | "_useGrayscale": false, 1272 | "_atlas": null, 1273 | "_id": "" 1274 | }, 1275 | { 1276 | "__type__": "cc.CompPrefabInfo", 1277 | "fileId": "20UGQn4U9GUoln0NJQTkbG" 1278 | }, 1279 | { 1280 | "__type__": "ea9d1sCNmFIY78k1DtEu0xO", 1281 | "_name": "", 1282 | "_objFlags": 0, 1283 | "node": { 1284 | "__id__": 1 1285 | }, 1286 | "_enabled": true, 1287 | "__prefab": { 1288 | "__id__": 59 1289 | }, 1290 | "label": { 1291 | "__id__": 5 1292 | }, 1293 | "input": { 1294 | "__id__": 48 1295 | }, 1296 | "_id": "" 1297 | }, 1298 | { 1299 | "__type__": "cc.CompPrefabInfo", 1300 | "fileId": "f8ccUxm6pDlJtwUTRRWeL3" 1301 | }, 1302 | { 1303 | "__type__": "cc.PrefabInfo", 1304 | "root": { 1305 | "__id__": 1 1306 | }, 1307 | "asset": { 1308 | "__id__": 0 1309 | }, 1310 | "fileId": "89ethdRvdHL6gxOx3A4hp+" 1311 | } 1312 | ] -------------------------------------------------------------------------------- /assets/core/super-layout.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: steveJobs 3 | * @Email: icipiqkm@gmail.com 4 | * @Date: 2021-8-1 01:15:04 5 | * @Last Modified by: steveJobs 6 | * @Last Modified time: 2021-8-1 14:35:43 7 | * @Description: 8 | */ 9 | import { _decorator, Component, Node, ccenum, UITransform, SystemEventType, director, Vec3, EventHandler, instantiate, Prefab, Size, Vec2, size, ScrollView, PageView, PageViewIndicator } from 'cc'; 10 | import { SuperScrollview } from './super-scrollview'; 11 | const { ccclass, property, requireComponent } = _decorator; 12 | const EPSILON = 1e-4 13 | enum Type { 14 | HORIZONTAL = 0, 15 | VERTICAL = 1, 16 | } 17 | ccenum(Type) 18 | enum VerticalAxisDirection { 19 | TOP_TO_BOTTOM = 0, 20 | BOTTOM_TO_TOP = 1 21 | } 22 | ccenum(VerticalAxisDirection) 23 | enum HorizontalAxisDirection { 24 | LEFT_TO_RIGHT = 0, 25 | RIGHT_TO_LEFT = 1 26 | } 27 | ccenum(HorizontalAxisDirection) 28 | enum ScrollDirection { 29 | NONE = 0, 30 | HEADER = 1, 31 | FOOTER = 2, 32 | } 33 | 34 | enum IndexVerticalAxisDirection { 35 | TOP = 0, 36 | BOTTOM = 1, 37 | } 38 | ccenum(IndexVerticalAxisDirection) 39 | enum IndexHorizontalAxisDirection { 40 | LEFT = 0, 41 | RIGHT = 1 42 | } 43 | ccenum(IndexHorizontalAxisDirection) 44 | @ccclass('SuperLayout') 45 | @requireComponent(UITransform) 46 | export class SuperLayout extends Component { 47 | static VerticalAxisDirection = VerticalAxisDirection 48 | static HorizontalAxisDirection = HorizontalAxisDirection 49 | 50 | @property(SuperScrollview) scrollView!: SuperScrollview 51 | @property(UITransform) view!: UITransform 52 | @property(Prefab) prefab!: Prefab 53 | @property({ type: Type }) layoutType: Type = Type.VERTICAL 54 | @property({ 55 | type: IndexVerticalAxisDirection, 56 | visible: function () { return (this as any).layoutType == Type.VERTICAL && !(this as any).autoCenter } 57 | }) indexVerticalAxisDirection = IndexVerticalAxisDirection.TOP 58 | @property({ 59 | type: IndexHorizontalAxisDirection, 60 | visible: function () { return (this as any).layoutType == Type.HORIZONTAL && !(this as any).autoCenter } 61 | }) indexHorizontalAxisDirection = IndexHorizontalAxisDirection.LEFT 62 | @property({ type: VerticalAxisDirection }) verticalAxisDirection = VerticalAxisDirection.TOP_TO_BOTTOM 63 | @property({ type: HorizontalAxisDirection }) horizontalAxisDirection = HorizontalAxisDirection.LEFT_TO_RIGHT 64 | 65 | @property({ tooltip: "最小值=1,大于1就是Grid模式" }) groupItemTotal: number = 1 66 | @property({ tooltip: "决定最多创建Prefab的数量" }) multiple: number = 2 67 | @property({ tooltip: "顶部填充" }) paddingTop: number = 0 68 | @property({ tooltip: "底部填充" }) paddingBottom: number = 0 69 | @property({ tooltip: "左侧填充" }) paddingLeft: number = 0 70 | @property({ tooltip: "右侧填充" }) paddingRight: number = 0 71 | @property({ tooltip: "横轴间距" }) spacingX: number = 0 72 | @property({ tooltip: "纵轴间距" }) spacingY: number = 0 73 | @property({ tooltip: "计算缩放后的尺寸" }) affectedByScale: boolean = false 74 | 75 | @property({ tooltip: "开启翻页模式" }) isPageView: boolean = false 76 | @property({ 77 | tooltip: "每个页面翻页时所需时间。单位:秒", 78 | visible: function () { return (this as any).isPageView } 79 | }) pageTurningSpeed = 0.3 80 | @property({ 81 | type: PageViewIndicator, 82 | visible: function () { return (this as any).isPageView } 83 | }) indicator!: PageViewIndicator 84 | @property({ 85 | slide: true, 86 | range: [0, 1, 0.01], 87 | tooltip: "滚动临界值,默认单位百分比,当拖拽超出该数值时,松开会自动滚动下一页,小于时则还原", 88 | visible: function () { return (this as any).isPageView } 89 | }) scrollThreshold = 0.5 90 | @property({ 91 | tooltip: "快速滑动翻页临界值。当用户快速滑动时,会根据滑动开始和结束的距离与时间计算出一个速度值,该值与此临界值相比较,如果大于临界值,则进行自动翻页", 92 | visible: function () { return (this as any).isPageView } 93 | }) autoPageTurningThreshold = 100 94 | @property({ 95 | type: EventHandler, 96 | visible: function () { return (this as any).isPageView } 97 | }) pageEvents: EventHandler[] = [] 98 | 99 | 100 | @property({ 101 | tooltip: "开启自动居中", 102 | visible: function () { return !(this as any).isPageView } 103 | }) autoCenter: boolean = false 104 | @property({ 105 | tooltip: "自动居中的滚动时间", 106 | visible: function () { return (this as any).autoCenter } 107 | }) centerTime: number = 1 108 | @property({ 109 | type: Node, 110 | tooltip: "自动居中的参考节点,如果为空、则默认选择View中心", 111 | visible: function () { return (this as any).autoCenter } 112 | }) centerNode!: Node 113 | @property({ 114 | type: Vec2, 115 | tooltip: "自动居中时、Item的居中锚点", 116 | visible: function () { return (this as any).autoCenter } 117 | }) centerAnchor: Vec2 = new Vec2(.5, .5) 118 | 119 | @property({ tooltip: "上/左 无限循环" }) headerLoop: boolean = false 120 | @property({ tooltip: "下/右 无限循环" }) footerLoop: boolean = false 121 | @property(EventHandler) refreshItemEvents: EventHandler[] = [] 122 | private _currPageIndex: number = 0 123 | get currPageIndex() { 124 | return this._currPageIndex 125 | } 126 | private _lastPageIndex: number = 0 127 | get lastPageIndex() { 128 | return this._lastPageIndex 129 | } 130 | private isRestart: boolean = false 131 | /** 当前滚动方向 */ 132 | private scrollDirection: ScrollDirection = ScrollDirection.NONE 133 | /** 是否垂直滚动 */ 134 | get vertical(): boolean { return this.layoutType == Type.VERTICAL } 135 | /** 是否水平滚动 */ 136 | get horizontal(): boolean { return this.layoutType == Type.HORIZONTAL } 137 | get transform(): UITransform | null { return this.node._uiProps.uiTransformComp } 138 | /** View 可容纳的宽度 */ 139 | get accommodWidth() { 140 | return this.view.width - this.paddingLeft - this.paddingRight 141 | } 142 | /** View 可容纳的高度 */ 143 | get accommodHeight() { 144 | return this.view.height - this.paddingTop - this.paddingBottom 145 | } 146 | /** 头部的节点 */ 147 | get header(): UITransform | null { 148 | if (this.node.children.length == 0) return null 149 | return this.node.children[0]._uiProps.uiTransformComp 150 | } 151 | /** 底部的节点 */ 152 | get footer(): UITransform | null { 153 | if (this.node.children.length == 0) return null 154 | return this.node.children[this.node.children.length - 1]._uiProps.uiTransformComp 155 | } 156 | /** 头部索引 */ 157 | get headerIndex(): number { 158 | if (!this.header) return -1 159 | let node: any = this.header.node 160 | return node["__index"] 161 | } 162 | /** 底部索引 */ 163 | get footerIndex(): number { 164 | if (!this.footer) return -1 165 | let node: any = this.footer.node 166 | return node["__index"] 167 | } 168 | /** Item起始位置 */ 169 | get viewStartPoint(): Vec3 { 170 | let pos = new Vec3() 171 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 172 | pos.x = this.view.width * -0.5 + this.paddingLeft 173 | } else { 174 | pos.x = this.view.width * 0.5 - this.paddingRight 175 | } 176 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 177 | pos.y = this.view.height * 0.5 - this.paddingTop 178 | } else { 179 | pos.y = this.view.height * -0.5 + this.paddingBottom 180 | } 181 | return pos 182 | } 183 | /** View 头部边界 */ 184 | get viewHeaderBoundary(): number { 185 | var offset = 0 186 | if (this.vertical) { 187 | offset = this.view.height * 0.5 188 | } else { 189 | offset = this.view.width * -0.5 190 | } 191 | return offset 192 | } 193 | /** View 底部边界 */ 194 | get viewFooterBoundary(): number { 195 | var offset = 0 196 | if (this.vertical) { 197 | offset = this.view.height * -0.5 198 | } else { 199 | offset = this.view.width * 0.5 200 | } 201 | return offset 202 | } 203 | /** 头部节点边界 */ 204 | get headerBoundary(): number { 205 | if (!this.header) return 0 206 | if (this.vertical) { 207 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 208 | return this.node.position.y + this.getItemYMax(this.header) + this.paddingTop 209 | } else { 210 | return this.node.position.y + this.getItemYMin(this.header) - this.paddingBottom 211 | } 212 | } else { 213 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 214 | return this.node.position.x + this.getItemXMin(this.header) - this.paddingLeft 215 | } else { 216 | return this.node.position.x + this.getItemXMax(this.header) + this.paddingRight 217 | } 218 | } 219 | } 220 | /** 底部节点边界 */ 221 | get footerBoundary(): number { 222 | if (!this.footer) return 0 223 | if (this.vertical) { 224 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 225 | return this.node.position.y + this.getItemYMin(this.footer) - this.paddingBottom 226 | } else { 227 | return this.node.position.y + this.getItemYMax(this.footer) + this.paddingTop 228 | } 229 | } else { 230 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 231 | return this.node.position.x + this.getItemXMax(this.footer) + this.paddingRight 232 | } else { 233 | return this.node.position.x + this.getItemXMin(this.footer) - this.paddingLeft 234 | } 235 | } 236 | } 237 | /** 自动居中节点头部边界 */ 238 | get centerHeaderBoundary() { 239 | let key = this.vertical ? "y" : "x" 240 | if (this.centerNode) { 241 | if (this.vertical) { 242 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 243 | return this.headerBoundary + (this.viewHeaderBoundary - (this.centerNode.position as any)[key]) 244 | } else { 245 | return this.footerBoundary + (this.viewHeaderBoundary - (this.centerNode.position as any)[key]) 246 | } 247 | } else { 248 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 249 | return this.headerBoundary + (this.viewHeaderBoundary - (this.centerNode.position as any)[key]) 250 | } else { 251 | return this.footerBoundary + (this.viewHeaderBoundary - (this.centerNode.position as any)[key]) 252 | } 253 | } 254 | } else { 255 | if (this.vertical) { 256 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 257 | return this.headerBoundary + (this.viewHeaderBoundary - (this.view.node.position as any)[key]) 258 | } else { 259 | return this.footerBoundary + (this.viewHeaderBoundary - (this.view.node.position as any)[key]) 260 | } 261 | } else { 262 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 263 | return this.headerBoundary + (this.viewHeaderBoundary - (this.view.node.position as any)[key]) 264 | } else { 265 | return this.footerBoundary + (this.viewHeaderBoundary - (this.view.node.position as any)[key]) 266 | } 267 | } 268 | 269 | } 270 | } 271 | /** 自动居中节点底部边界 */ 272 | get centerFooterBoundary() { 273 | let key = this.vertical ? "y" : "x" 274 | if (this.centerNode) { 275 | if (this.vertical) { 276 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 277 | return this.footerBoundary + (this.viewFooterBoundary - (this.centerNode.position as any)[key]) 278 | } else { 279 | return this.headerBoundary + (this.viewFooterBoundary - (this.centerNode.position as any)[key]) 280 | } 281 | } else { 282 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 283 | return this.footerBoundary + (this.viewFooterBoundary - (this.centerNode.position as any)[key]) 284 | } else { 285 | return this.headerBoundary + (this.viewFooterBoundary - (this.centerNode.position as any)[key]) 286 | } 287 | } 288 | } else { 289 | if (this.vertical) { 290 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 291 | return this.footerBoundary + (this.viewFooterBoundary - (this.view.node.position as any)[key]) 292 | } else { 293 | return this.headerBoundary + (this.viewFooterBoundary - (this.view.node.position as any)[key]) 294 | } 295 | } else { 296 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 297 | return this.footerBoundary + (this.viewFooterBoundary - (this.view.node.position as any)[key]) 298 | } else { 299 | return this.headerBoundary + (this.viewFooterBoundary - (this.view.node.position as any)[key]) 300 | } 301 | } 302 | } 303 | } 304 | /** 是否超出左侧边界 */ 305 | get isOfLeftBoundary(): number { 306 | if (this.vertical) return 0 307 | if (this.autoCenter) { 308 | if (this.scrollDirection == ScrollDirection.HEADER) { 309 | return this.centerHeaderBoundary 310 | } 311 | return 0 312 | } 313 | if (this.headerLoop) { 314 | if (this.header) return 0 315 | return this.viewHeaderBoundary + this.node.position.x 316 | } 317 | 318 | if (!this.header || this.fixedItemWidth <= this.view.width) { 319 | return this.viewHeaderBoundary + this.node.position.x 320 | } 321 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 322 | if (this.headerIndex == 0) { 323 | return this.headerBoundary 324 | } 325 | } else { 326 | if (this.footerIndex == this.itemTotal - 1) { 327 | return this.footerBoundary 328 | } 329 | } 330 | return 0 331 | } 332 | /** 是否超出顶部边界 */ 333 | get isOfTopBoundary(): number { 334 | if (!this.vertical) return 0 335 | if (this.autoCenter) { 336 | if (this.scrollDirection == ScrollDirection.HEADER) { 337 | return this.centerHeaderBoundary 338 | } 339 | return 0 340 | } 341 | if (this.headerLoop) { 342 | if (this.header) return 0 343 | return this.viewHeaderBoundary + this.node.position.y 344 | } 345 | if (!this.header || this.fixedItemHeight <= this.view.height) { 346 | return this.viewHeaderBoundary + this.node.position.y 347 | } 348 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 349 | if (this.headerIndex == 0) { 350 | return this.headerBoundary 351 | } 352 | } else { 353 | if (this.footerIndex == this.itemTotal - 1) { 354 | return this.footerBoundary 355 | } 356 | } 357 | return 0 358 | } 359 | /** 是否超出右侧边界 */ 360 | get isOfRightBoundary(): number { 361 | if (this.vertical) return 0 362 | if (this.autoCenter) { 363 | if (this.scrollDirection == ScrollDirection.FOOTER) { 364 | return this.centerFooterBoundary 365 | } 366 | return 0 367 | } 368 | if (this.footerLoop) { 369 | if (this.footer) return 0 370 | return this.viewFooterBoundary + this.node.position.x 371 | } 372 | if (!this.footer || this.fixedItemWidth <= this.view.width) { 373 | return this.viewFooterBoundary + this.node.position.x 374 | } 375 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 376 | if (this.footerIndex == this.itemTotal - 1) { 377 | return this.footerBoundary 378 | } 379 | } else { 380 | if (this.headerIndex == 0) { 381 | return this.headerBoundary 382 | } 383 | } 384 | return 0 385 | } 386 | /** 是否超出底部边界 */ 387 | get isOfButtomBoundary(): number { 388 | if (!this.vertical) return 0 389 | if (this.autoCenter) { 390 | if (this.scrollDirection == ScrollDirection.FOOTER) { 391 | return this.centerFooterBoundary 392 | } 393 | return 0 394 | } 395 | if (this.footerLoop) { 396 | if (this.footer) return 0 397 | return this.viewFooterBoundary + this.node.position.y 398 | } 399 | if (!this.footer || this.fixedItemHeight <= this.view.height) { 400 | return this.viewFooterBoundary + this.node.position.y 401 | } 402 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 403 | if (this.footerIndex == this.itemTotal - 1) { 404 | return this.footerBoundary 405 | } 406 | } else { 407 | if (this.headerIndex == 0) { 408 | return this.headerBoundary 409 | } 410 | } 411 | return 0 412 | } 413 | /** 从头部到底部的所有Item高度总和 */ 414 | get fixedItemHeight(): number { 415 | if (!this.header) return 0 416 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 417 | return Math.abs(this.getItemYMax(this.header)) + Math.abs(this.getItemYMin(this.footer)) 418 | } else { 419 | return Math.abs(this.getItemYMin(this.header)) + Math.abs(this.getItemYMax(this.footer)) 420 | } 421 | } 422 | /** 从头部到底部的所有Item宽度总和 */ 423 | get fixedItemWidth(): number { 424 | if (!this.header) return 0 425 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 426 | return Math.abs(this.getItemXMin(this.header)) + Math.abs(this.getItemXMax(this.footer)) 427 | } else { 428 | return Math.abs(this.getItemXMax(this.header)) + Math.abs(this.getItemXMin(this.footer)) 429 | } 430 | } 431 | /** 返回 header到 footer 之间的整体尺寸 如果Item数量不足以撑开View 则返回View尺寸 最小值是View尺寸 */ 432 | get contentSize(): Size { 433 | if (this.node.children.length == 0) return this.view.contentSize 434 | let size = new Size(this.view.contentSize.width, this.view.contentSize.height) 435 | if (this.vertical) { 436 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 437 | size.height = this.headerBoundary + -this.footerBoundary 438 | } else { 439 | size.height = this.footerBoundary + -this.headerBoundary 440 | } 441 | } else { 442 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 443 | size.width = this.footerBoundary + -this.headerBoundary 444 | } else { 445 | size.width = this.headerBoundary + -this.footerBoundary 446 | } 447 | } 448 | if (size.width < this.view.contentSize.width) { 449 | size.width = this.view.contentSize.width 450 | } 451 | if (size.height < this.view.contentSize.height) { 452 | size.height = this.view.contentSize.height 453 | } 454 | return size 455 | } 456 | private selfHorW: number = 0 457 | private prevPos: Vec3 = new Vec3(0, 0, 0) 458 | private _maxPrefabTotal: number = 0 459 | /** 已被创建的Item数量 */ 460 | get maxPrefabTotal(): number { return this._maxPrefabTotal } 461 | private currentCreateItemTotal: number = 0 462 | private _itemTotal: number = 0 463 | /** 数据长度 */ 464 | get itemTotal(): number { return this._itemTotal } 465 | private gener!: Generator 466 | private _centerPosition!: Vec3 467 | /** 自动居中的参考位置 */ 468 | get centerPosition(): Vec3 { 469 | if (!this._centerPosition) { 470 | this._centerPosition = new Vec3() 471 | if (this.autoCenter) { 472 | if (this.centerNode) { 473 | let worldPos = this.centerNode.parent?._uiProps.uiTransformComp?.convertToWorldSpaceAR(this.centerNode.position)! 474 | this._centerPosition = this.view.convertToNodeSpaceAR(worldPos) 475 | } 476 | } else { 477 | if (this.vertical) { 478 | if (this.indexVerticalAxisDirection == IndexVerticalAxisDirection.TOP) { 479 | this._centerPosition.y = this.viewHeaderBoundary 480 | } else { 481 | this._centerPosition.y = this.viewFooterBoundary 482 | } 483 | } else { 484 | if (this.indexHorizontalAxisDirection == IndexHorizontalAxisDirection.LEFT) { 485 | this._centerPosition.x = this.viewHeaderBoundary 486 | } else { 487 | this._centerPosition.x = this.viewFooterBoundary 488 | } 489 | } 490 | } 491 | } 492 | return this._centerPosition 493 | } 494 | onLoad() { 495 | this.transform?.setAnchorPoint(new Vec2(.5, .5)) 496 | this.transform?.setContentSize(this.view.contentSize) 497 | this.node.setPosition(Vec3.ZERO) 498 | if (this.isPageView) this.autoCenter = false 499 | this.scrollView.view?.node.on(Node.EventType.SIZE_CHANGED, this.onViewSizeChange, this) 500 | Object.defineProperty(this.transform, "contentSize", { get: () => this.contentSize }) 501 | Object.defineProperty(this.transform, "width", { get: () => this.contentSize.width }) 502 | Object.defineProperty(this.transform, "height", { get: () => this.contentSize.height }) 503 | } 504 | onEnable() { 505 | this.addEventListener() 506 | } 507 | onDisable() { 508 | this.removeEventListener() 509 | } 510 | /** 更新item数量 */ 511 | async total(count: number) { 512 | this.currentCreateItemTotal = count 513 | await this.createItems(count) 514 | let offset = count - this.itemTotal 515 | this._itemTotal = count 516 | this.refreshItems(offset) 517 | this.scrollView.release() 518 | if (this.indicator) { 519 | this.indicator.setPageView((this.scrollView as any)); 520 | } 521 | } 522 | /** 自动居中到最近Item */ 523 | scrollToCenter() { 524 | this.soonFinish() 525 | } 526 | /** 滚动到头部 */ 527 | scrollToHeader(timeInSecond?: number) { 528 | var headerOrFooter = 0 529 | if (this.vertical) { 530 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 531 | headerOrFooter = this.viewHeaderBoundary 532 | } else { 533 | headerOrFooter = this.viewFooterBoundary 534 | } 535 | } else { 536 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 537 | headerOrFooter = this.viewHeaderBoundary 538 | } else { 539 | headerOrFooter = this.viewFooterBoundary 540 | } 541 | } 542 | this.scrollToIndex(0, timeInSecond, new Vec3(headerOrFooter, headerOrFooter)) 543 | } 544 | /** 滚动到尾部 */ 545 | scrollToFooter(timeInSecond?: number) { 546 | var headerOrFooter = 0 547 | if (this.vertical) { 548 | if (this.fixedItemHeight < this.view.height) return 549 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 550 | headerOrFooter = this.viewFooterBoundary 551 | } else { 552 | headerOrFooter = this.viewHeaderBoundary 553 | } 554 | } else { 555 | if (this.fixedItemWidth < this.view.width) return 556 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 557 | headerOrFooter = this.viewFooterBoundary 558 | } else { 559 | headerOrFooter = this.viewHeaderBoundary 560 | } 561 | } 562 | this.scrollToIndex(this.itemTotal - 1, timeInSecond, new Vec3(headerOrFooter, headerOrFooter), true) 563 | } 564 | private isNearFooter(index: number) { 565 | let nearFooter = false 566 | let flag = index > this.footerIndex && index < this.headerIndex 567 | if (flag) { 568 | let result = Math.abs(index - this.headerIndex) < Math.abs(index - this.footerIndex) 569 | if (this.vertical) { 570 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 571 | nearFooter = !result 572 | } else { 573 | nearFooter = result 574 | } 575 | } else { 576 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 577 | nearFooter = !result 578 | } else { 579 | nearFooter = result 580 | } 581 | } 582 | } else if (index > this.footerIndex) { 583 | if (this.vertical) { 584 | nearFooter = this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM ? true : false 585 | } else { 586 | nearFooter = this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT ? true : false 587 | } 588 | } else if (index < this.headerIndex) { 589 | if (this.vertical) { 590 | nearFooter = this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM ? false : true 591 | } else { 592 | nearFooter = this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT ? false : true 593 | } 594 | } 595 | return nearFooter 596 | } 597 | private getFooterOffset(index: number) { 598 | let footerOffset = this.footerIndex % this.groupItemTotal 599 | let indexOffset = index % this.groupItemTotal 600 | return indexOffset - footerOffset + this.groupItemTotal 601 | } 602 | private getHeaderOffset(index: number) { 603 | let headerOffset = this.headerIndex % this.groupItemTotal 604 | let indexOffset = index % this.groupItemTotal 605 | return headerOffset - indexOffset + this.groupItemTotal 606 | } 607 | private offsetToHeader(index: number) { 608 | var offset = 0 609 | if (this.vertical) { 610 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 611 | offset = this.getHeaderOffset(index) 612 | } else { 613 | offset = this.getFooterOffset(index) 614 | } 615 | } else { 616 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 617 | offset = this.getHeaderOffset(index) 618 | } else { 619 | offset = this.getFooterOffset(index) 620 | } 621 | } 622 | for (let i = 0; i < offset; i++) { 623 | this.pushToHeader(true) 624 | } 625 | } 626 | private offsetToFooter(index: number) { 627 | var offset = 0 628 | if (this.vertical) { 629 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 630 | offset = this.getFooterOffset(index) 631 | } else { 632 | offset = this.getHeaderOffset(index) 633 | } 634 | } else { 635 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 636 | offset = this.getFooterOffset(index) 637 | } else { 638 | offset = this.getHeaderOffset(index) 639 | } 640 | } 641 | for (let i = 0; i < offset; i++) { 642 | this.pushToFooter(true) 643 | } 644 | } 645 | private resetIndexStartToEnd(index: number) { 646 | for (let i = 0; i < this.node.children.length; i++) { 647 | const child: any = this.node.children[i]; 648 | child["__index"] = index 649 | index++ 650 | if (this.headerLoop || this.footerLoop) { 651 | if (index >= this.itemTotal) { 652 | index = 0 653 | } 654 | } 655 | this.notifyRefreshItem(child) 656 | } 657 | } 658 | private resetIndexEndToStart(index: number) { 659 | for (let i = this.node.children.length - 1; i >= 0; i--) { 660 | const child: any = this.node.children[i]; 661 | child["__index"] = index 662 | index-- 663 | if (this.headerLoop || this.footerLoop) { 664 | if (index < 0) { 665 | index = this.itemTotal - 1 666 | } 667 | } 668 | this.notifyRefreshItem(child) 669 | } 670 | } 671 | /** 跳转到指定索引位置 */ 672 | scrollToIndex(index: number, timeInSecond?: number, boundary?: Vec3, reverse: boolean = false) { 673 | if (isNaN(index) || index < 0 || index > this.itemTotal - 1) return 674 | this.scrollView.stopAutoScroll() 675 | if (this.isPageView) { 676 | this.scrollView.savePageIndex(index) 677 | } 678 | var child = this.node.children.find((item: any) => item["__index"] == index) 679 | var nearFooter = false 680 | if (!child) { 681 | nearFooter = this.isNearFooter(index) 682 | var flag = this.vertical && this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM || !this.vertical && this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT 683 | if (nearFooter) { 684 | this.offsetToFooter(index) 685 | flag ? this.resetIndexEndToStart(index) : this.resetIndexStartToEnd(index) 686 | } else { 687 | this.offsetToHeader(index) 688 | flag ? this.resetIndexStartToEnd(index) : this.resetIndexEndToStart(index) 689 | } 690 | child = this.node.children.find((item: any) => item["__index"] == index) 691 | } 692 | if (!child) return 693 | let itemPos = child.getPosition().clone() 694 | if (!this.autoCenter) { 695 | if (this.vertical) { 696 | if (this.indexVerticalAxisDirection == IndexVerticalAxisDirection.TOP) { 697 | if (!reverse) { 698 | itemPos.y = this.getItemYMax(child._uiProps.uiTransformComp!) + this.paddingTop 699 | } else { 700 | itemPos.y = this.getItemYMin(child._uiProps.uiTransformComp!) - this.paddingBottom 701 | } 702 | } else { 703 | if (!reverse) { 704 | itemPos.y = this.getItemYMin(child._uiProps.uiTransformComp!) - this.paddingBottom 705 | } else { 706 | itemPos.y = this.getItemYMax(child._uiProps.uiTransformComp!) + this.paddingTop 707 | } 708 | } 709 | } else { 710 | if (this.indexHorizontalAxisDirection == IndexHorizontalAxisDirection.LEFT) { 711 | if (!reverse) { 712 | itemPos.x = this.getItemXMin(child._uiProps.uiTransformComp!) - this.paddingLeft 713 | } else { 714 | itemPos.x = this.getItemXMax(child._uiProps.uiTransformComp!) + this.paddingRight 715 | } 716 | } else { 717 | if (!reverse) { 718 | itemPos.x = this.getItemXMax(child._uiProps.uiTransformComp!) + this.paddingRight 719 | } else { 720 | itemPos.x = this.getItemXMin(child._uiProps.uiTransformComp!) - this.paddingLeft 721 | } 722 | } 723 | } 724 | } 725 | let worldPos = this.transform?.convertToWorldSpaceAR(itemPos)! 726 | let localPos = this.view.convertToNodeSpaceAR(worldPos) 727 | let multiple 728 | if (!this.autoCenter && boundary) { 729 | multiple = boundary 730 | } else { 731 | multiple = this.getCenterAnchor(child._uiProps.uiTransformComp!, this.centerPosition) 732 | } 733 | localPos.multiply(new Vec3(-1, -1, 1)).add(multiple) 734 | this.scrollView.scrollToAny(localPos, timeInSecond, true) 735 | } 736 | protected async onViewSizeChange() { 737 | this.isRestart = true 738 | if (this.selfHorW > 0 && this.currentCreateItemTotal > 0) { 739 | // 当尺寸改变时 重新计算prefab的数量 740 | var viewHorW = this.vertical ? this.view.height : this.view.width 741 | if (this.selfHorW < viewHorW * this.multiple) { 742 | await this.createItems(this.currentCreateItemTotal, true) 743 | this.scrollToHeader() 744 | } 745 | } 746 | for (let i = 0; i < this.node.children.length; i++) { 747 | const child: any = this.node.children[i]; 748 | const transform = child._uiProps.uiTransformComp! 749 | this.setAndSaveSizeAndScale(transform) 750 | } 751 | this.resetChilds(true) 752 | this.isRestart = false 753 | } 754 | protected setAndSaveSizeAndScale(item: UITransform) { 755 | item.setContentSize(this.getItemSize(item)); 756 | (item.node as any)["__size"] = item.contentSize.clone(); 757 | (item.node as any)["__scale"] = item.node.getScale().clone(); 758 | } 759 | /** 根据centerAnchor计算自动居中的真实位置 */ 760 | protected getCenterAnchor(item: UITransform, center: Vec3) { 761 | var pos = center.clone() 762 | if (this.vertical) { 763 | let anchor = item.height! * this.centerAnchor.y 764 | let origin = item.height! * item.anchorY! 765 | pos.y -= anchor - origin 766 | } else { 767 | let anchor = item.width! * this.centerAnchor.x 768 | let origin = item.width! * item.anchorX! 769 | pos.x += anchor - origin 770 | } 771 | return pos 772 | } 773 | /** 滚动即将结束时 跑自动居中的逻辑 */ 774 | protected soonFinish() { 775 | if (!this.autoCenter) return 776 | this.scrollView.stopAutoScroll() 777 | var findedPos = new Vec3(999999, 999999) 778 | for (let i = 0; i < this.node.children.length; i++) { 779 | const child = this.node.children[i]; 780 | let worldPos = this.transform?.convertToWorldSpaceAR(child.position)! 781 | let localPos = this.view.convertToNodeSpaceAR(worldPos) 782 | let map = { width: false, height: false } 783 | 784 | var multiple = this.getCenterAnchor(child._uiProps.uiTransformComp!, this.centerPosition) 785 | 786 | let newLocalPos = localPos.subtract(multiple) 787 | map.width = Math.abs(newLocalPos.x) < Math.abs(findedPos.x) 788 | map.height = Math.abs(newLocalPos.y) < Math.abs(findedPos.y) 789 | if (this.vertical && map.height) { 790 | findedPos = newLocalPos 791 | } else if (!this.vertical && map.width) { 792 | findedPos = newLocalPos 793 | } 794 | } 795 | findedPos.multiply(new Vec3(-1, -1, 1)) 796 | this.scrollView.scrollToAny(findedPos, this.centerTime) 797 | } 798 | /** 根据groupItemTotal和View可容纳的尺寸 来平均分配Item该有的尺寸 */ 799 | protected getItemSize(item: UITransform): Size { 800 | let size = new Size() 801 | if (this.vertical) { 802 | let spacing = this.spacingX * (this.groupItemTotal - 1) 803 | size.width = (this.accommodWidth - spacing) / this.groupItemTotal 804 | size.height = item.height 805 | } else { 806 | let spacing = this.spacingY * (this.groupItemTotal - 1) 807 | size.height = (this.accommodHeight - spacing) / this.groupItemTotal 808 | size.width = item.width 809 | } 810 | return size 811 | } 812 | /** 获取Item的YMax */ 813 | protected getItemYMax(item: UITransform | null): number { 814 | if (!item) return 0 815 | let height = this.getScaleHeight(item) * (1 - item.anchorY) 816 | return item.node.position.y + height 817 | } 818 | /** 获取Item的YMin */ 819 | protected getItemYMin(item: UITransform | null): number { 820 | if (!item) return 0 821 | let height = this.getScaleHeight(item) * item.anchorY 822 | return item.node.position.y - height 823 | } 824 | /** 获取Item的XMax */ 825 | protected getItemXMax(item: UITransform | null): number { 826 | if (!item) return 0 827 | let width = this.getScaleWidth(item) * (1 - item.anchorX) 828 | return item.node.position.x + width 829 | } 830 | /** 获取Item的XMin */ 831 | protected getItemXMin(item: UITransform | null): number { 832 | if (!item) return 0 833 | let width = this.getScaleWidth(item) * item.anchorX 834 | return item.node.position.x - width 835 | } 836 | /** 获取一组Item中起始位置X */ 837 | protected getStartX(item: UITransform | null): number { 838 | if (!item) return 0 839 | var x = 0 840 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 841 | let width = this.getScaleWidth(item) * item.anchorX 842 | x = this.viewStartPoint.x + width 843 | } else { 844 | let width = this.getScaleWidth(item) * (1 - item.anchorX) 845 | x = this.viewStartPoint.x - width 846 | } 847 | return x 848 | } 849 | /** 获取一组Item中结束位置X */ 850 | protected getEndX(item: UITransform | null): number { 851 | if (!item) return 0 852 | var x = 0 853 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 854 | let width = this.getScaleWidth(item) * (1 - item.anchorX) 855 | x = -this.viewStartPoint.x - width - this.paddingRight + this.paddingLeft 856 | } else { 857 | let width = this.getScaleWidth(item) * item.anchorX 858 | x = -this.viewStartPoint.x + width + this.paddingLeft - this.paddingRight 859 | } 860 | return x 861 | } 862 | /** 获取一组Item中起始位置Y */ 863 | protected getStartY(item: UITransform | null): number { 864 | if (!item) return 0 865 | var y = 0 866 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 867 | let height = this.getScaleHeight(item) * (1 - item.anchorY) 868 | y = this.viewStartPoint.y - height 869 | } else { 870 | let height = this.getScaleHeight(item) * item.anchorY 871 | y = this.viewStartPoint.y + height 872 | } 873 | return y 874 | } 875 | /** 获取一组Item中结束位置Y */ 876 | protected getEndY(item: UITransform | null): number { 877 | if (!item) return 0 878 | var y = 0 879 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 880 | let height = this.getScaleHeight(item) * item.anchorY 881 | y = -this.viewStartPoint.y + height + this.paddingBottom - this.paddingTop 882 | } else { 883 | let height = this.getScaleHeight(item) * (1 - item.anchorY) 884 | y = -this.viewStartPoint.y - height - this.paddingTop + this.paddingBottom 885 | } 886 | return y 887 | } 888 | /** relative的顶部是否有也容纳空间 */ 889 | protected isAccommodateByTop(relative: UITransform) { 890 | var max = this.getItemYMax(relative) 891 | return max + this.paddingTop < this.accommodHeight * 0.5 892 | } 893 | /** relative的底部是否有也容纳空间 */ 894 | protected isAccommodateByBottom(relative: UITransform) { 895 | var min = this.getItemYMin(relative) 896 | return min - this.paddingBottom > this.accommodHeight * -0.5 897 | } 898 | /** relative的左侧是否有也容纳空间 */ 899 | protected isAccommodateByLeft(relative: UITransform) { 900 | var min = this.getItemXMin(relative) 901 | return min - this.paddingLeft > this.accommodWidth * -0.5 902 | } 903 | /** relative的右侧是否有也容纳空间 */ 904 | protected isAccommodateByRight(relative: UITransform) { 905 | var max = this.getItemXMax(relative) 906 | return max + this.paddingRight < this.accommodWidth * 0.5 907 | } 908 | /** relative的左侧位置 */ 909 | protected getRelativeByLeft(item: UITransform, relative: UITransform): number { 910 | var min = this.getItemXMin(relative) 911 | return min - this.spacingX - this.getScaleWidth(item) * (1 - item.anchorX) 912 | } 913 | /** relative的右侧位置 */ 914 | protected getRelativeByRight(item: UITransform, relative: UITransform): number { 915 | var max = this.getItemXMax(relative) 916 | return max + this.spacingX + this.getScaleWidth(item) * item.anchorX 917 | } 918 | /** relative的顶部位置 */ 919 | protected getRelativeByTop(item: UITransform, relative: UITransform): number { 920 | var max = this.getItemYMax(relative) 921 | return max + this.spacingY + this.getScaleHeight(item) * (1 - item.anchorY) 922 | } 923 | /** relative的底部位置 */ 924 | protected getRelativeByBottom(item: UITransform, relative: UITransform): number { 925 | var min = this.getItemYMin(relative) 926 | return min - this.spacingY - this.getScaleHeight(item) * item.anchorY 927 | } 928 | /** 设置Item的坐标位置 */ 929 | protected setItemPosition(item: UITransform, relative: UITransform, reverse: boolean = false) { 930 | var pos = new Vec3() 931 | if (!this.header) { 932 | pos.x = this.getStartX(item) 933 | pos.y = this.getStartY(item) 934 | } else { 935 | if (this.vertical) { 936 | pos = this.getVerticalRelativePosition(item, relative, reverse) 937 | } else { 938 | pos = this.getHorizontalRelativePosition(item, relative, reverse) 939 | } 940 | } 941 | item.node.setPosition(pos) 942 | } 943 | /** 计算垂直模式的Item应该的位置 */ 944 | protected getVerticalRelativePosition(item: UITransform, relative: UITransform, reverse: boolean) { 945 | var pos = new Vec3() 946 | var isAccommodate = false 947 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 948 | isAccommodate = !reverse ? this.isAccommodateByRight(relative) : this.isAccommodateByLeft(relative) 949 | } else { 950 | isAccommodate = !reverse ? this.isAccommodateByLeft(relative) : this.isAccommodateByRight(relative) 951 | } 952 | // 横轴 953 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 954 | if (!reverse) { 955 | pos.x = isAccommodate ? this.getRelativeByRight(item, relative) : this.getStartX(item) 956 | } else { 957 | pos.x = isAccommodate ? this.getRelativeByLeft(item, relative) : this.getEndX(item) 958 | } 959 | } else { 960 | if (!reverse) { 961 | pos.x = isAccommodate ? this.getRelativeByLeft(item, relative) : this.getStartX(item) 962 | } else { 963 | pos.x = isAccommodate ? this.getRelativeByRight(item, relative) : this.getEndX(item) 964 | } 965 | } 966 | // 纵轴 967 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 968 | if (!reverse) { 969 | pos.y = isAccommodate ? relative.node.position.y : this.getRelativeByBottom(item, relative) 970 | } else { 971 | pos.y = isAccommodate ? relative.node.position.y : this.getRelativeByTop(item, relative) 972 | } 973 | } else { 974 | if (!reverse) { 975 | pos.y = isAccommodate ? relative.node.position.y : this.getRelativeByTop(item, relative) 976 | } else { 977 | pos.y = isAccommodate ? relative.node.position.y : this.getRelativeByBottom(item, relative) 978 | } 979 | } 980 | return pos 981 | } 982 | /** 计算水平模式的Item应该的位置 */ 983 | protected getHorizontalRelativePosition(item: UITransform, relative: UITransform, reverse: boolean) { 984 | var pos = new Vec3() 985 | var isAccommodate = false 986 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 987 | isAccommodate = !reverse ? this.isAccommodateByBottom(relative) : this.isAccommodateByTop(relative) 988 | } else { 989 | isAccommodate = !reverse ? this.isAccommodateByTop(relative) : this.isAccommodateByBottom(relative) 990 | } 991 | // 纵轴 992 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 993 | if (!reverse) { 994 | pos.y = isAccommodate ? this.getRelativeByBottom(item, relative) : this.getStartY(item) 995 | } else { 996 | pos.y = isAccommodate ? this.getRelativeByTop(item, relative) : this.getEndY(item) 997 | } 998 | } else { 999 | if (!reverse) { 1000 | pos.y = isAccommodate ? this.getRelativeByTop(item, relative) : this.getStartY(item) 1001 | } else { 1002 | pos.y = isAccommodate ? this.getRelativeByBottom(item, relative) : this.getEndY(item) 1003 | } 1004 | } 1005 | // 横轴 1006 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 1007 | if (!reverse) { 1008 | pos.x = isAccommodate ? relative.node.position.x : this.getRelativeByRight(item, relative) 1009 | } else { 1010 | pos.x = isAccommodate ? relative.node.position.x : this.getRelativeByLeft(item, relative) 1011 | } 1012 | } else { 1013 | if (!reverse) { 1014 | pos.x = isAccommodate ? relative.node.position.x : this.getRelativeByLeft(item, relative) 1015 | } else { 1016 | pos.x = isAccommodate ? relative.node.position.x : this.getRelativeByRight(item, relative) 1017 | } 1018 | } 1019 | return pos 1020 | } 1021 | /** 当数据长度发生变化时 计算item应该怎么排列 */ 1022 | protected refreshItems(offset: number) { 1023 | if (offset < 0) { 1024 | for (let i = 0; i < -offset; i++) { 1025 | if (this.headerLoop) { 1026 | this.pushToHeader() 1027 | } else if (this.footerLoop) { 1028 | this.pushToHeader() 1029 | } else { 1030 | this.pushToHeader(true) 1031 | } 1032 | } 1033 | let startIndex = this.headerIndex > 0 ? this.headerIndex : 0 1034 | for (let i = 0; i < this.node.children.length; i++) { 1035 | const child: any = this.node.children[i]; 1036 | if (this.headerLoop || this.footerLoop) { 1037 | if (startIndex > this.itemTotal - 1) { 1038 | startIndex = 0 1039 | } 1040 | } 1041 | child["__index"] = startIndex 1042 | this.notifyRefreshItem(child) 1043 | startIndex++ 1044 | } 1045 | this.scrollView.startAutoScroll() 1046 | } else { 1047 | for (let i = 0; i < this.node.children.length; i++) { 1048 | if (this.vertical) { 1049 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 1050 | this.pushToFooter() 1051 | } else { 1052 | this.pushToHeader() 1053 | } 1054 | } else { 1055 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 1056 | this.pushToFooter() 1057 | } else { 1058 | this.pushToHeader() 1059 | } 1060 | } 1061 | } 1062 | } 1063 | } 1064 | /** 创建Item */ 1065 | protected async createItems(count: number, force: boolean = false) { 1066 | this.gener?.return("") 1067 | if (force) { 1068 | this._maxPrefabTotal = 0 1069 | this.selfHorW = 0 1070 | } 1071 | // 有多余的item 需要删除 不处理 1072 | if (!force && this.node.children.length > count) { 1073 | this.removeItems(count) 1074 | return false 1075 | } 1076 | // 已经固定item总数 不处理 1077 | if (this._maxPrefabTotal > 0 && this._maxPrefabTotal == this.node.children.length) { 1078 | return false 1079 | } 1080 | // 开始分帧创建item 1081 | let total = count - this.node.children.length //计算当前应该创建的总数 1082 | this.gener = this.getGeneratorLength(total, () => { 1083 | let child: any = instantiate(this.prefab) 1084 | child["__index"] = this.node.children.length 1085 | const transform = child._uiProps.uiTransformComp 1086 | this.setAndSaveSizeAndScale(transform) 1087 | this.setItemPosition(child._uiProps.uiTransformComp, this.footer!) 1088 | this.node.addChild(child) 1089 | this.notifyRefreshItem(child) 1090 | child.on(Node.EventType.SIZE_CHANGED, this.onChildSize, this) 1091 | child.on(Node.EventType.TRANSFORM_CHANGED, this.onChildScale, this) 1092 | let selfHorW, viewHorW 1093 | if (this.vertical) { 1094 | selfHorW = this.contentSize.height 1095 | viewHorW = this.view.height 1096 | } else { 1097 | selfHorW = this.contentSize.width 1098 | viewHorW = this.view.width 1099 | } 1100 | /** 1101 | * 根据排列方向 来判断对比宽度还是高度 1102 | * 这里使用参数this.multiple来判断是否需要继续创建 默认为2倍 比如view可视尺寸为800 2倍就是1600 1103 | * 根据之前所创建的所有item的尺寸计算是否满足这个尺寸 如果满足则不再继续创建 1104 | * 由于是分帧加载 所以下一次创建会等这一次的返回结果 返回false 则终止分帧任务 1105 | */ 1106 | if (selfHorW >= viewHorW * this.multiple) { 1107 | this._maxPrefabTotal = this.node.children.length 1108 | this.selfHorW = selfHorW 1109 | console.log("已固定item数量", this._maxPrefabTotal) 1110 | return false 1111 | } 1112 | return true 1113 | }) 1114 | await this.exeGenerator(this.gener, 20) //执行分帧任务 1帧创建20个 1115 | return true 1116 | } 1117 | /** 删除多余的item */ 1118 | protected removeItems(count: number) { 1119 | // 有多余的item 需要删除 1120 | let length = this.node.children.length - count 1121 | // 删除掉多余的item 1122 | for (let i = 0; i < length; i++) { 1123 | var child = this.node.children[this.node.children.length - 1] 1124 | child.off(Node.EventType.SIZE_CHANGED, this.onChildSize, this); 1125 | child.off(Node.EventType.TRANSFORM_CHANGED, this.onChildScale, this); 1126 | child.destroy() 1127 | this.node.removeChild(child) 1128 | } 1129 | } 1130 | protected addEventListener() { 1131 | this.node.on(SystemEventType.TRANSFORM_CHANGED, this.onPositionChanged, this) 1132 | } 1133 | protected removeEventListener() { 1134 | this.node.off(SystemEventType.TRANSFORM_CHANGED, this.onPositionChanged, this) 1135 | } 1136 | /** 当Item缩放改变时 限制并改回该有的缩放 */ 1137 | protected onChildScale(type: any) { 1138 | if (this.isRestart) return 1139 | if (!this.affectedByScale) return 1140 | if (type == Node.TransformBit.SCALE) { 1141 | for (let i = 0; i < this.node.children.length; i++) { 1142 | const child: any = this.node.children[i]; 1143 | const __scale = child["__scale"] 1144 | if (this.groupItemTotal == 1) { 1145 | if (this.vertical) { 1146 | if (child.scale.x != __scale.x) { 1147 | console.warn("不允许修改Item缩放X") 1148 | child.setScale(new Vec3(__scale.x, child.scale.y)) 1149 | return 1150 | } 1151 | } else { 1152 | if (child.scale.y != __scale.y) { 1153 | console.warn("不允许修改Item缩放Y") 1154 | child.setScale(new Vec3(child.scale.y, __scale.y)) 1155 | return 1156 | } 1157 | } 1158 | } else if (this.groupItemTotal > 1) { 1159 | if (!child.scale.equals(__scale)) { 1160 | console.warn("Grid模式不允许修改Item缩放") 1161 | child.setScale(__scale) 1162 | return 1163 | } 1164 | } 1165 | } 1166 | if (this.groupItemTotal > 1) return 1167 | this.resetChilds() 1168 | } 1169 | } 1170 | /** 当Item尺寸改变时 限制并改回该有的尺寸 */ 1171 | protected onChildSize() { 1172 | if (this.isRestart) return 1173 | for (let i = 0; i < this.node.children.length; i++) { 1174 | const child: any = this.node.children[i]; 1175 | const __size = child["__size"] 1176 | const transform = child._uiProps.uiTransformComp! 1177 | if (this.groupItemTotal == 1) { 1178 | if (this.vertical) { 1179 | if (transform?.width != __size.width) { 1180 | console.warn("不允许修改Item宽度") 1181 | transform.setContentSize(size(__size.width, transform.height)) 1182 | return 1183 | } 1184 | } else { 1185 | if (transform?.height != __size.height) { 1186 | console.warn("不允许修改Item高度") 1187 | transform.setContentSize(size(transform.width, __size.height)) 1188 | return 1189 | } 1190 | } 1191 | } else if (this.groupItemTotal > 1) { 1192 | if (!transform.contentSize.equals(__size)) { 1193 | console.warn("Grid模式不允许修改Item尺寸") 1194 | transform.setContentSize(__size) 1195 | return 1196 | } 1197 | } 1198 | } 1199 | if (this.groupItemTotal > 1) return 1200 | this.resetChilds() 1201 | } 1202 | /** 重新计算当前所有Item的位置 */ 1203 | protected resetChilds(start: boolean = false) { 1204 | var prevItem: any = this.header 1205 | if (this.vertical && this.fixedItemHeight <= this.view.height || !this.vertical && this.fixedItemWidth <= this.view.width) { 1206 | let x = this.getStartX(this.header) 1207 | let y = this.getStartY(this.header) 1208 | this.header?.node.setPosition(new Vec3(x, y)) 1209 | } 1210 | if (start) { 1211 | if (this.vertical) { 1212 | let x = this.getStartX(this.header) 1213 | this.header?.node.setPosition(new Vec3(x, this.header.node.position.y)) 1214 | } else { 1215 | let y = this.getStartY(this.header) 1216 | this.header?.node.setPosition(new Vec3(this.header.node.position.x, y)) 1217 | } 1218 | } 1219 | for (let i = 1; i < this.node.children.length; i++) { 1220 | const child = this.node.children[i]; 1221 | const transform = child._uiProps.uiTransformComp! 1222 | let relative = !prevItem ? this.header : prevItem 1223 | this.setItemPosition(transform, relative) 1224 | prevItem = transform 1225 | } 1226 | if (!start) this.scrollView.startAutoScroll() 1227 | } 1228 | protected getUsedScaleValue(value: number) { 1229 | return this.affectedByScale ? Math.abs(value) : 1; 1230 | } 1231 | protected getScaleWidth(trans: UITransform | null): number { 1232 | if (!trans) return 0 1233 | return trans.width * this.getUsedScaleValue(trans.node.scale.x) 1234 | } 1235 | protected getScaleHeight(trans: UITransform | null): number { 1236 | if (!trans) return 0 1237 | return trans.height * this.getUsedScaleValue(trans.node.scale.y) 1238 | } 1239 | protected onPositionChanged() { 1240 | if (this.isRestart) return 1241 | if (this.vertical) { 1242 | if (this.scrollView.prevLocation.y < this.scrollView.location.y) { 1243 | this.scrollDirection = ScrollDirection.FOOTER 1244 | } else if (this.scrollView.prevLocation.y > this.scrollView.location.y) { 1245 | this.scrollDirection = ScrollDirection.HEADER 1246 | } else { 1247 | this.scrollDirection = ScrollDirection.NONE 1248 | } 1249 | } else { 1250 | if (this.scrollView.prevLocation.x > this.scrollView.location.x) { 1251 | this.scrollDirection = ScrollDirection.FOOTER 1252 | } else if (this.scrollView.prevLocation.x < this.scrollView.location.x) { 1253 | this.scrollDirection = ScrollDirection.HEADER 1254 | } else { 1255 | this.scrollDirection = ScrollDirection.NONE 1256 | } 1257 | } 1258 | 1259 | if (this.vertical) { 1260 | for (let i = 0; i < this.node.children.length; i++) { 1261 | let isOfBoundary = Math.abs(this.prevPos.y - this.node.position.y) > EPSILON 1262 | if (!isOfBoundary) continue 1263 | if (this.prevPos.y < this.node.position.y) { 1264 | this.pushToFooter() 1265 | } else if (this.prevPos.y > this.node.position.y) { 1266 | this.pushToHeader() 1267 | } 1268 | } 1269 | } else { 1270 | for (let i = 0; i < this.node.children.length; i++) { 1271 | let isOfBoundary = Math.abs(this.prevPos.x - this.node.position.x) > EPSILON 1272 | if (!isOfBoundary) continue 1273 | if (this.prevPos.x > this.node.position.x) { 1274 | this.pushToFooter() 1275 | } else if (this.prevPos.x < this.node.position.x) { 1276 | this.pushToHeader() 1277 | } 1278 | } 1279 | } 1280 | this.prevPos = this.node.position.clone() 1281 | } 1282 | /** 向尾部填充 force如果为true 则强制填充 */ 1283 | protected pushToFooter(force: boolean = false) { 1284 | if (this.vertical) { 1285 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 1286 | if (force || this.headerBoundary - this.paddingTop > this.viewHeaderBoundary + this.header?.height!) { 1287 | this.pushToFooterHandler() 1288 | } 1289 | } else { 1290 | if (force || this.footerBoundary - this.paddingTop > this.viewHeaderBoundary + this.header?.height!) { 1291 | this.pushToHeaderHandler() 1292 | } 1293 | } 1294 | } else { 1295 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 1296 | if (force || this.headerBoundary + this.paddingLeft < this.viewHeaderBoundary - this.header?.width!) { 1297 | this.pushToFooterHandler() 1298 | } 1299 | } else { 1300 | if (force || this.footerBoundary + this.paddingLeft < this.viewHeaderBoundary - this.header?.width!) { 1301 | this.pushToHeaderHandler() 1302 | } 1303 | } 1304 | } 1305 | } 1306 | /** 向头部填充 force如果为true 则强制填充 */ 1307 | protected pushToHeader(force: boolean = false) { 1308 | if (this.vertical) { 1309 | if (this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM) { 1310 | if (force || this.footerBoundary + this.paddingBottom < this.viewFooterBoundary - this.footer?.height!) { 1311 | this.pushToHeaderHandler() 1312 | } 1313 | } else { 1314 | if (force || this.headerBoundary + this.paddingBottom < this.viewFooterBoundary - this.footer?.height!) { 1315 | this.pushToFooterHandler() 1316 | } 1317 | } 1318 | } else { 1319 | if (this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT) { 1320 | if (force || this.footerBoundary - this.paddingRight > this.viewFooterBoundary + this.footer?.width!) { 1321 | this.pushToHeaderHandler() 1322 | } 1323 | } else { 1324 | if (force || this.headerBoundary - this.paddingRight > this.viewFooterBoundary + this.footer?.width!) { 1325 | this.pushToFooterHandler() 1326 | } 1327 | } 1328 | } 1329 | } 1330 | protected pushToFooterHandler() { 1331 | var node: any = this.header?.node 1332 | let loop 1333 | if (this.vertical) { 1334 | loop = this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM ? this.footerLoop : this.headerLoop 1335 | } else { 1336 | loop = this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT ? this.footerLoop : this.headerLoop 1337 | } 1338 | if (loop) { 1339 | if (this.footerIndex >= this.itemTotal - 1) { 1340 | node["__index"] = 0 1341 | } else { 1342 | node["__index"] = this.footerIndex + 1 1343 | } 1344 | } else { 1345 | if (!this.footer || this.footerIndex >= this.itemTotal - 1) return 1346 | node["__index"] = this.footerIndex + 1 1347 | } 1348 | this.notifyRefreshItem(node) 1349 | this.setItemPosition(this.header!, this.footer!) 1350 | this.header?.node.setSiblingIndex(this.node.children.length) 1351 | } 1352 | protected pushToHeaderHandler() { 1353 | var node: any = this.footer?.node 1354 | let loop, loop2 1355 | if (this.vertical) { 1356 | loop = this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM ? this.headerLoop : this.footerLoop 1357 | loop2 = this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM ? this.footerLoop : this.headerLoop 1358 | } else { 1359 | loop = this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT ? this.headerLoop : this.footerLoop 1360 | loop2 = this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT ? this.footerLoop : this.headerLoop 1361 | } 1362 | // 对其头部 1363 | if (!loop && this.headerIndex == 0) { 1364 | // 判断是否是起始位置 1365 | var accommodate 1366 | if (this.vertical) { 1367 | accommodate = this.horizontalAxisDirection == HorizontalAxisDirection.LEFT_TO_RIGHT ? this.isAccommodateByLeft(this.header!) : this.isAccommodateByRight(this.header!) 1368 | } else { 1369 | accommodate = this.verticalAxisDirection == VerticalAxisDirection.TOP_TO_BOTTOM ? this.isAccommodateByTop(this.header!) : this.isAccommodateByBottom(this.header!) 1370 | } 1371 | if (accommodate) { 1372 | this.resetChilds(true) 1373 | } 1374 | } 1375 | if (loop) { 1376 | if (this.headerIndex == 0) { 1377 | node["__index"] = this.itemTotal - 1 1378 | } else { 1379 | node["__index"] = this.headerIndex - 1 1380 | } 1381 | } else { 1382 | if (!this.header || this.headerIndex == 0) return 1383 | node["__index"] = this.headerIndex - 1 1384 | } 1385 | this.notifyRefreshItem(node) 1386 | this.setItemPosition(this.footer!, this.header!, true) 1387 | this.footer?.node.setSiblingIndex(0) 1388 | 1389 | } 1390 | /** 通知给定的node刷新数据 */ 1391 | protected notifyRefreshItem(target: Node) { 1392 | EventHandler.emitEvents(this.refreshItemEvents, target, (target as any)['__index']) 1393 | } 1394 | /** 分帧加载 */ 1395 | protected * getGeneratorLength(length: number, callback: Function, ...params: any): Generator { 1396 | for (let i = 0; i < length; i++) { 1397 | let result = callback(i, ...params) 1398 | if (result) { 1399 | yield 1400 | } else { 1401 | return 1402 | } 1403 | } 1404 | } 1405 | /** 分帧执行 */ 1406 | protected exeGenerator(generator: Generator, duration: number) { 1407 | return new Promise((resolve, reject) => { 1408 | let gen = generator 1409 | let execute = () => { 1410 | let startTime = new Date().getTime() 1411 | for (let iter = gen.next(); ; iter = gen.next()) { 1412 | if (iter == null || iter.done) { 1413 | resolve(null) 1414 | return 1415 | } 1416 | if (new Date().getTime() - startTime > duration) { 1417 | setTimeout(() => execute(), director.getDeltaTime()) 1418 | return 1419 | } 1420 | } 1421 | } 1422 | execute() 1423 | }) 1424 | } 1425 | } --------------------------------------------------------------------------------