@shijiu/jsview-vue 2.3.0 → 2.3.151-test.0
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/bin/browser/BrowserAudio.vue.mjs +4 -1
- package/bin/jsview-vue.mjs +2200 -466
- package/bin/types/utils/JsViewEngineWidget/JsvFocus/JsvFocusHub.d.ts +21 -1
- package/bin/types/utils/JsViewEngineWidget/MetroWidget/RenderItem.d.ts +5 -1
- package/bin/types/utils/JsViewEngineWidget/TemplateParser/CommonMetroTemplate.d.ts +2 -1
- package/bin/types/utils/JsViewEngineWidget/WidgetCommon.d.ts +10 -7
- package/bin/types/utils/JsViewVueTools/ForgeHandles.d.ts +1 -0
- package/bin/types/utils/JsViewVueTools/JsvRuntimeBridge.d.ts +37 -1
- package/bin/types/utils/JsViewVueTools/JsvTextureStore/CapturedTexture/CapturedTexture.d.ts +3 -3
- package/bin/types/utils/JsViewVueTools/JsvTextureStore/DominantColor/GetDominantColor.d.ts +7 -0
- package/bin/types/utils/JsViewVueTools/JsvTextureStore/JsvTextureStore.d.ts +14 -1
- package/bin/types/utils/JsViewVueTools/JsvTextureStore/Store.d.ts +2 -0
- package/bin/types/utils/JsViewVueTools/JsvTextureStore/Texture.d.ts +4 -0
- package/bin/types/utils/JsViewVueWidget/JsvDashPath.vue.d.ts +11 -0
- package/bin/types/utils/JsViewVueWidget/JsvFragShaderView/JsvFragShaderView.vue.d.ts +2 -1
- package/bin/types/utils/JsViewVueWidget/JsvSmoothSlideContainer.vue.d.ts +72 -0
- package/bin/types/utils/JsViewVueWidget/JsvSoundPool.d.ts +26 -0
- package/bin/types/utils/JsViewVueWidget/JsvSwiper/JsvSmoothSwiper.vue.d.ts +112 -0
- package/bin/types/utils/JsViewVueWidget/JsvSwiper/JsvSwiper2.vue.d.ts +142 -0
- package/bin/types/utils/JsViewVueWidget/JsvSwiper/index.d.ts +3 -1
- package/bin/types/utils/JsViewVueWidget/JsvTextureAnim/JsvTextureAnim.vue.d.ts +2 -2
- package/bin/types/utils/JsViewVueWidget/index.d.ts +2 -1
- package/package.json +1 -1
- package/utils/JsViewEngineWidget/JsvFocus/JsvFocusHub.ts +27 -1
- package/utils/JsViewEngineWidget/MetroWidget/MetroWidget.vue +35 -3
- package/utils/JsViewEngineWidget/MetroWidget/MetroWidgetSetup.js +736 -386
- package/utils/JsViewEngineWidget/MetroWidget/RenderItem.ts +13 -2
- package/utils/JsViewEngineWidget/MetroWidget/TaskManager.ts +38 -26
- package/utils/JsViewEngineWidget/TemplateParser/CommonMetroTemplate.ts +144 -73
- package/utils/JsViewEngineWidget/WidgetCommon.ts +12 -0
- package/utils/JsViewPlugin/JsvAudio/BrowserAudio/BrowserAudio.vue +4 -0
- package/utils/JsViewPlugin/JsvAudio/BrowserAudio/JsvSystemAudio.vue +13 -13
- package/utils/JsViewPlugin/JsvPlayer/BrowserJsvPlayer.vue +1 -1
- package/utils/JsViewVueTools/FeatureActive.ts +2 -1
- package/utils/JsViewVueTools/ForgeHandles.ts +5 -2
- package/utils/JsViewVueTools/JsvRuntimeBridge.js +97 -1
- package/utils/JsViewVueTools/JsvTextTools.ts +3 -1
- package/utils/JsViewVueTools/JsvTextureStore/CapturedTexture/CapturedTexture.ts +15 -12
- package/utils/JsViewVueTools/JsvTextureStore/DominantColor/GetDominantColor.ts +36 -0
- package/utils/JsViewVueTools/JsvTextureStore/JsvTextureStore.ts +23 -2
- package/utils/JsViewVueTools/JsvTextureStore/Store.ts +33 -21
- package/utils/JsViewVueTools/JsvTextureStore/Texture.ts +56 -41
- package/utils/JsViewVueWidget/JsvDashPath.vue +150 -0
- package/utils/JsViewVueWidget/JsvFlexCell/JsvFullScrAdjust.vue +3 -1
- package/utils/JsViewVueWidget/JsvFragShaderView/JsvFragShaderView.vue +26 -22
- package/utils/JsViewVueWidget/JsvFreeMoveActor/SetAction.ts +1 -1
- package/utils/JsViewVueWidget/JsvInput/JsvInput.vue +1 -0
- package/utils/JsViewVueWidget/JsvPreload/JsvPreload.vue +2 -2
- package/utils/JsViewVueWidget/JsvSmoothSlideContainer.vue +108 -0
- package/utils/JsViewVueWidget/JsvSoundPool.js +75 -12
- package/utils/JsViewVueWidget/JsvSwiper/JsvSmoothSwiper.vue +543 -0
- package/utils/JsViewVueWidget/JsvSwiper/JsvSwiper.vue +3 -3
- package/utils/JsViewVueWidget/JsvSwiper/JsvSwiper2.vue +644 -0
- package/utils/JsViewVueWidget/JsvSwiper/index.js +3 -1
- package/utils/JsViewVueWidget/JsvTextureAnim/JsvTextureAnim.vue +14 -8
- package/utils/JsViewVueWidget/index.js +2 -1
|
@@ -17,6 +17,7 @@ interface ItemConfig {
|
|
|
17
17
|
itemSlide: number,
|
|
18
18
|
permanent: boolean,
|
|
19
19
|
showSkeleton: boolean,
|
|
20
|
+
enableLongPress: boolean,
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
interface CustomerCallbackMap {
|
|
@@ -43,9 +44,11 @@ export class RenderItem {
|
|
|
43
44
|
public rootDiv: HTMLDivElement | null = null;
|
|
44
45
|
public enableTap: boolean = false;
|
|
45
46
|
public renderKey: Ref<number> = ref(0);
|
|
47
|
+
public placeHolderLayout = null;
|
|
46
48
|
|
|
47
49
|
private customerCallbackMap: CustomerCallbackMap = {};
|
|
48
50
|
private onRef: (() => void) | null;
|
|
51
|
+
private metroWidgetCbk: any;
|
|
49
52
|
public readonly registerObj: object;
|
|
50
53
|
public readonly query: object;
|
|
51
54
|
|
|
@@ -55,7 +58,9 @@ export class RenderItem {
|
|
|
55
58
|
renderStyle: RenderItemStyle,
|
|
56
59
|
itemConfig: ItemConfig,
|
|
57
60
|
onRef: () => void,
|
|
58
|
-
query: object
|
|
61
|
+
query: object,
|
|
62
|
+
metroWidgetCallback: Object,
|
|
63
|
+
) {
|
|
59
64
|
this.templateInfo = templateInfo;
|
|
60
65
|
this.customerData = customerData;
|
|
61
66
|
this.renderStyle = renderStyle;
|
|
@@ -65,6 +70,7 @@ export class RenderItem {
|
|
|
65
70
|
const unregister = this.unregister.bind(this);
|
|
66
71
|
this.registerObj = { register, unregister };
|
|
67
72
|
this.query = query;
|
|
73
|
+
this.metroWidgetCbk = metroWidgetCallback;
|
|
68
74
|
}
|
|
69
75
|
|
|
70
76
|
get id() {
|
|
@@ -147,9 +153,14 @@ export class RenderItem {
|
|
|
147
153
|
}
|
|
148
154
|
|
|
149
155
|
public readonly onTap = computed(() => {
|
|
150
|
-
return this.enableTap ? this.
|
|
156
|
+
return this.enableTap ? this.innerOnTap.bind(this) : null;
|
|
151
157
|
})
|
|
152
158
|
|
|
159
|
+
private innerOnTap(): boolean {
|
|
160
|
+
this.metroWidgetCbk?.onTap?.(this);
|
|
161
|
+
return this.onClick();
|
|
162
|
+
}
|
|
163
|
+
|
|
153
164
|
public onClick(): boolean {
|
|
154
165
|
if (this.mounted.value) {
|
|
155
166
|
this.customerCallbackMap.onClick?.();
|
|
@@ -4,8 +4,8 @@ interface AnimSetting {
|
|
|
4
4
|
easing?: string | null;
|
|
5
5
|
onStart?: () => void;
|
|
6
6
|
onEnd?: (done: boolean) => void;
|
|
7
|
-
duration?: number
|
|
8
|
-
speed?: number
|
|
7
|
+
duration?: number;
|
|
8
|
+
speed?: number;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export class SlideAnimWrapper {
|
|
@@ -19,7 +19,8 @@ export class SlideAnimWrapper {
|
|
|
19
19
|
element: any,
|
|
20
20
|
from: [number, number],
|
|
21
21
|
to: [number, number],
|
|
22
|
-
setting: AnimSetting
|
|
22
|
+
setting: AnimSetting
|
|
23
|
+
) {
|
|
23
24
|
this.frameCount = frameCount;
|
|
24
25
|
this.animSetting = setting;
|
|
25
26
|
this.element = element;
|
|
@@ -28,7 +29,10 @@ export class SlideAnimWrapper {
|
|
|
28
29
|
if (typeof setting.duration == "number") {
|
|
29
30
|
duration = setting.duration;
|
|
30
31
|
} else if (typeof setting.speed == "number") {
|
|
31
|
-
duration = Math.round(
|
|
32
|
+
duration = Math.round(
|
|
33
|
+
Math.max(Math.abs(to[0] - from[0]), Math.abs(to[1] - from[1])) /
|
|
34
|
+
setting.speed
|
|
35
|
+
);
|
|
32
36
|
}
|
|
33
37
|
this.forgeAnim = new Forge.TranslateAnimation(
|
|
34
38
|
from[0],
|
|
@@ -36,10 +40,14 @@ export class SlideAnimWrapper {
|
|
|
36
40
|
from[1],
|
|
37
41
|
to[1],
|
|
38
42
|
duration,
|
|
39
|
-
setting.easing
|
|
43
|
+
Forge.Easing.str2Easing(setting.easing)
|
|
40
44
|
);
|
|
41
45
|
this.forgeAnim.SetAnimationListener(
|
|
42
|
-
new Forge.AnimationListener(
|
|
46
|
+
new Forge.AnimationListener(
|
|
47
|
+
this.onStart.bind(this),
|
|
48
|
+
this.onEnd.bind(this),
|
|
49
|
+
null
|
|
50
|
+
)
|
|
43
51
|
);
|
|
44
52
|
}
|
|
45
53
|
|
|
@@ -72,7 +80,12 @@ export class AnimationManager {
|
|
|
72
80
|
private animList: Array<SlideAnimWrapper> = [];
|
|
73
81
|
private frameCount: number = 0;
|
|
74
82
|
|
|
75
|
-
public startSlideAnim(
|
|
83
|
+
public startSlideAnim(
|
|
84
|
+
element: any,
|
|
85
|
+
from: [number, number],
|
|
86
|
+
to: [number, number],
|
|
87
|
+
setting: AnimSetting
|
|
88
|
+
) {
|
|
76
89
|
let curFrameCount = Forge.sFrameCount.count;
|
|
77
90
|
if (curFrameCount != this.frameCount) {
|
|
78
91
|
this.tryCleanOldAnim();
|
|
@@ -86,7 +99,7 @@ export class AnimationManager {
|
|
|
86
99
|
obj.removeListener();
|
|
87
100
|
}
|
|
88
101
|
obj.stop();
|
|
89
|
-
}
|
|
102
|
+
};
|
|
90
103
|
}
|
|
91
104
|
|
|
92
105
|
private tryCleanOldAnim() {
|
|
@@ -124,7 +137,6 @@ class CancellableRunner {
|
|
|
124
137
|
}
|
|
125
138
|
}
|
|
126
139
|
|
|
127
|
-
|
|
128
140
|
export enum TaskType {
|
|
129
141
|
RESIZE_ITEM = 1,
|
|
130
142
|
SLIDE,
|
|
@@ -141,16 +153,16 @@ export enum SlideTaskType {
|
|
|
141
153
|
type SubType = SlideTaskType | null;
|
|
142
154
|
|
|
143
155
|
interface Task {
|
|
144
|
-
frameCount: number
|
|
145
|
-
type: TaskType
|
|
146
|
-
subType: SubType
|
|
147
|
-
params: any
|
|
156
|
+
frameCount: number;
|
|
157
|
+
type: TaskType;
|
|
158
|
+
subType: SubType;
|
|
159
|
+
params: any;
|
|
148
160
|
}
|
|
149
161
|
|
|
150
162
|
export interface AllTaskList {
|
|
151
|
-
slide: Array<Task
|
|
152
|
-
focus: Array<Task
|
|
153
|
-
resize: Array<Task
|
|
163
|
+
slide: Array<Task>;
|
|
164
|
+
focus: Array<Task>;
|
|
165
|
+
resize: Array<Task>;
|
|
154
166
|
}
|
|
155
167
|
export type AddTaskCallback = (taskList: AllTaskList) => void;
|
|
156
168
|
export class TaskManager {
|
|
@@ -162,9 +174,9 @@ export class TaskManager {
|
|
|
162
174
|
slide: [],
|
|
163
175
|
focus: [],
|
|
164
176
|
resize: [],
|
|
165
|
-
}
|
|
177
|
+
};
|
|
166
178
|
|
|
167
|
-
constructor(private onAddTask: AddTaskCallback) {
|
|
179
|
+
constructor(private onAddTask: AddTaskCallback) {}
|
|
168
180
|
|
|
169
181
|
private cleanTaskCache(): void {
|
|
170
182
|
this.allTaskList.slide = [];
|
|
@@ -179,7 +191,7 @@ export class TaskManager {
|
|
|
179
191
|
this.frameCount = Forge.sFrameCount.count;
|
|
180
192
|
}
|
|
181
193
|
//取消同帧的旧runner
|
|
182
|
-
this.cancellableRunnerList.forEach(t => {
|
|
194
|
+
this.cancellableRunnerList.forEach((t) => {
|
|
183
195
|
t.cancel();
|
|
184
196
|
});
|
|
185
197
|
|
|
@@ -188,19 +200,19 @@ export class TaskManager {
|
|
|
188
200
|
subType: subtype,
|
|
189
201
|
params,
|
|
190
202
|
frameCount: Forge.sFrameCount.count,
|
|
191
|
-
}
|
|
203
|
+
};
|
|
192
204
|
switch (type) {
|
|
193
205
|
case TaskType.SLIDE:
|
|
194
|
-
this.allTaskList.slide.push(tObj)
|
|
206
|
+
this.allTaskList.slide.push(tObj);
|
|
195
207
|
break;
|
|
196
208
|
case TaskType.ON_FOCUS_CHANGE:
|
|
197
|
-
this.allTaskList.focus.push(tObj)
|
|
209
|
+
this.allTaskList.focus.push(tObj);
|
|
198
210
|
break;
|
|
199
211
|
case TaskType.RESIZE_ITEM:
|
|
200
|
-
this.allTaskList.resize.push(tObj)
|
|
212
|
+
this.allTaskList.resize.push(tObj);
|
|
201
213
|
break;
|
|
202
214
|
default:
|
|
203
|
-
console.error("undefined type")
|
|
215
|
+
console.error("undefined type");
|
|
204
216
|
break;
|
|
205
217
|
}
|
|
206
218
|
this.onAddTask(this.allTaskList);
|
|
@@ -214,9 +226,9 @@ export class TaskManager {
|
|
|
214
226
|
|
|
215
227
|
public cancelAllTask() {
|
|
216
228
|
this.cleanTaskCache();
|
|
217
|
-
this.cancellableRunnerList.forEach(t => {
|
|
229
|
+
this.cancellableRunnerList.forEach((t) => {
|
|
218
230
|
t.cancel();
|
|
219
231
|
});
|
|
220
232
|
this.cancellableRunnerList = [];
|
|
221
233
|
}
|
|
222
|
-
}
|
|
234
|
+
}
|
|
@@ -47,6 +47,20 @@ interface VisibleSearchConfig {
|
|
|
47
47
|
common: VisibleSearchConfigCommon;
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
+
|
|
51
|
+
function left(item: TemplateItem) {
|
|
52
|
+
return item.left;
|
|
53
|
+
}
|
|
54
|
+
function right(item: TemplateItem) {
|
|
55
|
+
return item.left + item.width - 1;
|
|
56
|
+
}
|
|
57
|
+
function top(item: TemplateItem) {
|
|
58
|
+
return item.top;
|
|
59
|
+
}
|
|
60
|
+
function bottom(item: TemplateItem) {
|
|
61
|
+
return item.top + item.height - 1;
|
|
62
|
+
}
|
|
63
|
+
|
|
50
64
|
class CommonMetroTemplate extends MetroTemplate {
|
|
51
65
|
private _FenceStack: Array<Fence>;
|
|
52
66
|
private _FenceEdge: { StartX: number, StartY: number };
|
|
@@ -445,24 +459,94 @@ class CommonMetroTemplate extends MetroTemplate {
|
|
|
445
459
|
}
|
|
446
460
|
}
|
|
447
461
|
|
|
448
|
-
if (
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
) {
|
|
454
|
-
nextTemplateItem =
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
462
|
+
if (
|
|
463
|
+
vOffset != 0 &&
|
|
464
|
+
moveType & FocusMoveType.ROW_FIND_NEAR
|
|
465
|
+
) {
|
|
466
|
+
let rowNear = this._GetDirectionNearItem(itemIndex, vOffset > 0 ? "bottom" : "top");
|
|
467
|
+
if (rowNear) {
|
|
468
|
+
nextTemplateItem = rowNear;
|
|
469
|
+
}
|
|
470
|
+
} else if (
|
|
471
|
+
hOffset != 0 &&
|
|
472
|
+
moveType & FocusMoveType.COLUMN_FIND_NEAR
|
|
473
|
+
) {
|
|
474
|
+
let colNear = this._GetDirectionNearItem(itemIndex, hOffset > 0 ? "right" : "left");
|
|
475
|
+
if (colNear) {
|
|
476
|
+
nextTemplateItem = colNear;
|
|
460
477
|
}
|
|
461
478
|
}
|
|
462
479
|
|
|
463
480
|
return nextTemplateItem;
|
|
464
481
|
}
|
|
465
482
|
|
|
483
|
+
private _GetDirectionNearItem(index: number, direction: string, mustFocusable: boolean = true) {
|
|
484
|
+
const SEARCH_RANGE = 100;
|
|
485
|
+
let searchMin = Math.max(0, index - SEARCH_RANGE);
|
|
486
|
+
let searchMax = Math.min(this.templateList.length - 1, index + SEARCH_RANGE);
|
|
487
|
+
let targetItem = this.templateList[index];
|
|
488
|
+
let tl = left(targetItem);
|
|
489
|
+
let tr = right(targetItem);
|
|
490
|
+
let tt = top(targetItem);
|
|
491
|
+
let tb = bottom(targetItem);
|
|
492
|
+
let info: {
|
|
493
|
+
item: TemplateItem | null,
|
|
494
|
+
minMainDistance: number,
|
|
495
|
+
minSubDistance: number,
|
|
496
|
+
} = {
|
|
497
|
+
item: null,
|
|
498
|
+
minMainDistance: -1,
|
|
499
|
+
minSubDistance: -1,
|
|
500
|
+
};
|
|
501
|
+
const compare = (item: TemplateItem, getMainDistance: (i: TemplateItem) => number, getSubDistance: (i: TemplateItem) => number) => {
|
|
502
|
+
if (mustFocusable && !item.focusable) return;
|
|
503
|
+
const mainDistance = getMainDistance(item);
|
|
504
|
+
if (mainDistance <= 0) return;
|
|
505
|
+
const subDistance = getSubDistance(item);
|
|
506
|
+
if (info.minMainDistance < 0 || mainDistance < info.minMainDistance) {
|
|
507
|
+
info.minMainDistance = mainDistance;
|
|
508
|
+
info.minSubDistance = subDistance;
|
|
509
|
+
info.item = item;
|
|
510
|
+
} else if (mainDistance === info.minMainDistance && subDistance < info.minSubDistance) {
|
|
511
|
+
info.minSubDistance = subDistance;
|
|
512
|
+
info.item = item;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
for (let i = searchMin; i <= searchMax; i++) {
|
|
517
|
+
const item = this.templateList[i];
|
|
518
|
+
let il = left(item);
|
|
519
|
+
let ir = right(item);
|
|
520
|
+
let it = top(item);
|
|
521
|
+
let ib = bottom(item);
|
|
522
|
+
switch(direction) {
|
|
523
|
+
case "left":
|
|
524
|
+
compare(item,
|
|
525
|
+
(item) => {return tl - il},
|
|
526
|
+
(item) => {
|
|
527
|
+
return Math.min(Math.abs(tt - it), Math.abs(tb - ib), Math.abs(tt - ib), Math.abs(tb - it));
|
|
528
|
+
});
|
|
529
|
+
break;
|
|
530
|
+
case "right":
|
|
531
|
+
compare(item,
|
|
532
|
+
(item) => {return ir - tr},
|
|
533
|
+
(item) => {return Math.min(Math.abs(tt - it), Math.abs(tb - ib), Math.abs(tt - ib), Math.abs(tb - it));});
|
|
534
|
+
break;
|
|
535
|
+
case "top":
|
|
536
|
+
compare(item,
|
|
537
|
+
(item) => {return tt - it},
|
|
538
|
+
(item) => {return Math.min(Math.abs(tl - il), Math.abs(tr - ir), Math.abs(tl - ir), Math.abs(tr - il));});
|
|
539
|
+
break;
|
|
540
|
+
case "bottom":
|
|
541
|
+
compare(item,
|
|
542
|
+
(item) => {return ib - tb},
|
|
543
|
+
(item) => {return Math.min(Math.abs(tl - il), Math.abs(tr - ir), Math.abs(tl - ir), Math.abs(tr - il));});
|
|
544
|
+
break;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return info.item;
|
|
548
|
+
}
|
|
549
|
+
|
|
466
550
|
|
|
467
551
|
private getNextItemInner(index: number, offset: number,
|
|
468
552
|
vertical: boolean, useHistory: boolean, checkAnchor: number = -1): any {
|
|
@@ -666,6 +750,22 @@ class CommonMetroTemplate extends MetroTemplate {
|
|
|
666
750
|
return nearestIndex;
|
|
667
751
|
}
|
|
668
752
|
|
|
753
|
+
private _FindNearestByDirection(itemIndexList: Array<number>, direction: string) {
|
|
754
|
+
return itemIndexList.reduce((acc, cur) => {
|
|
755
|
+
const curItem = this.templateList[cur];
|
|
756
|
+
const accItem = this.templateList[acc];
|
|
757
|
+
if(direction == "left") {
|
|
758
|
+
return curItem.left < accItem.left ? cur : acc;
|
|
759
|
+
} else if (direction == "right") {
|
|
760
|
+
return curItem.left + curItem.width > accItem.left + accItem.width ? cur : acc;
|
|
761
|
+
} else if (direction == "top") {
|
|
762
|
+
return curItem.top < accItem.top ? cur : acc;
|
|
763
|
+
} else {
|
|
764
|
+
return curItem.top + curItem.height > accItem.top + accItem.height ? cur : acc;
|
|
765
|
+
}
|
|
766
|
+
}, itemIndexList[0]);
|
|
767
|
+
}
|
|
768
|
+
|
|
669
769
|
private _GetNextLoopItem(index: number, offset: number, isVertical: boolean): TemplateItem | null {
|
|
670
770
|
const templateList = this.templateList;
|
|
671
771
|
const baseItem = templateList[index];
|
|
@@ -679,75 +779,46 @@ class CommonMetroTemplate extends MetroTemplate {
|
|
|
679
779
|
let focusableTarget = -1;
|
|
680
780
|
let startIndex = -1;
|
|
681
781
|
let neighborList = [];
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
782
|
+
//目前的算法针对规整的列表, 瀑布流这种不对齐, 以及列表中存在非focusable项, 行为不可控
|
|
783
|
+
|
|
784
|
+
let curIndex = index;
|
|
785
|
+
let nextLevelNeighborList = this._GetTotalNeighbor(curIndex, startDirection);
|
|
786
|
+
while (!nextLevelNeighborList || nextLevelNeighborList.length == 0) {
|
|
787
|
+
//查询同级的邻居
|
|
788
|
+
const sameLevelList = this._GetTotalNeighbor(curIndex, searchDirection);
|
|
789
|
+
if (sameLevelList.length > 0) {
|
|
790
|
+
//找最边缘的同级邻居
|
|
791
|
+
const i = this._FindNearestByDirection(sameLevelList, startDirection);
|
|
792
|
+
nextLevelNeighborList = this._GetTotalNeighbor(i, startDirection);
|
|
793
|
+
curIndex = i;
|
|
794
|
+
} else {
|
|
795
|
+
//没有同级邻居, 返回null
|
|
796
|
+
return null;
|
|
693
797
|
}
|
|
694
798
|
}
|
|
695
|
-
if (startIndex >= 0) {
|
|
696
|
-
neighborList = this._GetTotalNeighbor(startIndex, startDirection);
|
|
697
|
-
|
|
698
|
-
//寻找最近的neighbor
|
|
699
|
-
let nearestIndex = -1,
|
|
700
|
-
minDistance = Number.POSITIVE_INFINITY;
|
|
701
|
-
for (let i of neighborList) {
|
|
702
|
-
const d = this._GetItemDistance(templateList[i], baseItem);
|
|
703
|
-
if (d < minDistance) {
|
|
704
|
-
nearestIndex = i;
|
|
705
|
-
minDistance = d;
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
799
|
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
if (
|
|
713
|
-
focusableTarget =
|
|
800
|
+
if (nextLevelNeighborList && nextLevelNeighborList.length > 0) {
|
|
801
|
+
for (let i of nextLevelNeighborList) {
|
|
802
|
+
const item = templateList[i];
|
|
803
|
+
if (item.focusable) {
|
|
804
|
+
focusableTarget = i;
|
|
805
|
+
startIndex = i;
|
|
806
|
+
break;
|
|
714
807
|
}
|
|
715
|
-
neighborList = this._GetTotalNeighbor(targetIndex, searchDirection);
|
|
716
|
-
}
|
|
717
|
-
if (focusableTarget >= 0) {
|
|
718
|
-
return templateList[focusableTarget];
|
|
719
|
-
} else if (targetIndex >= 0) {
|
|
720
|
-
return this._GetNextLoopItem(targetIndex, offset, isVertical);
|
|
721
808
|
}
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
let startDirection = isVertical ? "top" : "left";
|
|
731
|
-
if (offset > 0) {
|
|
732
|
-
searchDirection = isVertical ? "left" : "top";
|
|
733
|
-
startDirection = isVertical ? "bottom" : "right";
|
|
734
|
-
}
|
|
735
|
-
let startIndex = -1;
|
|
736
|
-
let neighborList = [];
|
|
737
|
-
//寻找下一列的起始item
|
|
738
|
-
neighborList = this._GetTotalNeighbor(index, searchDirection);
|
|
739
|
-
while (startIndex < 0 && neighborList.length > 0) {
|
|
740
|
-
for (let i of neighborList) {
|
|
741
|
-
const n = this._GetTotalNeighbor(i, startDirection);
|
|
742
|
-
if (n.length > 0) {
|
|
743
|
-
return templateList[this._GetNearestItem(index, n)];
|
|
744
|
-
} else {
|
|
745
|
-
//TODO 是否要用递归
|
|
746
|
-
neighborList = this._GetTotalNeighbor(i, searchDirection);
|
|
809
|
+
neighborList = this._GetTotalNeighbor(startIndex, searchDirection);
|
|
810
|
+
while (neighborList.length > 0) {
|
|
811
|
+
for (let i of neighborList) {
|
|
812
|
+
const item = templateList[i];
|
|
813
|
+
if (item.focusable) {
|
|
814
|
+
focusableTarget = i;
|
|
815
|
+
break;
|
|
816
|
+
}
|
|
747
817
|
}
|
|
818
|
+
neighborList = this._GetTotalNeighbor(focusableTarget, searchDirection);
|
|
748
819
|
}
|
|
749
820
|
}
|
|
750
|
-
return null;
|
|
821
|
+
return focusableTarget >= 0 ? templateList[focusableTarget] : null;
|
|
751
822
|
}
|
|
752
823
|
|
|
753
824
|
public updateItemSize(index: number, newSize: { width: number, height: number }): void {
|
|
@@ -225,11 +225,13 @@ export class SeamlessSlide extends SlideSetting {
|
|
|
225
225
|
* easing: 滚动动画的easing
|
|
226
226
|
* boundaryProtect: 确定滚动位置能否小于0或者大于最大长度
|
|
227
227
|
* fixFirstPage: 首页不滚动
|
|
228
|
+
* align: 对齐方式 start, center, end
|
|
228
229
|
* }
|
|
229
230
|
**/
|
|
230
231
|
export class FixPositionSlide extends SlideSetting {
|
|
231
232
|
public readonly FixPercent: number;
|
|
232
233
|
public readonly FixFirstPage: boolean;
|
|
234
|
+
public readonly Align: "start" | "center" | "end";
|
|
233
235
|
|
|
234
236
|
constructor({
|
|
235
237
|
fixPercent = .5,
|
|
@@ -237,11 +239,21 @@ export class FixPositionSlide extends SlideSetting {
|
|
|
237
239
|
duration = null,
|
|
238
240
|
easing = defaultEasing,
|
|
239
241
|
fixFirstPage = false,
|
|
242
|
+
align = "center",
|
|
240
243
|
boundaryProtect = SlideSetting.START_PROTECT | SlideSetting.END_PROTECT,
|
|
244
|
+
}: {
|
|
245
|
+
fixPercent?: number;
|
|
246
|
+
speed?: number;
|
|
247
|
+
duration?: number | null;
|
|
248
|
+
easing?: string;
|
|
249
|
+
fixFirstPage?: boolean;
|
|
250
|
+
align?: "start" | "center" | "end";
|
|
251
|
+
boundaryProtect?: number;
|
|
241
252
|
} = {}) {
|
|
242
253
|
super(SlideSetting.Type.FIX_POSITION, speed, duration, easing, boundaryProtect);
|
|
243
254
|
this.FixPercent = fixPercent;
|
|
244
255
|
this.FixFirstPage = fixFirstPage;
|
|
256
|
+
this.Align = align;
|
|
245
257
|
}
|
|
246
258
|
}
|
|
247
259
|
|
|
@@ -17,12 +17,16 @@ export default {
|
|
|
17
17
|
methods: {
|
|
18
18
|
onRefProxy(audio_ref) {
|
|
19
19
|
if (audio_ref != null) {
|
|
20
|
+
// 扩展浏览器端缺少的接口
|
|
20
21
|
audio_ref.closeScreenSaver = () => {
|
|
21
22
|
//浏览器端仅提供接口, 不实现功能
|
|
22
23
|
};
|
|
23
24
|
audio_ref.openScreenSaver = () => {
|
|
24
25
|
//浏览器端仅提供接口, 不实现功能
|
|
25
26
|
};
|
|
27
|
+
audio_ref.unload = () => {
|
|
28
|
+
audio_ref.src = "";
|
|
29
|
+
}
|
|
26
30
|
}
|
|
27
31
|
this.audioRef = audio_ref;
|
|
28
32
|
// 不在此直接回调 onRef,因为onRefProxy可能会因为 .src的设置导致重新触发一次调用(vue本身问题)
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :style="{ width: 1, height: 1 }" backgroundColor="rgba(0,0,0,1)"></div>
|
|
3
3
|
</template>
|
|
4
|
-
<script
|
|
4
|
+
<script>
|
|
5
5
|
export default {
|
|
6
6
|
props: {
|
|
7
7
|
/**
|
|
8
8
|
* 回调函数,播放器对象通知接口
|
|
9
9
|
* @param {Object} video对象,可以通过此video对象调用video相关属性和方法,具体属性和方法定义见JsvMedia.js文件里相关说明。
|
|
10
10
|
*/
|
|
11
|
-
onRef: { type: Function, default: () => {
|
|
11
|
+
onRef: { type: Function, default: () => {} },
|
|
12
12
|
/**
|
|
13
13
|
* 属性,Boolean类型,true表示自动播放,默认false。
|
|
14
14
|
*/
|
|
@@ -94,8 +94,8 @@ export default {
|
|
|
94
94
|
*/
|
|
95
95
|
preDownload: {
|
|
96
96
|
type: Boolean,
|
|
97
|
-
default: false
|
|
98
|
-
}
|
|
97
|
+
default: false,
|
|
98
|
+
},
|
|
99
99
|
},
|
|
100
100
|
setup() {
|
|
101
101
|
return {
|
|
@@ -103,7 +103,7 @@ export default {
|
|
|
103
103
|
};
|
|
104
104
|
},
|
|
105
105
|
mounted() {
|
|
106
|
-
this.Jsvinit()
|
|
106
|
+
this.Jsvinit();
|
|
107
107
|
},
|
|
108
108
|
|
|
109
109
|
beforeUnmount() {
|
|
@@ -112,7 +112,7 @@ export default {
|
|
|
112
112
|
this.audio.releaseResource?.();
|
|
113
113
|
this.audio.onPlatformDestroy?.();
|
|
114
114
|
this.onRef?.(null);
|
|
115
|
-
this.unregisterOnVisibilityChange()
|
|
115
|
+
this.unregisterOnVisibilityChange();
|
|
116
116
|
}
|
|
117
117
|
},
|
|
118
118
|
|
|
@@ -123,7 +123,7 @@ export default {
|
|
|
123
123
|
this.audio.addEventListener("error", this.onError);
|
|
124
124
|
this.audio.addEventListener("loadstart", this.onLoadStart);
|
|
125
125
|
this.audio.addEventListener("loadedmetadata", this.onLoadedMetaData);
|
|
126
|
-
this.audio.addEventListener("
|
|
126
|
+
this.audio.addEventListener("loadeddata", this.onLoad); // html标准的loadeddata事件相当于jsview的onLoad
|
|
127
127
|
this.audio.addEventListener("audiofocusloss", this.onAudioFocusLoss);
|
|
128
128
|
this.audio.addEventListener("audiofocusgain", this.onAudioFocusGain);
|
|
129
129
|
}
|
|
@@ -157,19 +157,19 @@ export default {
|
|
|
157
157
|
onJsViewShow() {
|
|
158
158
|
//重新加载
|
|
159
159
|
if (!this.audio) {
|
|
160
|
-
this.Jsvinit()
|
|
160
|
+
this.Jsvinit();
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
if (this.stopByOnHide) {
|
|
164
164
|
this.stopByOnHide = false;
|
|
165
|
-
this.Jsvinit()
|
|
165
|
+
this.Jsvinit();
|
|
166
166
|
}
|
|
167
167
|
},
|
|
168
168
|
Jsvinit() {
|
|
169
169
|
this.audio = new Audio();
|
|
170
170
|
this.registerEvent();
|
|
171
171
|
if (this.src && this.src !== "") {
|
|
172
|
-
let realUrl
|
|
172
|
+
let realUrl;
|
|
173
173
|
if (window.JsView) {
|
|
174
174
|
// jsview上
|
|
175
175
|
realUrl = new window.JsView.Dom.UrlRef(this.src).href;
|
|
@@ -200,10 +200,10 @@ export default {
|
|
|
200
200
|
this.audio.confirmInitSetup?.();
|
|
201
201
|
}
|
|
202
202
|
});
|
|
203
|
-
this.registerOnVisibilityChange()
|
|
204
|
-
}
|
|
203
|
+
this.registerOnVisibilityChange();
|
|
204
|
+
},
|
|
205
205
|
},
|
|
206
206
|
};
|
|
207
207
|
</script>
|
|
208
208
|
|
|
209
|
-
<style lang="scss" scoped></style>
|
|
209
|
+
<style lang="scss" scoped></style>
|
|
@@ -493,7 +493,7 @@ export default {
|
|
|
493
493
|
this.video.addEventListener("canplaythrough", this.onCanPlayThrough);
|
|
494
494
|
this.video.addEventListener("progress", this.onProgress);
|
|
495
495
|
this.video.addEventListener("loadedmetadata", this.onLoadedMetaData);
|
|
496
|
-
this.video.addEventListener("
|
|
496
|
+
this.video.addEventListener("loadeddata", this.onLoad);
|
|
497
497
|
this.video.addEventListener("durationchange", this.onDurationChange);
|
|
498
498
|
this.video.addEventListener("seeking", this.onSeeking);
|
|
499
499
|
this.video.addEventListener("seeked", this.onSeeked);
|
|
@@ -53,7 +53,8 @@ function JsvUseFeature(from: String, comp_name: String) {
|
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
// 未激活简易提示, need JsvActiveFeature(JsvFeatureNames.${ comp_name }) in boot`);
|
|
57
|
+
console.log(`LOG: ${comp_name}(from ${from}) is not activated`);
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
// 备用接口: 防止未授权组件被错误激活引起的崩溃和水印显示
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
let handles: {
|
|
2
2
|
TextureManager: any,
|
|
3
3
|
RootView: any,
|
|
4
|
-
RootActivity: any
|
|
4
|
+
RootActivity: any,
|
|
5
|
+
sRenderBridge: any
|
|
5
6
|
} = {
|
|
6
7
|
TextureManager: null,
|
|
7
8
|
RootView: null,
|
|
8
|
-
RootActivity: null
|
|
9
|
+
RootActivity: null,
|
|
10
|
+
sRenderBridge: null
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
const jsvCode = (window as any).JsvCode;
|
|
@@ -13,6 +15,7 @@ jsvCode.ForgeHandles.listenToReady(() => {
|
|
|
13
15
|
handles.TextureManager = jsvCode.ForgeHandles.TextureManager;
|
|
14
16
|
handles.RootView = jsvCode.ForgeHandles.RootView;
|
|
15
17
|
handles.RootActivity = jsvCode.ForgeHandles.RootActivity;
|
|
18
|
+
handles.sRenderBridge = jsvCode.ForgeHandles.sRenderBridge;
|
|
16
19
|
})
|
|
17
20
|
|
|
18
21
|
export default handles;
|