@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.
Files changed (56) hide show
  1. package/bin/browser/BrowserAudio.vue.mjs +4 -1
  2. package/bin/jsview-vue.mjs +2200 -466
  3. package/bin/types/utils/JsViewEngineWidget/JsvFocus/JsvFocusHub.d.ts +21 -1
  4. package/bin/types/utils/JsViewEngineWidget/MetroWidget/RenderItem.d.ts +5 -1
  5. package/bin/types/utils/JsViewEngineWidget/TemplateParser/CommonMetroTemplate.d.ts +2 -1
  6. package/bin/types/utils/JsViewEngineWidget/WidgetCommon.d.ts +10 -7
  7. package/bin/types/utils/JsViewVueTools/ForgeHandles.d.ts +1 -0
  8. package/bin/types/utils/JsViewVueTools/JsvRuntimeBridge.d.ts +37 -1
  9. package/bin/types/utils/JsViewVueTools/JsvTextureStore/CapturedTexture/CapturedTexture.d.ts +3 -3
  10. package/bin/types/utils/JsViewVueTools/JsvTextureStore/DominantColor/GetDominantColor.d.ts +7 -0
  11. package/bin/types/utils/JsViewVueTools/JsvTextureStore/JsvTextureStore.d.ts +14 -1
  12. package/bin/types/utils/JsViewVueTools/JsvTextureStore/Store.d.ts +2 -0
  13. package/bin/types/utils/JsViewVueTools/JsvTextureStore/Texture.d.ts +4 -0
  14. package/bin/types/utils/JsViewVueWidget/JsvDashPath.vue.d.ts +11 -0
  15. package/bin/types/utils/JsViewVueWidget/JsvFragShaderView/JsvFragShaderView.vue.d.ts +2 -1
  16. package/bin/types/utils/JsViewVueWidget/JsvSmoothSlideContainer.vue.d.ts +72 -0
  17. package/bin/types/utils/JsViewVueWidget/JsvSoundPool.d.ts +26 -0
  18. package/bin/types/utils/JsViewVueWidget/JsvSwiper/JsvSmoothSwiper.vue.d.ts +112 -0
  19. package/bin/types/utils/JsViewVueWidget/JsvSwiper/JsvSwiper2.vue.d.ts +142 -0
  20. package/bin/types/utils/JsViewVueWidget/JsvSwiper/index.d.ts +3 -1
  21. package/bin/types/utils/JsViewVueWidget/JsvTextureAnim/JsvTextureAnim.vue.d.ts +2 -2
  22. package/bin/types/utils/JsViewVueWidget/index.d.ts +2 -1
  23. package/package.json +1 -1
  24. package/utils/JsViewEngineWidget/JsvFocus/JsvFocusHub.ts +27 -1
  25. package/utils/JsViewEngineWidget/MetroWidget/MetroWidget.vue +35 -3
  26. package/utils/JsViewEngineWidget/MetroWidget/MetroWidgetSetup.js +736 -386
  27. package/utils/JsViewEngineWidget/MetroWidget/RenderItem.ts +13 -2
  28. package/utils/JsViewEngineWidget/MetroWidget/TaskManager.ts +38 -26
  29. package/utils/JsViewEngineWidget/TemplateParser/CommonMetroTemplate.ts +144 -73
  30. package/utils/JsViewEngineWidget/WidgetCommon.ts +12 -0
  31. package/utils/JsViewPlugin/JsvAudio/BrowserAudio/BrowserAudio.vue +4 -0
  32. package/utils/JsViewPlugin/JsvAudio/BrowserAudio/JsvSystemAudio.vue +13 -13
  33. package/utils/JsViewPlugin/JsvPlayer/BrowserJsvPlayer.vue +1 -1
  34. package/utils/JsViewVueTools/FeatureActive.ts +2 -1
  35. package/utils/JsViewVueTools/ForgeHandles.ts +5 -2
  36. package/utils/JsViewVueTools/JsvRuntimeBridge.js +97 -1
  37. package/utils/JsViewVueTools/JsvTextTools.ts +3 -1
  38. package/utils/JsViewVueTools/JsvTextureStore/CapturedTexture/CapturedTexture.ts +15 -12
  39. package/utils/JsViewVueTools/JsvTextureStore/DominantColor/GetDominantColor.ts +36 -0
  40. package/utils/JsViewVueTools/JsvTextureStore/JsvTextureStore.ts +23 -2
  41. package/utils/JsViewVueTools/JsvTextureStore/Store.ts +33 -21
  42. package/utils/JsViewVueTools/JsvTextureStore/Texture.ts +56 -41
  43. package/utils/JsViewVueWidget/JsvDashPath.vue +150 -0
  44. package/utils/JsViewVueWidget/JsvFlexCell/JsvFullScrAdjust.vue +3 -1
  45. package/utils/JsViewVueWidget/JsvFragShaderView/JsvFragShaderView.vue +26 -22
  46. package/utils/JsViewVueWidget/JsvFreeMoveActor/SetAction.ts +1 -1
  47. package/utils/JsViewVueWidget/JsvInput/JsvInput.vue +1 -0
  48. package/utils/JsViewVueWidget/JsvPreload/JsvPreload.vue +2 -2
  49. package/utils/JsViewVueWidget/JsvSmoothSlideContainer.vue +108 -0
  50. package/utils/JsViewVueWidget/JsvSoundPool.js +75 -12
  51. package/utils/JsViewVueWidget/JsvSwiper/JsvSmoothSwiper.vue +543 -0
  52. package/utils/JsViewVueWidget/JsvSwiper/JsvSwiper.vue +3 -3
  53. package/utils/JsViewVueWidget/JsvSwiper/JsvSwiper2.vue +644 -0
  54. package/utils/JsViewVueWidget/JsvSwiper/index.js +3 -1
  55. package/utils/JsViewVueWidget/JsvTextureAnim/JsvTextureAnim.vue +14 -8
  56. 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.onClick.bind(this) : null;
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(Math.max(Math.abs(to[0] - from[0]), Math.abs(to[1] - from[1])) / setting.speed);
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(this.onStart.bind(this), this.onEnd.bind(this), null)
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(element: any, from: [number, number], to: [number, number], setting: AnimSetting) {
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 (nextTemplateItem === null) {
449
- // 临近行的焦点移动
450
- if (
451
- vOffset != 0 &&
452
- moveType & FocusMoveType.ROW_FIND_NEAR
453
- ) {
454
- nextTemplateItem = this._GetNearLineItem(itemIndex, vOffset, true);
455
- } else if (
456
- hOffset != 0 &&
457
- moveType & FocusMoveType.COLUMN_FIND_NEAR
458
- ) {
459
- nextTemplateItem = this._GetNearLineItem(itemIndex, hOffset, false);
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
- //寻找下一列的起始item
683
- neighborList = this._GetTotalNeighbor(index, searchDirection);
684
- while (startIndex < 0 && neighborList.length > 0) {
685
- for (let i of neighborList) {
686
- if (this._GetTotalNeighbor(i, startDirection).length > 0) {
687
- startIndex = i;
688
- break;
689
- } else {
690
- //TODO 是否要用递归
691
- neighborList = this._GetTotalNeighbor(i, searchDirection);
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
- neighborList = this._GetTotalNeighbor(nearestIndex, searchDirection);
710
- while (neighborList.length > 0) {
711
- targetIndex = this._GetNearestItem(nearestIndex, neighborList);
712
- if (templateList[targetIndex].focusable) {
713
- focusableTarget = targetIndex;
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
- return null;
724
- }
725
-
726
- //获取临近行的item
727
- private _GetNearLineItem(index: number, offset: number, isVertical: boolean) {
728
- const templateList = this.templateList;
729
- let searchDirection = isVertical ? "right" : "bottom";
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("load", this.onLoad);
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("load", this.onLoad);
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
- console.error(`Error: ${comp_name}(from ${from}) is not activated, need JsvActiveFeature(JsvFeatureNames.${comp_name}) in boot`);
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;