@cc-component/cc-ex-component 1.1.6 → 1.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/core/BaseReference.ts +40 -0
- package/assets/{video/VideoComponent.ts.meta → core/BaseReference.ts.meta} +1 -1
- package/assets/core/BaseViewModelData.ts +12 -0
- package/assets/{video/Interface.ts.meta → core/BaseViewModelData.ts.meta} +1 -1
- package/assets/core/ReferenceComponent.ts +317 -0
- package/assets/core/ViewModel.ts +542 -0
- package/assets/{video/IVideo.ts.meta → core/ViewModel.ts.meta} +9 -9
- package/assets/ex/EXButton.ts +191 -0
- package/assets/ex/EXButton.ts.meta +9 -0
- package/assets/ex/ExCommon.ts +6 -4
- package/assets/ex/ExTool.ts +116 -0
- package/assets/ex/ExTool.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext/custom-grid-flow-layout.ts +105 -0
- package/assets/lib/collectView/lib-ext/custom-grid-flow-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext/horizontal-center-layout.ts +84 -0
- package/assets/lib/collectView/lib-ext/horizontal-center-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext/yx-card-page-layout.ts +132 -0
- package/assets/lib/collectView/lib-ext/yx-card-page-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext/yx-carousel-layout.ts +156 -0
- package/assets/lib/collectView/lib-ext/yx-carousel-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext/yx-cover-layout.ts +405 -0
- package/assets/lib/collectView/lib-ext/yx-cover-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext/yx-masonry-flow-layout.ts +194 -0
- package/assets/lib/collectView/lib-ext/yx-masonry-flow-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext/yx-page-view.ts +232 -0
- package/assets/lib/collectView/lib-ext/yx-page-view.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext/yx-table-view.ts +159 -0
- package/assets/lib/collectView/lib-ext/yx-table-view.ts.meta +9 -0
- package/assets/lib/collectView/lib-ext.meta +9 -0
- package/assets/lib/collectView/lib_collect/yx-collection-view.ts +1549 -0
- package/assets/lib/collectView/lib_collect/yx-collection-view.ts.meta +9 -0
- package/assets/lib/collectView/lib_collect/yx-compact-flow-layout.ts +364 -0
- package/assets/lib/collectView/lib_collect/yx-compact-flow-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib_collect/yx-flow-layout.ts +909 -0
- package/assets/lib/collectView/lib_collect/yx-flow-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib_collect/yx-table-layout.ts +352 -0
- package/assets/lib/collectView/lib_collect/yx-table-layout.ts.meta +9 -0
- package/assets/lib/collectView/lib_collect.meta +9 -0
- package/assets/{video/list.meta → lib/collectView.meta} +9 -9
- package/assets/lib/tableView/IListView.ts +17 -0
- package/assets/lib/tableView/IListView.ts.meta +9 -0
- package/assets/lib/tableView/ListView.ts +197 -0
- package/assets/lib/tableView/ListView.ts.meta +9 -0
- package/assets/lib/tableView/ListViewPage.ts +1048 -0
- package/assets/lib/tableView/ListViewPage.ts.meta +9 -0
- package/assets/lib/tableView/ListViewPageLoop.ts +922 -0
- package/assets/lib/tableView/ListViewPageLoop.ts.meta +1 -0
- package/assets/lib/tableView/TableView.ts +82 -0
- package/assets/lib/tableView/TableView.ts.meta +9 -0
- package/assets/lib/tableView.meta +9 -0
- package/assets/{video.meta → lib.meta} +1 -1
- package/assets/platform/Interface.ts +15 -10
- package/assets/platform/android/AndroidModule.ts +12 -0
- package/assets/platform/android/AndroidModule.ts.meta +9 -0
- package/assets/platform/android/AndroidSDK.ts +1 -2
- package/assets/platform/base/PlatfprmModule.ts +44 -29
- package/assets/platform/base/SDKBase.ts +2 -2
- package/assets/platform/base/TTSDK.ts +21 -10
- package/assets/platform/base/WXSDK.ts +15 -16
- package/assets/platform/wx/MiniSDK.ts +41 -3
- package/assets/platform/wx/wxmini.d.ts +2 -2
- package/index.ts +10 -3
- package/package.json +1 -1
- package/assets/core/ReferenceCollector.ts +0 -172
- package/assets/video/IVideo.ts +0 -73
- package/assets/video/Interface.ts +0 -25
- package/assets/video/VideoComponent.prefab +0 -614
- package/assets/video/VideoComponent.prefab.meta +0 -13
- package/assets/video/VideoComponent.ts +0 -33
- package/assets/video/VideoManager.ts +0 -399
- package/assets/video/VideoManager.ts.meta +0 -9
- package/assets/video/VideoModule.ts +0 -137
- package/assets/video/VideoModule.ts.meta +0 -9
- package/assets/video/VideoPlayTT.ts +0 -338
- package/assets/video/VideoPlayTT.ts.meta +0 -9
- package/assets/video/VideoPlayWX.ts +0 -274
- package/assets/video/VideoPlayWX.ts.meta +0 -9
- package/assets/video/VideoPlayWeb.ts +0 -228
- package/assets/video/VideoPlayWeb.ts.meta +0 -9
- /package/assets/core/{ReferenceCollector.ts.meta → ReferenceComponent.ts.meta} +0 -0
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
import { _decorator, math } from 'cc';
|
|
2
|
+
import { YXBinaryLayout, YXCollectionView, YXIndexPath, YXLayoutAttributes } from '../lib_collect/yx-collection-view';
|
|
3
|
+
|
|
4
|
+
enum _yx_cover_layout_snap_mode {
|
|
5
|
+
/**
|
|
6
|
+
* 无吸附行为,就正常的惯性滚动,停到哪里算哪里
|
|
7
|
+
*/
|
|
8
|
+
NONE,
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 在松手时立刻吸附至选中节点
|
|
12
|
+
*/
|
|
13
|
+
FAST,
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 正常的惯性滚动,最终吸附至某个节点
|
|
17
|
+
*/
|
|
18
|
+
AUTO,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 用来实现突出选中节点效果的布局规则
|
|
23
|
+
* 不支持分区排列
|
|
24
|
+
*/
|
|
25
|
+
export class YXCoverLayout extends YXBinaryLayout {
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @deprecated 已废弃,使用 snapMode 属性代替
|
|
29
|
+
*/
|
|
30
|
+
set pagingEnabled(value: boolean) {
|
|
31
|
+
this.snapMode = value ? _yx_cover_layout_snap_mode.FAST : _yx_cover_layout_snap_mode.NONE
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 吸附行为模式
|
|
36
|
+
* 默认 AUTO
|
|
37
|
+
*/
|
|
38
|
+
snapMode: _yx_cover_layout_snap_mode = _yx_cover_layout_snap_mode.AUTO
|
|
39
|
+
static SnapMode = _yx_cover_layout_snap_mode
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 吸附过渡动画时间
|
|
43
|
+
* 默认 0.5
|
|
44
|
+
*/
|
|
45
|
+
fastSnapDuration: number = 0.5
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 节点大小
|
|
49
|
+
*/
|
|
50
|
+
itemSize: math.Size = null
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 间距
|
|
54
|
+
* 默认 0
|
|
55
|
+
*/
|
|
56
|
+
spacing: number = 0
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 非选中节点的缩放系数
|
|
60
|
+
* 默认 0.8
|
|
61
|
+
*/
|
|
62
|
+
scaleValue: number = 0.8
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 非选中节点的 x 轴旋转角度
|
|
66
|
+
* 仅支持 3D 节点
|
|
67
|
+
* 默认 0
|
|
68
|
+
*/
|
|
69
|
+
angleX: number = 0
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* 非选中节点的 y 轴旋转角度
|
|
73
|
+
* 仅支持 3D 节点
|
|
74
|
+
* 默认 0
|
|
75
|
+
*/
|
|
76
|
+
angleY: number = 0
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 非选中节点的 z 轴旋转角度
|
|
80
|
+
* 默认 0
|
|
81
|
+
*/
|
|
82
|
+
angleZ: number = 0
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 构造函数,此类布局必须要确定节点大小属性
|
|
86
|
+
* @param itemSize
|
|
87
|
+
*/
|
|
88
|
+
constructor(itemSize: math.Size) {
|
|
89
|
+
super()
|
|
90
|
+
this.itemSize = itemSize
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* 获取此刻最靠近屏幕中心的节点索引
|
|
95
|
+
* @param collectionView
|
|
96
|
+
* @returns
|
|
97
|
+
*/
|
|
98
|
+
static getCenterProximal(collectionView: YXCollectionView) {
|
|
99
|
+
let offset = collectionView.scrollView.getScrollOffset()
|
|
100
|
+
offset.x = - offset.x
|
|
101
|
+
let visibleCells = collectionView.getVisibleCellNodes()
|
|
102
|
+
let target: YXLayoutAttributes = null
|
|
103
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.HORIZONTAL) {
|
|
104
|
+
let mid = offset.x + collectionView.scrollView.view.width * 0.5
|
|
105
|
+
visibleCells.forEach((element) => {
|
|
106
|
+
const attr = collectionView.getElementAttributes(element)
|
|
107
|
+
let distance1 = Math.abs(attr.frame.center.x - mid)
|
|
108
|
+
let distance2 = target ? Math.abs(target.frame.center.x - mid) : null
|
|
109
|
+
if (distance2 == null || distance1 < distance2) {
|
|
110
|
+
target = attr
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
if (target) { return target.indexPath }
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.VERTICAL) {
|
|
117
|
+
let mid = offset.y + collectionView.scrollView.view.height * 0.5
|
|
118
|
+
visibleCells.forEach((element) => {
|
|
119
|
+
const attr = collectionView.getElementAttributes(element)
|
|
120
|
+
let distance1 = Math.abs(attr.frame.center.y - mid)
|
|
121
|
+
let distance2 = target ? Math.abs(target.frame.center.y - mid) : null
|
|
122
|
+
if (distance2 == null || distance1 < distance2) {
|
|
123
|
+
target = attr
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
if (target) { return target.indexPath }
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return null
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
prepare(collectionView: YXCollectionView): void {
|
|
133
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.HORIZONTAL) {
|
|
134
|
+
this._prepare_horizontal(collectionView)
|
|
135
|
+
return
|
|
136
|
+
}
|
|
137
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.VERTICAL) {
|
|
138
|
+
this._prepare_vertical(collectionView)
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
protected _prepare_horizontal(collectionView: YXCollectionView) {
|
|
144
|
+
collectionView.scrollView.horizontal = true
|
|
145
|
+
collectionView.scrollView.vertical = false
|
|
146
|
+
const nodeSize = collectionView.scrollView.view.contentSize
|
|
147
|
+
let array = []
|
|
148
|
+
|
|
149
|
+
let offset = (nodeSize.width - this.itemSize.width) * 0.5
|
|
150
|
+
let y = (nodeSize.height - this.itemSize.height) * 0.5
|
|
151
|
+
let numberOfItems = collectionView.getNumberOfItems(0)
|
|
152
|
+
for (let item = 0; item < numberOfItems; item++) {
|
|
153
|
+
let indexPath = new YXIndexPath(0, item)
|
|
154
|
+
let attr = YXLayoutAttributes.layoutAttributesForCell(indexPath)
|
|
155
|
+
attr.frame.size = this.itemSize
|
|
156
|
+
attr.frame.y = y
|
|
157
|
+
attr.frame.x = offset + (item > 0 ? this.spacing : 0)
|
|
158
|
+
offset = attr.frame.xMax
|
|
159
|
+
array.push(attr)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
this.attributes = array
|
|
163
|
+
let contentSize = nodeSize.clone()
|
|
164
|
+
contentSize.width = offset + (nodeSize.width - this.itemSize.width) * 0.5
|
|
165
|
+
this.contentSize = contentSize
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
protected _prepare_vertical(collectionView: YXCollectionView) {
|
|
169
|
+
collectionView.scrollView.horizontal = false
|
|
170
|
+
collectionView.scrollView.vertical = true
|
|
171
|
+
const nodeSize = collectionView.scrollView.view.contentSize
|
|
172
|
+
let array = []
|
|
173
|
+
|
|
174
|
+
let offset = (nodeSize.height - this.itemSize.height) * 0.5
|
|
175
|
+
let x = (nodeSize.width - this.itemSize.width) * 0.5
|
|
176
|
+
let numberOfItems = collectionView.getNumberOfItems(0)
|
|
177
|
+
for (let item = 0; item < numberOfItems; item++) {
|
|
178
|
+
let indexPath = new YXIndexPath(0, item)
|
|
179
|
+
let attr = YXLayoutAttributes.layoutAttributesForCell(indexPath)
|
|
180
|
+
attr.frame.size = this.itemSize
|
|
181
|
+
attr.frame.y = offset + (item > 0 ? this.spacing : 0)
|
|
182
|
+
attr.frame.x = x
|
|
183
|
+
offset = attr.frame.yMax
|
|
184
|
+
array.push(attr)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
this.attributes = array
|
|
188
|
+
let contentSize = nodeSize.clone()
|
|
189
|
+
contentSize.height = offset + (nodeSize.height - this.itemSize.height) * 0.5
|
|
190
|
+
this.contentSize = contentSize
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
initOffset(collectionView: YXCollectionView): void {
|
|
194
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.HORIZONTAL) {
|
|
195
|
+
collectionView.scrollView.scrollToLeft(0)
|
|
196
|
+
return
|
|
197
|
+
}
|
|
198
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.VERTICAL) {
|
|
199
|
+
collectionView.scrollView.scrollToTop(0)
|
|
200
|
+
return
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
targetOffset(collectionView: YXCollectionView, touchMoveVelocity: math.Vec3, startOffset: math.Vec2, originTargetOffset: math.Vec2, originScrollDuration: number): { offset: math.Vec2; time?: number; attenuated?: boolean; } | null {
|
|
205
|
+
|
|
206
|
+
// 此刻偏移位置
|
|
207
|
+
let offset = collectionView.scrollView.getScrollOffset()
|
|
208
|
+
offset.x = - offset.x
|
|
209
|
+
|
|
210
|
+
let maxScrollOffset = collectionView.scrollView.getMaxScrollOffset()
|
|
211
|
+
|
|
212
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.HORIZONTAL) {
|
|
213
|
+
if (this.snapMode == _yx_cover_layout_snap_mode.AUTO) {
|
|
214
|
+
// 计算出停留区域
|
|
215
|
+
let visibleRect = new math.Rect()
|
|
216
|
+
visibleRect.origin = originTargetOffset
|
|
217
|
+
visibleRect.x = - visibleRect.x
|
|
218
|
+
visibleRect.y = 0
|
|
219
|
+
if (visibleRect.x < 0) { visibleRect.x = 0 }
|
|
220
|
+
if (visibleRect.x > maxScrollOffset.x) { visibleRect.x = maxScrollOffset.x }
|
|
221
|
+
visibleRect.size = collectionView.scrollView.view.contentSize
|
|
222
|
+
|
|
223
|
+
// 获取目标区域水平中心位置
|
|
224
|
+
let mid = visibleRect.x + collectionView.scrollView.view.width * 0.5
|
|
225
|
+
// 获取目标区域的节点
|
|
226
|
+
let result = this.layoutAttributesForElementsInRect(visibleRect, collectionView)
|
|
227
|
+
// 获取目标区域的最靠近显示范围中心节点
|
|
228
|
+
let target: YXLayoutAttributes = null
|
|
229
|
+
result.forEach((element) => {
|
|
230
|
+
let distance1 = Math.abs(element.frame.center.x - mid)
|
|
231
|
+
let distance2 = target ? Math.abs(target.frame.center.x - mid) : null
|
|
232
|
+
if (distance2 == null || distance1 < distance2) {
|
|
233
|
+
target = element
|
|
234
|
+
}
|
|
235
|
+
})
|
|
236
|
+
// 吸附至目标偏移位置
|
|
237
|
+
if (target) {
|
|
238
|
+
offset.x = target.frame.center.x - collectionView.scrollView.view.width * 0.5
|
|
239
|
+
return { offset: offset, time: Math.max(originScrollDuration, this.fastSnapDuration) }
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (this.snapMode == _yx_cover_layout_snap_mode.FAST) {
|
|
244
|
+
// 此刻显示范围
|
|
245
|
+
let visibleRect = new math.Rect()
|
|
246
|
+
visibleRect.origin = offset
|
|
247
|
+
visibleRect.y = 0
|
|
248
|
+
if (visibleRect.x < 0) { visibleRect.x = 0 }
|
|
249
|
+
if (visibleRect.x > maxScrollOffset.x) { visibleRect.x = maxScrollOffset.x }
|
|
250
|
+
visibleRect.size = collectionView.scrollView.view.contentSize
|
|
251
|
+
|
|
252
|
+
// 获取目标区域水平中心位置
|
|
253
|
+
let mid = visibleRect.x + collectionView.scrollView.view.width * 0.5
|
|
254
|
+
// 获取目标区域的节点
|
|
255
|
+
let result = this.layoutAttributesForElementsInRect(visibleRect, collectionView)
|
|
256
|
+
// 获取目标区域的最靠近显示范围中心节点
|
|
257
|
+
let target: YXLayoutAttributes = null
|
|
258
|
+
result.forEach((element) => {
|
|
259
|
+
let distance1 = Math.abs(element.frame.center.x - mid)
|
|
260
|
+
let distance2 = target ? Math.abs(target.frame.center.x - mid) : null
|
|
261
|
+
if (distance2 == null || distance1 < distance2) {
|
|
262
|
+
target = element
|
|
263
|
+
}
|
|
264
|
+
})
|
|
265
|
+
// 吸附至目标偏移位置
|
|
266
|
+
if (target) {
|
|
267
|
+
offset.x = target.frame.center.x - collectionView.scrollView.view.width * 0.5
|
|
268
|
+
return { offset: offset, time: this.fastSnapDuration }
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.VERTICAL) {
|
|
274
|
+
if (this.snapMode == _yx_cover_layout_snap_mode.AUTO) {
|
|
275
|
+
// 计算出停留区域
|
|
276
|
+
let visibleRect = new math.Rect()
|
|
277
|
+
visibleRect.origin = originTargetOffset
|
|
278
|
+
visibleRect.x = 0
|
|
279
|
+
if (visibleRect.y < 0) { visibleRect.y = 0 }
|
|
280
|
+
if (visibleRect.y > maxScrollOffset.y) { visibleRect.y = maxScrollOffset.y }
|
|
281
|
+
visibleRect.size = collectionView.scrollView.view.contentSize
|
|
282
|
+
|
|
283
|
+
// 获取目标区域垂直中心位置
|
|
284
|
+
let mid = visibleRect.y + collectionView.scrollView.view.height * 0.5
|
|
285
|
+
// 获取目标区域的节点
|
|
286
|
+
let result = this.layoutAttributesForElementsInRect(visibleRect, collectionView)
|
|
287
|
+
// 获取目标区域的最靠近显示范围中心节点
|
|
288
|
+
let target: YXLayoutAttributes = null
|
|
289
|
+
result.forEach((element) => {
|
|
290
|
+
let distance1 = Math.abs(element.frame.center.y - mid)
|
|
291
|
+
let distance2 = target ? Math.abs(target.frame.center.y - mid) : null
|
|
292
|
+
if (distance2 == null || distance1 < distance2) {
|
|
293
|
+
target = element
|
|
294
|
+
}
|
|
295
|
+
})
|
|
296
|
+
// 吸附至目标偏移位置
|
|
297
|
+
if (target) {
|
|
298
|
+
offset.y = target.frame.center.y - collectionView.scrollView.view.height * 0.5
|
|
299
|
+
return { offset: offset, time: Math.max(originScrollDuration, this.fastSnapDuration) }
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (this.snapMode == _yx_cover_layout_snap_mode.FAST) {
|
|
304
|
+
// 计算出停留区域
|
|
305
|
+
let visibleRect = new math.Rect()
|
|
306
|
+
visibleRect.origin = offset
|
|
307
|
+
visibleRect.x = 0
|
|
308
|
+
if (visibleRect.y < 0) { visibleRect.y = 0 }
|
|
309
|
+
if (visibleRect.y > maxScrollOffset.y) { visibleRect.y = maxScrollOffset.y }
|
|
310
|
+
visibleRect.size = collectionView.scrollView.view.contentSize
|
|
311
|
+
|
|
312
|
+
// 获取目标区域垂直中心位置
|
|
313
|
+
let mid = visibleRect.y + collectionView.scrollView.view.height * 0.5
|
|
314
|
+
// 获取目标区域的节点
|
|
315
|
+
let result = this.layoutAttributesForElementsInRect(visibleRect, collectionView)
|
|
316
|
+
// 获取目标区域的最靠近显示范围中心节点
|
|
317
|
+
let target: YXLayoutAttributes = null
|
|
318
|
+
result.forEach((element) => {
|
|
319
|
+
let distance1 = Math.abs(element.frame.center.y - mid)
|
|
320
|
+
let distance2 = target ? Math.abs(target.frame.center.y - mid) : null
|
|
321
|
+
if (distance2 == null || distance1 < distance2) {
|
|
322
|
+
target = element
|
|
323
|
+
}
|
|
324
|
+
})
|
|
325
|
+
// 吸附至目标偏移位置
|
|
326
|
+
if (target) {
|
|
327
|
+
offset.y = target.frame.center.y - collectionView.scrollView.view.height * 0.5
|
|
328
|
+
return { offset: offset, time: this.fastSnapDuration }
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return null
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
scrollTo(indexPath: YXIndexPath, collectionView: YXCollectionView): math.Vec2 {
|
|
337
|
+
let attr = this.layoutAttributesForItemAtIndexPath(indexPath, collectionView)
|
|
338
|
+
if (attr) {
|
|
339
|
+
let offset = attr.frame.origin
|
|
340
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.HORIZONTAL) {
|
|
341
|
+
offset.x = offset.x - (collectionView.scrollView.view.width - attr.frame.width) * 0.5
|
|
342
|
+
}
|
|
343
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.VERTICAL) {
|
|
344
|
+
offset.y = offset.y - (collectionView.scrollView.view.height - attr.frame.height) * 0.5
|
|
345
|
+
}
|
|
346
|
+
return offset
|
|
347
|
+
}
|
|
348
|
+
return null
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
layoutAttributesForElementsInRect(rect: math.Rect, collectionView: YXCollectionView): YXLayoutAttributes[] {
|
|
352
|
+
let result = super.layoutAttributesForElementsInRect(rect, collectionView)
|
|
353
|
+
let offset = collectionView.scrollView.getScrollOffset()
|
|
354
|
+
offset.x = - offset.x
|
|
355
|
+
|
|
356
|
+
let scale = this.scaleValue
|
|
357
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.HORIZONTAL) {
|
|
358
|
+
let mid = offset.x + collectionView.scrollView.view.width * 0.5
|
|
359
|
+
result.forEach((element) => {
|
|
360
|
+
let diff = element.frame.center.x - mid
|
|
361
|
+
let distance = Math.abs(diff)
|
|
362
|
+
let progress = distance / this.itemSize.width
|
|
363
|
+
progress = Math.min(1, progress)
|
|
364
|
+
let scaleValue = 1 - (1 - scale) * progress
|
|
365
|
+
element.scale = new math.Vec3(scaleValue, scaleValue, 1)
|
|
366
|
+
element.zIndex = -distance
|
|
367
|
+
|
|
368
|
+
let eulerAngles = new math.Vec3()
|
|
369
|
+
eulerAngles.x = progress * this.angleX * (diff > 0 ? -1 : 1)
|
|
370
|
+
eulerAngles.y = progress * this.angleY * (diff > 0 ? -1 : 1)
|
|
371
|
+
eulerAngles.z = progress * this.angleZ * (diff > 0 ? -1 : 1)
|
|
372
|
+
element.eulerAngles = eulerAngles
|
|
373
|
+
})
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.VERTICAL) {
|
|
377
|
+
let mid = offset.y + collectionView.scrollView.view.height * 0.5
|
|
378
|
+
result.forEach((element) => {
|
|
379
|
+
let diff = element.frame.center.y - mid
|
|
380
|
+
let distance = Math.abs(diff)
|
|
381
|
+
let progress = distance / this.itemSize.height
|
|
382
|
+
progress = Math.min(1, progress)
|
|
383
|
+
let scaleValue = 1 - (1 - scale) * progress
|
|
384
|
+
element.scale = new math.Vec3(scaleValue, scaleValue, 1)
|
|
385
|
+
element.zIndex = 1 - progress
|
|
386
|
+
|
|
387
|
+
let eulerAngles = new math.Vec3()
|
|
388
|
+
eulerAngles.x = progress * this.angleX * (diff > 0 ? -1 : 1)
|
|
389
|
+
eulerAngles.y = progress * this.angleY * (diff > 0 ? -1 : 1)
|
|
390
|
+
eulerAngles.z = progress * this.angleZ * (diff > 0 ? -1 : 1)
|
|
391
|
+
element.eulerAngles = eulerAngles
|
|
392
|
+
})
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return result
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
shouldUpdateAttributesZIndex(): boolean {
|
|
399
|
+
return true
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
shouldUpdateAttributesForBoundsChange(): boolean {
|
|
403
|
+
return true
|
|
404
|
+
}
|
|
405
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { _decorator, math, UITransform } from 'cc';
|
|
2
|
+
import { YXBinaryLayout, YXCollectionView, YXEdgeInsets, YXIndexPath, YXLayoutAttributes } from '../lib_collect/yx-collection-view';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 瀑布流布局方案
|
|
6
|
+
*/
|
|
7
|
+
export class YXMasonryFlowLayout extends YXBinaryLayout {
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 分几行(水平滚动模式下)或者几列(垂直滚动模式下)展示
|
|
11
|
+
*/
|
|
12
|
+
divide: number | ((section: number, layout: YXMasonryFlowLayout, collectionView: YXCollectionView) => number) = 1
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 水平滚动模式下,仅宽度生效
|
|
16
|
+
* 垂直滚动模式下,仅高度生效
|
|
17
|
+
*/
|
|
18
|
+
itemSize: math.Size | ((indexPath: YXIndexPath, layout: YXMasonryFlowLayout, collectionView: YXCollectionView) => math.Size) = new math.Size(100, 100);
|
|
19
|
+
getItemSize(): math.Size {
|
|
20
|
+
if (this.itemSize instanceof Function == false) {
|
|
21
|
+
return this.itemSize
|
|
22
|
+
}
|
|
23
|
+
throw new Error("YXMasonryFlowLayout: 动态配置的布局参数不支持直接获取,请检查自己的布局逻辑并谨慎的通过动态配置自己获取,注意避免死循环");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 元素之间垂直间距
|
|
28
|
+
*/
|
|
29
|
+
verticalSpacing: number | ((section: number, layout: YXMasonryFlowLayout, collectionView: YXCollectionView) => number) = 0
|
|
30
|
+
getVerticalSpacing(): number {
|
|
31
|
+
if (this.verticalSpacing instanceof Function == false) {
|
|
32
|
+
return this.verticalSpacing
|
|
33
|
+
}
|
|
34
|
+
throw new Error("YXMasonryFlowLayout: 动态配置的布局参数不支持直接获取,请检查自己的布局逻辑并谨慎的通过动态配置自己获取,注意避免死循环");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 元素之间水平间距
|
|
39
|
+
*/
|
|
40
|
+
horizontalSpacing: number | ((section: number, layout: YXMasonryFlowLayout, collectionView: YXCollectionView) => number) = 0
|
|
41
|
+
getHorizontalSpacing(): number {
|
|
42
|
+
if (this.horizontalSpacing instanceof Function == false) {
|
|
43
|
+
return this.horizontalSpacing
|
|
44
|
+
}
|
|
45
|
+
throw new Error("YXMasonryFlowLayout: 动态配置的布局参数不支持直接获取,请检查自己的布局逻辑并谨慎的通过动态配置自己获取,注意避免死循环");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 边距
|
|
50
|
+
*/
|
|
51
|
+
sectionInset: YXEdgeInsets | ((section: number, layout: YXMasonryFlowLayout, collectionView: YXCollectionView) => YXEdgeInsets) = YXEdgeInsets.ZERO
|
|
52
|
+
getSectionInset(): YXEdgeInsets {
|
|
53
|
+
if (this.sectionInset instanceof Function == false) {
|
|
54
|
+
return this.sectionInset
|
|
55
|
+
}
|
|
56
|
+
throw new Error("YXMasonryFlowLayout: 动态配置的布局参数不支持直接获取,请检查自己的布局逻辑并谨慎的通过动态配置自己获取,注意避免死循环");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
prepare(collectionView: YXCollectionView): void {
|
|
60
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.HORIZONTAL) {
|
|
61
|
+
this._masonry_horizontal(collectionView)
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.VERTICAL) {
|
|
65
|
+
this._masonry_vertical(collectionView)
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private _masonry_horizontal(collectionView: YXCollectionView) {
|
|
71
|
+
collectionView.scrollView.horizontal = true
|
|
72
|
+
collectionView.scrollView.vertical = false
|
|
73
|
+
let contentSize = collectionView.node.getComponent(UITransform).contentSize.clone()
|
|
74
|
+
let allAttributes: YXLayoutAttributes[] = []
|
|
75
|
+
|
|
76
|
+
let numberOfSections = collectionView.getNumberOfSections()
|
|
77
|
+
|
|
78
|
+
let sectionMaxX = 0
|
|
79
|
+
for (let section = 0; section < numberOfSections; section++) {
|
|
80
|
+
let numberOfItems = collectionView.getNumberOfItems(section)
|
|
81
|
+
let verticalSpacing = this.verticalSpacing instanceof Function ? this.verticalSpacing(section, this, collectionView) : this.verticalSpacing
|
|
82
|
+
let horizontalSpacing = this.horizontalSpacing instanceof Function ? this.horizontalSpacing(section, this, collectionView) : this.horizontalSpacing
|
|
83
|
+
let sectionInset = this.sectionInset instanceof Function ? this.sectionInset(section, this, collectionView) : this.sectionInset
|
|
84
|
+
let divide = this.divide instanceof Function ? this.divide(section, this, collectionView) : this.divide
|
|
85
|
+
let itemHeight = (contentSize.height - sectionInset.top - sectionInset.bottom - (divide - 1) * verticalSpacing) / divide
|
|
86
|
+
|
|
87
|
+
sectionMaxX += sectionInset.left
|
|
88
|
+
// 初始化区布局信息,key=行,value=目前此行最右边的位置
|
|
89
|
+
let sectionInfos = {}
|
|
90
|
+
for (let divideIdx = 0; divideIdx < divide; divideIdx++) {
|
|
91
|
+
sectionInfos[`${divideIdx}`] = sectionMaxX
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
for (let item = 0; item < numberOfItems; item++) {
|
|
95
|
+
let indexPath = new YXIndexPath(section, item)
|
|
96
|
+
let itemSize = this.itemSize instanceof Function ? this.itemSize(indexPath, this, collectionView) : this.itemSize
|
|
97
|
+
itemSize.height = itemHeight
|
|
98
|
+
|
|
99
|
+
// 查找目前最短的行,在最短的行后面插入节点
|
|
100
|
+
let x = null
|
|
101
|
+
let y = null
|
|
102
|
+
let idx = null
|
|
103
|
+
for (let divideIdx = 0; divideIdx < divide; divideIdx++) {
|
|
104
|
+
let max = sectionInfos[`${divideIdx}`]
|
|
105
|
+
if (x == null || max < x) {
|
|
106
|
+
idx = divideIdx
|
|
107
|
+
x = max
|
|
108
|
+
y = sectionInset.top + (itemHeight + verticalSpacing) * divideIdx
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
let attributes = YXLayoutAttributes.layoutAttributesForCell(indexPath)
|
|
113
|
+
attributes.frame.set(x + horizontalSpacing, y, itemSize.width, itemSize.height)
|
|
114
|
+
allAttributes.push(attributes)
|
|
115
|
+
|
|
116
|
+
sectionInfos[`${idx}`] = attributes.frame.xMax
|
|
117
|
+
sectionMaxX = Math.max(sectionMaxX, attributes.frame.xMax)
|
|
118
|
+
}
|
|
119
|
+
sectionMaxX += sectionInset.right
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
this.attributes = allAttributes
|
|
123
|
+
contentSize.width = Math.max(contentSize.width, sectionMaxX)
|
|
124
|
+
this.contentSize = contentSize
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private _masonry_vertical(collectionView: YXCollectionView) {
|
|
128
|
+
collectionView.scrollView.horizontal = false
|
|
129
|
+
collectionView.scrollView.vertical = true
|
|
130
|
+
let contentSize = collectionView.node.getComponent(UITransform).contentSize.clone()
|
|
131
|
+
let allAttributes: YXLayoutAttributes[] = []
|
|
132
|
+
|
|
133
|
+
let numberOfSections = collectionView.getNumberOfSections()
|
|
134
|
+
|
|
135
|
+
let sectionMaxY = 0
|
|
136
|
+
for (let section = 0; section < numberOfSections; section++) {
|
|
137
|
+
let numberOfItems = collectionView.getNumberOfItems(section)
|
|
138
|
+
let verticalSpacing = this.verticalSpacing instanceof Function ? this.verticalSpacing(section, this, collectionView) : this.verticalSpacing
|
|
139
|
+
let horizontalSpacing = this.horizontalSpacing instanceof Function ? this.horizontalSpacing(section, this, collectionView) : this.horizontalSpacing
|
|
140
|
+
let sectionInset = this.sectionInset instanceof Function ? this.sectionInset(section, this, collectionView) : this.sectionInset
|
|
141
|
+
let divide = this.divide instanceof Function ? this.divide(section, this, collectionView) : this.divide
|
|
142
|
+
let itemWidth = (contentSize.width - sectionInset.left - sectionInset.right - (divide - 1) * horizontalSpacing) / divide
|
|
143
|
+
|
|
144
|
+
sectionMaxY += sectionInset.top
|
|
145
|
+
// 初始化区布局信息,key=列,value=目前此列最底部的位置
|
|
146
|
+
let sectionInfos = {}
|
|
147
|
+
for (let divideIdx = 0; divideIdx < divide; divideIdx++) {
|
|
148
|
+
sectionInfos[`${divideIdx}`] = sectionMaxY
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
for (let item = 0; item < numberOfItems; item++) {
|
|
152
|
+
let indexPath = new YXIndexPath(section, item)
|
|
153
|
+
let itemSize = this.itemSize instanceof Function ? this.itemSize(indexPath, this, collectionView) : this.itemSize
|
|
154
|
+
itemSize.width = itemWidth
|
|
155
|
+
|
|
156
|
+
// 查找目前最短的列,在最短的列下面插入节点
|
|
157
|
+
let x = null
|
|
158
|
+
let y = null
|
|
159
|
+
let idx = null
|
|
160
|
+
for (let divideIdx = 0; divideIdx < divide; divideIdx++) {
|
|
161
|
+
let max = sectionInfos[`${divideIdx}`]
|
|
162
|
+
if (y == null || max < y) {
|
|
163
|
+
idx = divideIdx
|
|
164
|
+
y = max
|
|
165
|
+
x = sectionInset.left + (itemWidth + horizontalSpacing) * divideIdx
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
let attributes = YXLayoutAttributes.layoutAttributesForCell(indexPath)
|
|
170
|
+
attributes.frame.set(x, y + verticalSpacing, itemSize.width, itemSize.height)
|
|
171
|
+
allAttributes.push(attributes)
|
|
172
|
+
|
|
173
|
+
sectionInfos[`${idx}`] = attributes.frame.yMax
|
|
174
|
+
sectionMaxY = Math.max(sectionMaxY, attributes.frame.yMax)
|
|
175
|
+
}
|
|
176
|
+
sectionMaxY += sectionInset.bottom
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
this.attributes = allAttributes
|
|
180
|
+
contentSize.height = Math.max(contentSize.height, sectionMaxY)
|
|
181
|
+
this.contentSize = contentSize
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
initOffset(collectionView: YXCollectionView): void {
|
|
185
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.HORIZONTAL) {
|
|
186
|
+
collectionView.scrollView.scrollToLeft(0)
|
|
187
|
+
return
|
|
188
|
+
}
|
|
189
|
+
if (collectionView.scrollDirection == YXCollectionView.ScrollDirection.VERTICAL) {
|
|
190
|
+
collectionView.scrollView.scrollToTop(0)
|
|
191
|
+
return
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|