YZ_ListView.ts 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. import { SubLocation } from "./YZ_Constant";
  2. import CompatibleTool from "./CompatibleTool";
  3. const { ccclass, property } = cc._decorator;
  4. @ccclass
  5. export default class YZ_ListView extends cc.Component {
  6. _scrollView: cc.ScrollView = null;
  7. _content: cc.Node = null;
  8. _itemObj: cc.Node = null;
  9. _visibleCount: number = 5;
  10. _totalCount: number = 0;
  11. _itemSize: cc.Size = cc.size(0, 0);
  12. _spaceX: number = 0;
  13. _bannerSize: cc.Size = cc.size(0, 0);
  14. _itemArray: cc.Node[] = [];
  15. _curOffsetX: number = 0;
  16. _minOffsetX: number = 0;
  17. _maxOffsetX: number = 0;
  18. // 起始位置的索引值
  19. _startIndex: number = 0;
  20. // 滑动方向 -1 向左, 1 向右
  21. _scrollDir: number = 0;
  22. // 交叉推广数据,数组
  23. _recommendData: any = null;
  24. _dataDirty: boolean = false;
  25. _isInit: boolean = false;
  26. _isScorllBar: boolean = false; //是否滚动条
  27. public _location: SubLocation = null; //显示位置
  28. onLoad() {
  29. this._scrollView = this.getComponent(cc.ScrollView);
  30. this._content = this._scrollView.content;
  31. this._itemObj = cc.find("GamePage", this._content);
  32. this._itemSize = this._itemObj.getContentSize();
  33. this._startIndex = 0;
  34. this._bannerSize = this.node.getContentSize();
  35. }
  36. onEnable() {
  37. this._scrollView.node.on("scrolling", this.OnScroll, this);
  38. this._scrollView.node.on("scroll-ended", this.onScrollEnded, this);
  39. }
  40. onDisable() {
  41. this._scrollView.node.targetOff(this);
  42. }
  43. _itemPosX: number = 0;
  44. _itemtmp: cc.Node = null;
  45. _itemToCenterLength: number = 0;
  46. _percent: number = 1;
  47. update(dt: number) {
  48. if (this._isInit) {
  49. if (this._scrollView) {
  50. if (this._scrollView.isScrolling) {
  51. for (let i = 0; i < this._itemArray.length; i++) {
  52. this._itemtmp = this._itemArray[i];
  53. this._itemToCenterLength = Math.abs(this._itemtmp.x + this._content.x - this._bannerSize.width * 0.5);
  54. if ((this._itemSize.width - this._itemToCenterLength) > 0) {
  55. this._percent = (this._itemSize.width - this._itemToCenterLength) / this._itemSize.width;
  56. // if (!this._isScorllBar) {
  57. // this._itemtmp.scale = 1 + this._percent * 0.2;
  58. // }
  59. } else {
  60. if (!this._isScorllBar) {
  61. this._itemtmp.scale = 1;
  62. }
  63. }
  64. }
  65. }
  66. }
  67. this.autoScroll(dt);
  68. }
  69. if (this._dataDirty) {
  70. this._dataDirty = false;
  71. this._updateContent();
  72. }
  73. }
  74. public init(data: any, isScorllBar: boolean = false) {
  75. if (data) {
  76. this._recommendData = data;
  77. this._totalCount = data.length;
  78. this._dataDirty = true;
  79. this._isScorllBar = isScorllBar;
  80. if (this._isScorllBar) {
  81. this._location = SubLocation.isScrollbar;
  82. this._autoScrollInterval = 0.3;
  83. } else {
  84. this._location = SubLocation.isYzBanner;
  85. }
  86. }
  87. }
  88. private _updateContent() {
  89. // 初始化content大小
  90. let num: number = this._recommendData.length;
  91. this._content.setContentSize(cc.size(this._itemSize.width * num, this._itemSize.height));
  92. this.InitObjs();
  93. }
  94. InitObjs() {
  95. let obj: cc.Node = null;
  96. for (let i = 0; i < this._totalCount; i++) {
  97. obj = cc.instantiate(this._itemObj);
  98. obj.x = this._spaceX * 0.5 + this._itemSize.width * 0.5 + this._itemSize.width * i + this._spaceX * i;
  99. obj.y = 0;
  100. obj.getComponentInChildren("GameItem").init(this._recommendData[i], this._location);
  101. this._content.addChild(obj);
  102. this._itemArray.push(obj);
  103. }
  104. let unvisibleCount: number = this._totalCount - this._visibleCount;
  105. this._maxOffsetX = (this._spaceX + this._itemSize.width) * unvisibleCount * -1;
  106. this._itemObj.destroy();
  107. this._isInit = true;
  108. }
  109. OnScroll(scrollview: cc.ScrollView, eventType: cc.ScrollView.EventType, customEventData: any) {
  110. this._content.stopAllActions();
  111. this._canAutoScroll = false;
  112. if (this._scrollView.getScrollOffset().x < this._curOffsetX) {
  113. this._scrollDir = -1;
  114. } else {
  115. this._scrollDir = 1;
  116. }
  117. this._curOffsetX = this._scrollView.getScrollOffset().x;
  118. if (this._scrollView.getScrollOffset().x == 0) {
  119. // utils.showLog("到达最左端......");
  120. // 向右滑动,到达最左端
  121. this._arriveLeft();
  122. } else if (this._scrollView.getScrollOffset().x == this._maxOffsetX) {
  123. // utils.showLog("到达最右端......");
  124. // 向左滑动,到达最右端
  125. this._arriveRight();
  126. }
  127. }
  128. onScrollEnded(scrollview: cc.ScrollView, eventType: cc.ScrollView.EventType, customEventData: any) {
  129. let stopIdx: number = 0;
  130. let tmp: number = Math.abs(this._curOffsetX) % (this._itemSize.width + this._spaceX);
  131. if (tmp > (this._itemSize.width + this._spaceX) * 0.5) {
  132. // 前进一格
  133. stopIdx = Math.ceil(Math.abs(this._curOffsetX) / (this._itemSize.width + this._spaceX));
  134. } else {
  135. // 后退一格
  136. stopIdx = Math.floor(Math.abs(this._curOffsetX) / (this._itemSize.width + this._spaceX));
  137. }
  138. let posX: number = (this._itemSize.width + this._spaceX) * stopIdx * -1;
  139. this._curOffsetX = posX;
  140. this.scroll(posX, 0.3);
  141. }
  142. _arriveLeft() {
  143. this._scrollView.setContentPosition(CompatibleTool.position(this._maxOffsetX, 0));
  144. this._curOffsetX = this._maxOffsetX;
  145. this._startIndex = (this._visibleCount + this._startIndex) % this._totalCount;
  146. this.refreshItem();
  147. }
  148. _arriveRight() {
  149. this._scrollView.setContentPosition(CompatibleTool.position(0, 0));
  150. this._curOffsetX = 0;
  151. this._startIndex = (this._startIndex + this._totalCount - this._visibleCount) % this._totalCount;
  152. this.refreshItem();
  153. }
  154. private refreshItem() {
  155. let posIdx: number = 0;
  156. let obj: cc.Node = null;
  157. for (let i = 0; i < this._totalCount; i++) {
  158. posIdx = (this._totalCount - this._startIndex + i) % this._totalCount;
  159. obj = this._itemArray[i];
  160. obj.x = this._spaceX * 0.5 + this._itemSize.width * 0.5 + this._spaceX * posIdx + this._itemSize.width * posIdx;
  161. }
  162. }
  163. _canAutoScroll: boolean = true;
  164. _autoScrollInterval: number = 2.5;
  165. _timeTmp: number = 0;
  166. autoScroll(dt: number) {
  167. if (this._canAutoScroll) {
  168. this._timeTmp += dt;
  169. if (this._timeTmp >= this._autoScrollInterval) {
  170. this._timeTmp = 0;
  171. let posX: number = this._curOffsetX - this._itemSize.width - this._spaceX;
  172. this._curOffsetX = posX;
  173. this._scrollDir = -1;
  174. if (this._isScorllBar) {
  175. this.scroll(posX, 0);
  176. } else {
  177. this.scroll(posX, 0.5);
  178. }
  179. }
  180. } else {
  181. this._timeTmp = 0;
  182. }
  183. }
  184. scroll(posX: number, duration: number) {
  185. this._content.runAction(cc.sequence(cc.moveTo(duration, CompatibleTool.position(posX, 0)), cc.callFunc(() => {
  186. this._canAutoScroll = true;
  187. if (this._scrollDir == 1 && this._curOffsetX == 0) {
  188. this._arriveLeft();
  189. } else if (this._scrollDir == -1 && this._curOffsetX == this._maxOffsetX) {
  190. this._arriveRight();
  191. }
  192. })));
  193. }
  194. }