我智商爆棚
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wozhishangbaopeng/assets/FrameWork/Component/FMScrollViewLoop.ts

411 lines
17 KiB

4 weeks ago
/*
* @Descripttion:
* @version: 1.0.0
* @Author: YeeChan
* @Date: 2020-07-17 10:32:52
*/
import FMTouchMaskView, { SlideDirection, FMTouchEvent } from "./FMTouchMaskView";
import { FMListener, callFM_custom, handleFM_custom } from "../Interface/FMInterface";
import Utilit from "../Util/Utilit";
import FMItemLayout from "./FMItemLayout";
const { ccclass, property, requireComponent, disallowMultiple, menu } = cc._decorator;
@ccclass
// @requireComponent(cc.ScrollView)
@disallowMultiple() //防止多个相同类型(或子类型)的组件被添加到同一个节点
//@menu('FM组件/FMScrollViewLoop')
export default class FMScrollViewLoop extends FMTouchMaskView {
//是否自动移动
@property()
private _isAutoMoveType: boolean = true;
@property({ tooltip: "自动滚动", type: cc.Boolean })
set isAutoMoveType(val: boolean) {
this._isAutoMoveType = val;
}
get isAutoMoveType() { return this._isAutoMoveType; }
//--------------------------------------
//广告标签
protected ad_tag_custom: any;
//更新的回调
protected fmListenerUpdateData_custom: FMListener;
//layout list
protected arrayAliveListLayout_custom: FMItemLayout[] = []
//自由的节点
protected arrayFreeListLayout_custom: FMItemLayout[] = []
//一个屏幕中的layout数量
private viewLayoutNum_custom: number = 0;
//超出的个数
private viewLayoutGapNum_custom: number = 3;
//总共的个数
private viewLayoutSum_custom: number = 0;
//初始的下标
private startIndexItem_custom: number = 0;
//是否可以更新item相关
private isCanUpdateItems_custom: boolean = false;
//点击了 触发停止
private isTouchStop_custom: boolean = false;
//外部需要控制的是否可以update
private _isCanScrollViewLoopUpdate_custom: boolean = true;
protected isAutoMoveWayLeftUp_custom: boolean = true;//是否自动移动往左或上 还是右或下
//自动移动后等待的时间
protected autoMoveWaitTime_custom: number = 60;
//自动移动的一次的距离格子数量 0不启用
protected autoMoveWaitNum_custom: number = 1;
//移动的数据
protected autoMoveSpeed_custom: number = 3;
//
//当次移动的距离大小
private _nextMoveLength_custom: number = 0;
//当下需要等待的时间
private _waitTimeNum_custom: number = 0;
private _moveState_custom: number = 0;//0正常移动 1等待
protected _init_custom(): boolean {
if (super._init_custom()) {
if (this._slideDirection == SlideDirection.HORIZONTAL) {//水平
this.viewLayoutNum_custom = Math.ceil(this.node.width / (this.itemPrefabWidth_custom));
} else if (this._slideDirection == SlideDirection.VERTICAL) {//垂直
this.viewLayoutNum_custom = Math.ceil(this.node.width / (this.itemPrefabHeight_custom));
}
//创建的个数
this.viewLayoutSum_custom = this.viewLayoutNum_custom + this.viewLayoutGapNum_custom * 2
let pos = 0;
for (let index = 0; index < this.viewLayoutSum_custom; index++) {
let layoutScript = this.cloneLayout_custom();
let layout = layoutScript.node;
if (this._slideDirection == SlideDirection.HORIZONTAL) {//水平
layout.x = pos;
layout.y = 0;
pos = pos + layout.width;
} else if (this._slideDirection == SlideDirection.VERTICAL) {//垂直
layout.x = 0;
layout.y = pos;
pos = pos - layout.height
}
this.arrayAliveListLayout_custom.push(layoutScript);
}
this.isCanUpdateItems_custom = true;
return true;
}
return false;
}
/**
*
* @param _listener
*/
public setFMListenerUpdateItem_custom(_listener: FMListener) {
this.fmListenerUpdateData_custom = _listener;
}
/**
*
* @param way
* @param moveWaitNum 0
* @param waitTime s
* @param speed
*/
public setAutoData_custom(way: number, moveWaitNum?: number, waitTime?: number, speed?: number, bgColor?: string) {
this.isAutoMoveWayLeftUp_custom = way == 0 ? true : false;
this.autoMoveWaitNum_custom = moveWaitNum ? Math.abs(moveWaitNum) : 0;
this.autoMoveWaitTime_custom = waitTime ? Math.abs(waitTime) * 60 : 60;
this.autoMoveSpeed_custom = speed ? Math.abs(speed) : 3;
if (bgColor) {
this.node.color = Utilit.colorHex2Rgb_custom(bgColor);
}
}
/**
*
*/
public isTouchStopView_custom() {
return this.isTouchStop_custom;
}
/**
* update
*/
public setCanScrollViewLoopUpdate_custom(_update: boolean) {
this._isCanScrollViewLoopUpdate_custom = _update;
}
/**
* 广
* @param tag
*/
public setAdTag_custom(tag: any) {
this.ad_tag_custom = tag;
for (let index = 0; index < this.arrayAliveListLayout_custom.length; index++) {
const element = this.arrayAliveListLayout_custom[index];
element.setAdTag_custom(this.ad_tag_custom);
}
for (let index = 0; index < this.arrayFreeListLayout_custom.length; index++) {
const element = this.arrayFreeListLayout_custom[index];
element.setAdTag_custom(this.ad_tag_custom);
}
}
//外部初始数据
public initUpdateItems_custom() {
this._init_custom();
this.startIndexItem_custom = 0;
if (this._slideDirection == SlideDirection.HORIZONTAL) {//水平
let pos = - this.itemPrefabWidth_custom * 3;
for (let index = 0; index < this.arrayAliveListLayout_custom.length; index++) {
const element = this.arrayAliveListLayout_custom[index];
element.setPointX_custom(pos);
element.setItemIndex_custom(this.startIndexItem_custom + index);
pos = pos + this.itemPrefabWidth_custom
}
} else { //垂直
let pos = this.itemPrefabHeight_custom * 3;
for (let index = 0; index < this.arrayAliveListLayout_custom.length; index++) {
const element = this.arrayAliveListLayout_custom[index];
element.setPointY_custom(pos);
element.setItemIndex_custom(this.startIndexItem_custom + index);
pos = pos - this.itemPrefabHeight_custom
}
}
this._updateNextLengthTime_custom();
}
protected update(dt: number): void {
if (this.isCanUpdateItems_custom && this._isCanScrollViewLoopUpdate_custom) {
this.updateScrollingItems_custom();
if (this.isAutoMoveType == true) {//判断类型是自动移动类型
this._updateAutoMove_custom();
}
}
}
/**
*
* @param index
* @param childIndex
*/
protected listenerUpdateInitItem_custom(sum: number) {
if (this.fmListenerUpdateData_custom) {
let data = callFM_custom(this.fmListenerUpdateData_custom, sum);
return data;
}
}
/**
*
*/
public _updateAutoMove_custom() {
if (this.isTouchStopView_custom()) {
return;
}
if (this._moveState_custom == 0) {
if (this.isAutoMoveWayLeftUp_custom) {
if (this._slideDirection == SlideDirection.HORIZONTAL) {//水平
this.content_custom.x = this.content_custom.x - this.autoMoveSpeed_custom
} else {
this.content_custom.y = this.content_custom.y + this.autoMoveSpeed_custom
}
} else {
if (this._slideDirection == SlideDirection.HORIZONTAL) {//水平
this.content_custom.x = this.content_custom.x + this.autoMoveSpeed_custom
} else {
this.content_custom.y = this.content_custom.y - this.autoMoveSpeed_custom
}
}
if (this.autoMoveWaitNum_custom > 0) {//0 持续移动
this._nextMoveLength_custom = this._nextMoveLength_custom - this.autoMoveSpeed_custom;
if (this._nextMoveLength_custom <= 0) {
this._moveState_custom = 1;
}
}
} else {
this._waitTimeNum_custom = this._waitTimeNum_custom + 1;
if (this._waitTimeNum_custom >= this.autoMoveWaitTime_custom) {
this._waitTimeNum_custom = 0;
this._updateNextLengthTime_custom();
}
}
}
/**
*
* @param event
*/
protected _dispatchEvent_custom(event: FMTouchEvent) {
if (event == FMTouchEvent.Scrolling) {
//this.updateScrollingItems();
} else if (event == FMTouchEvent.TouchStart) {
this.isTouchStop_custom = true;
} else if (event == FMTouchEvent.TouchEnded) {
this._updateNextLengthTime_custom();
this.isTouchStop_custom = false;
}
}
/**
*
*/
protected _updateNextLengthTime_custom() {
if (this.autoMoveWaitNum_custom > 0) {
if (this._slideDirection == SlideDirection.HORIZONTAL) {//水平
this._nextMoveLength_custom = this.autoMoveWaitNum_custom * this.itemPrefab.data.width
if (this.isAutoMoveWayLeftUp_custom) {
for (let index = 0; index < this.arrayAliveListLayout_custom.length; index++) {
const element = this.arrayAliveListLayout_custom[index];
let vcx = this.content_custom.x + element.node.x;
if (vcx > -element.node.width && vcx < 0) {
this._nextMoveLength_custom = this._nextMoveLength_custom + vcx;
break;
}
}
} else {
for (let index = this.arrayAliveListLayout_custom.length - 1; index >= 0; index--) {
const element = this.arrayAliveListLayout_custom[index];
let vcx = this.content_custom.x + element.node.x;
if (vcx < this.node.width + element.node.width && vcx > this.node.width) {
vcx = vcx - this.node.width;
this._nextMoveLength_custom = this._nextMoveLength_custom - vcx;
break;
}
}
}
} else {//垂直
this._nextMoveLength_custom = this.autoMoveWaitNum_custom * this.itemPrefab.data.height
if (this.isAutoMoveWayLeftUp_custom) {
for (let index = 0; index < this.arrayAliveListLayout_custom.length; index++) {
const element = this.arrayAliveListLayout_custom[index];
let vcy = this.content_custom.y + element.node.y;
if (vcy < element.node.height && vcy > 0) {
this._nextMoveLength_custom = this._nextMoveLength_custom - vcy;
break;
}
}
} else {
for (let index = this.arrayAliveListLayout_custom.length - 1; index >= 0; index--) {
const element = this.arrayAliveListLayout_custom[index];
let vcy = this.content_custom.y + element.node.y - element.node.height;
if (vcy > -(this.node.height + element.node.height) && vcy < -this.node.height) {
vcy = vcy + this.node.height;
this._nextMoveLength_custom = this._nextMoveLength_custom + vcy;
break;
}
}
}
}
}
this._waitTimeNum_custom = 0;
this._moveState_custom = 0;
}
//更新
protected updateScrollingItems_custom() {
let arrayLive: FMItemLayout[] = []
if (this._slideDirection == SlideDirection.HORIZONTAL) {//水平
for (let index = 0; index < this.arrayAliveListLayout_custom.length; index++) {
const element = this.arrayAliveListLayout_custom[index];
if (this.content_custom.x + element.getPointX_custom() < - this.itemPrefabWidth_custom * 3) {//左 超过三个标准 移除
this.addFreeItem_custom(element);
} else if (element.getPointX_custom() + this.content_custom.x > this.node.width + this.itemPrefabWidth_custom * 3) { //右 超过三个标准 移除
this.addFreeItem_custom(element);
} else { //中间区域 激活
arrayLive.push(element);
}
}
if (arrayLive[0].getPointX_custom() + this.content_custom.x > - this.itemPrefabWidth_custom) {//起始的 低于一个标准 创建一个
let element = this.getFreeItem_custom();
element.setPointX_custom(arrayLive[0].getPointX_custom() - this.itemPrefabWidth_custom);
element.setItemIndex_custom(arrayLive[0].getItemIndex_custom() - 1)
arrayLive.splice(0, 0, element);
element.node.active = true;
}
if (arrayLive[arrayLive.length - 1].getPointX_custom() + this.content_custom.x < + this.node.width + this.itemPrefabWidth_custom) {//结尾的 低于一个标准 创建一个
const element = this.getFreeItem_custom()
element.setPointX_custom(arrayLive[arrayLive.length - 1].getPointX_custom() + this.itemPrefabWidth_custom);
element.setItemIndex_custom(arrayLive[arrayLive.length - 1].getItemIndex_custom() + 1)
arrayLive.push(element);
element.node.active = true;
}
} else { //垂直
for (let index = 0; index < this.arrayAliveListLayout_custom.length; index++) {
const element = this.arrayAliveListLayout_custom[index];
if (element.getPointY_custom() + this.content_custom.y > this.itemPrefabHeight_custom * 3) {//上 超过三个标准 移除
this.addFreeItem_custom(element);
} else if (element.getPointY_custom() < -(this.content_custom.y + this.node.height + this.itemPrefabHeight_custom * 3)) { //下 超过三个标准 移除
this.addFreeItem_custom(element);
} else { //中间区域 激活
arrayLive.push(element);
}
}
if (arrayLive[0].getPointY_custom() + this.content_custom.y <= this.itemPrefabHeight_custom) {//起始的 低于一个标准 创建一个
let element = this.getFreeItem_custom();
element.setPointY_custom(arrayLive[0].getPointY_custom() + this.itemPrefabHeight_custom);
element.setItemIndex_custom(arrayLive[0].getItemIndex_custom() - 1)
arrayLive.splice(0, 0, element);
element.node.active = true;
}
if (arrayLive[arrayLive.length - 1].getPointY_custom() >= -(this.content_custom.y + this.node.height + this.itemPrefabHeight_custom)) {//结尾的 低于一个标准 创建一个
const element = this.getFreeItem_custom()
element.setPointY_custom(arrayLive[arrayLive.length - 1].getPointY_custom() - this.itemPrefabHeight_custom);
element.setItemIndex_custom(arrayLive[arrayLive.length - 1].getItemIndex_custom() + 1)
arrayLive.push(element);
element.node.active = true;
}
}
this.arrayAliveListLayout_custom = arrayLive;
}
/**
*
*/
private cloneLayout_custom(): FMItemLayout {
let layout = cc.instantiate(this.itemPrefab);
let script = layout.getComponent(FMItemLayout);
script.setAdTag_custom(this.ad_tag_custom)
script.setFMListenerUpdate_custom(handleFM_custom(this.listenerUpdateInitItem_custom, this));
this.content_custom.addChild(layout);
return script;
}
/**
*
*/
private getFreeItem_custom(): FMItemLayout {
let element = this.arrayFreeListLayout_custom.pop()
if (!element) {
element = this.cloneLayout_custom();
}
return element;
}
private addFreeItem_custom(item: FMItemLayout) {
item.node.active = false;
this.arrayFreeListLayout_custom.push(item);
}
}