@shijiu/jsview-vue-samples 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 (117) hide show
  1. package/DashPath/App.vue +17 -16
  2. package/DashPath/AppForOperator.vue +2 -4
  3. package/DemoForOperator/AnimPic/AnimPic.vue +24 -2
  4. package/DemoForOperator/Banger/Banger/Banger.vue +73 -9
  5. package/DemoForOperator/Blur/Blur.vue +146 -0
  6. package/DemoForOperator/Blur/BlurInOut/BlurInOut.vue +158 -0
  7. package/DemoForOperator/Blur/BlurInOut/StaticBgSlide.vue +162 -0
  8. package/DemoForOperator/Blur/BlurPopup/BlurPopup.vue +113 -0
  9. package/DemoForOperator/BookFlip/App.vue +115 -0
  10. package/DemoForOperator/BookFlip/BookFlip/FlipPage.vue +179 -0
  11. package/DemoForOperator/BookFlip/BookFlip/FlippingBook.vue +310 -0
  12. package/DemoForOperator/BookFlip/BookFlip/flip.glsl +135 -0
  13. package/DemoForOperator/BookFlip/BookPage.vue +82 -0
  14. package/DemoForOperator/Bounce/Bounce.vue +33 -1
  15. package/DemoForOperator/ChunLian/Couplets.vue +44 -1
  16. package/DemoForOperator/ClickSpriteAnim/App.vue +130 -0
  17. package/DemoForOperator/ClickSpriteAnim/Item.vue +74 -0
  18. package/DemoForOperator/DominantColor/App.vue +187 -0
  19. package/DemoForOperator/EpisodeList/EpisodeList/Controller.vue +0 -3
  20. package/DemoForOperator/EpisodeList/EpisodeList/EpisodeList.vue +76 -2
  21. package/DemoForOperator/Firework1/App.vue +1 -1
  22. package/DemoForOperator/Firework1/Fireworks.vue +50 -11
  23. package/DemoForOperator/FlipPage/FlipPage/FlipPage.vue +29 -1
  24. package/DemoForOperator/Focus/Alpha/AlphaFocusBox.vue +27 -2
  25. package/DemoForOperator/Focus/Light/LightFocusBox.vue +42 -1
  26. package/DemoForOperator/Focus/Normal/NormalFocusBox.vue +12 -0
  27. package/DemoForOperator/FrameShadow/App.vue +193 -0
  28. package/DemoForOperator/FrameShadow/FrameShadow.vue +61 -0
  29. package/DemoForOperator/FullscreenIn/App.vue +1 -1
  30. package/DemoForOperator/FullscreenIn/FullscreenPoster.vue +18 -3
  31. package/DemoForOperator/Genie/geniePakcer/Genie.vue +60 -18
  32. package/DemoForOperator/GrayFilter/GrayFilter.vue +21 -0
  33. package/DemoForOperator/Jigsaw/JigsawFull.vue +46 -4
  34. package/DemoForOperator/Jigsaw/JigsawSingle.vue +34 -2
  35. package/DemoForOperator/LongChatBox/App.vue +36 -0
  36. package/DemoForOperator/LongChatBox/Bubble.vue +104 -0
  37. package/DemoForOperator/LongChatBox/LongChat.vue +173 -0
  38. package/DemoForOperator/LongChatBox/TextManager.ts +147 -0
  39. package/DemoForOperator/LongChatBox/VirtualList.vue +298 -0
  40. package/DemoForOperator/LongChatBox/testData.js +51 -0
  41. package/DemoForOperator/LongChatBox/utile.js +331 -0
  42. package/DemoForOperator/Particle/Drop/DropParticle.vue +33 -1
  43. package/DemoForOperator/Particle/Explode/ExplodeParticle.vue +23 -2
  44. package/DemoForOperator/PosterAnim/PosterAnim.js +21 -0
  45. package/DemoForOperator/PosterOverflow/PosterOverflow.vue +16 -0
  46. package/DemoForOperator/Resize/App.vue +157 -0
  47. package/DemoForOperator/Resize/Resize/Item.vue +234 -0
  48. package/DemoForOperator/Resize/Resize/Resize.vue +96 -0
  49. package/DemoForOperator/Ripple/Ripple.vue +16 -1
  50. package/DemoForOperator/ScreenShootScale/App.vue +96 -0
  51. package/DemoForOperator/ScreenShootScale/Back.vue +86 -0
  52. package/DemoForOperator/ScreenShootScale/Front.vue +133 -0
  53. package/DemoForOperator/ScreenShootScale/Item.vue +62 -0
  54. package/DemoForOperator/ScreenShootScale/ScreenShootScale.vue +109 -0
  55. package/DemoForOperator/SmoothSwiper/App.vue +50 -0
  56. package/DemoForOperator/Sound/Bounce/App.vue +56 -0
  57. package/DemoForOperator/Sound/Bounce/Bounce.vue +87 -0
  58. package/DemoForOperator/Sound/Bounce/FreeMoveBuilder.js +146 -0
  59. package/DemoForOperator/Sound/Bounce/bgmusic.mp3 +0 -0
  60. package/DemoForOperator/Sound/Bounce/coin.mp3 +0 -0
  61. package/DemoForOperator/Sound/FocusMove/App.vue +134 -0
  62. package/DemoForOperator/Sound/FocusMove/Item.vue +43 -0
  63. package/DemoForOperator/Sound/FocusMove/move.mp3 +0 -0
  64. package/DemoForOperator/Sound/Rain/App.vue +11 -0
  65. package/DemoForOperator/Sound/Rain/Raining/Rain.vue +69 -0
  66. package/DemoForOperator/Sound/Rain/Raining/RainScene.vue +118 -0
  67. package/DemoForOperator/Sound/Sound/Sound.vue +24 -0
  68. package/DemoForOperator/Sound/Sound/index.js +4 -0
  69. package/DemoForOperator/Sound/Sound/useSound.js +112 -0
  70. package/DemoForOperator/Sprite/Sprite.vue +62 -5
  71. package/DemoForOperator/Stretch/Stretch/Stretch.vue +52 -2
  72. package/DemoForOperator/Swiper/App.vue +101 -0
  73. package/DemoForOperator/Swiper/Item.vue +56 -0
  74. package/DemoForOperator/Swiper/ParallaxSlide.vue +164 -0
  75. package/DemoForOperator/TabContent/TabContent/TabContent.vue +39 -1
  76. package/DemoForOperator/TabContentVertical/App.vue +104 -0
  77. package/DemoForOperator/TabContentVertical/ContentPage.vue +67 -0
  78. package/DemoForOperator/TabContentVertical/Item.vue +94 -0
  79. package/DemoForOperator/TabContentVertical/PageItem.vue +40 -0
  80. package/DemoForOperator/TabContentVertical/TabContent/CreepFocus.vue +160 -0
  81. package/DemoForOperator/TabContentVertical/TabContent/Item.vue +63 -0
  82. package/DemoForOperator/TabContentVertical/TabContent/TabContent.vue +184 -0
  83. package/DemoForOperator/TabContentVertical/TabContent/TabItem.vue +368 -0
  84. package/DemoForOperator/TabContentVertical/TabContent/TabWidget.vue +259 -0
  85. package/DemoForOperator/TabContentVertical/TabContent/Util.js +3 -0
  86. package/DemoForOperator/TabContentVertical/TabContent/ViewSwiper.vue +110 -0
  87. package/DemoForOperator/TabContentVertical/assets/children_science.png +0 -0
  88. package/DemoForOperator/TabContentVertical/assets/documentary.png +0 -0
  89. package/DemoForOperator/TabContentVertical/assets/free.png +0 -0
  90. package/DemoForOperator/TabContentVertical/assets/game.png +0 -0
  91. package/DemoForOperator/TabContentVertical/assets/home_selected.png +0 -0
  92. package/DemoForOperator/TabContentVertical/assets/movie_ticket.png +0 -0
  93. package/DemoForOperator/TabContentVertical/assets/my_account.png +0 -0
  94. package/DemoForOperator/TabContentVertical/assets/opera.png +0 -0
  95. package/DemoForOperator/TabContentVertical/assets/sports.png +0 -0
  96. package/DemoForOperator/TabContentVertical/assets/tv_drama.png +0 -0
  97. package/DemoForOperator/TabContentVertical/assets/variety_show.png +0 -0
  98. package/DemoForOperator/TabContentVertical/assets/vip.png +0 -0
  99. package/DemoForOperator/TabContentVertical/testData.js +76 -0
  100. package/DemoForOperator/Vortex/Vortex/Vortex.vue +26 -0
  101. package/DemoForOperator/routeList.js +118 -1
  102. package/DemoHomepage/components/Item.vue +11 -0
  103. package/DemoHomepage/router.js +75 -1
  104. package/GiftRain/components/SpriteTranslate.vue +68 -48
  105. package/HashHistory/App.vue +2 -2
  106. package/HashHistory/router.js +1 -1
  107. package/MetroWidgetDemos/TripleWidget/App.vue +7 -1
  108. package/MetroWidgetDemos/TripleWidget/Item.vue +16 -2
  109. package/MetroWidgetDemos/TripleWidget/SWidgetItem.vue +7 -1
  110. package/MetroWidgetDemos/TripleWidget/WidgetItem.vue +8 -2
  111. package/MetroWidgetDemos/routeList.js +17 -0
  112. package/PosterPacker/App.vue +2 -2
  113. package/ViewOpacity/App.vue +19 -0
  114. package/package.json +1 -1
  115. package/DashPath/DashPath.vue +0 -118
  116. package/DemoForOperator/ScalePoster/App.vue +0 -4
  117. package/DemoForOperator/ScalePoster/ScalePoster.vue +0 -0
@@ -0,0 +1,164 @@
1
+ <template>
2
+ <jsv-preload
3
+ key="preload"
4
+ :preloadList="[preloadInfo]"
5
+ :onPreloadDone="handlePreloadDone"
6
+ ></jsv-preload>
7
+ <jsv-texture-anim
8
+ v-if="isPreloadDone"
9
+ ref="pandaAnim"
10
+ :src="props.imgUrl"
11
+ :width="props.width"
12
+ :height="props.height"
13
+ :animation="appliedAnim"
14
+ :duration="props.duration"
15
+ :transform="appliedTrans"
16
+ :borderRadius="props.borderRadius"
17
+ :autoStart="false"
18
+ :easing="props.easing"
19
+ :onAnimationEnd="onAnimEnd"
20
+ ></jsv-texture-anim>
21
+ </template>
22
+
23
+ <script setup>
24
+ import { ref, shallowRef, computed } from "vue";
25
+ import { JsvPreload, buildPreloadInfo } from "jsview";
26
+ import { JsvTextureAnim } from "jsview";
27
+
28
+ const props = defineProps({
29
+ imgUrl: {
30
+ type: String,
31
+ required: true,
32
+ },
33
+ width: {
34
+ type: Number,
35
+ required: true,
36
+ },
37
+ height: {
38
+ type: Number,
39
+ required: true,
40
+ },
41
+ collapseWidth: {
42
+ type: Number,
43
+ required: true,
44
+ },
45
+ duration: {
46
+ type: Number,
47
+ default: 200,
48
+ },
49
+ easing: {
50
+ type: String,
51
+ default: "linear",
52
+ },
53
+ borderRadius: {
54
+ type: Number,
55
+ default: 0,
56
+ },
57
+ /**
58
+ * 初始位置
59
+ * @type {"left" | "right" | "center"}
60
+ */
61
+ initPosition: {
62
+ type: String,
63
+ default: "center",
64
+ },
65
+ });
66
+
67
+ const isPreloadDone = ref(false);
68
+ const preloadInfo = buildPreloadInfo(props.imgUrl);
69
+
70
+ const pandaAnim = shallowRef(null);
71
+
72
+ const imageW = ref(0);
73
+ const imageH = ref(0);
74
+ const imageRatio = computed(() => imageW.value / imageH.value);
75
+
76
+ const imageShowWidth = computed(() => props.height * imageRatio.value);
77
+ const offset = computed(() => (imageShowWidth.value - props.width) / 2);
78
+
79
+ const baseScale = computed(
80
+ () => `scale3d(${imageShowWidth.value / props.width}, 1, 1)`
81
+ );
82
+ // const baseScale = computed(
83
+ // () => `rotate3d(0,0,1,45deg)`
84
+ // );
85
+
86
+ const leftTranslate = computed(
87
+ () =>
88
+ `translate3d(${
89
+ ((props.width - props.collapseWidth - -offset.value) / props.width) * 100
90
+ }%, 0, 0) ${baseScale.value}`
91
+ );
92
+ const rightTranslate = computed(
93
+ () =>
94
+ `translate3d(${
95
+ ((-(imageShowWidth.value - props.collapseWidth) - -offset.value) /
96
+ props.width) *
97
+ 100
98
+ }%, 0, 0) ${baseScale.value}`
99
+ );
100
+ const centerTranslate = computed(() => `translate3d(0,0,0) ${baseScale.value}`);
101
+ const curPosition = ref(props.initPosition);
102
+
103
+ const transform = computed(
104
+ () =>
105
+ (curPosition.value === "left"
106
+ ? leftTranslate.value
107
+ : curPosition.value === "right"
108
+ ? rightTranslate.value
109
+ : centerTranslate.value)
110
+ );
111
+ const appliedTrans = ref(null);
112
+ const appliedAnim = ref(null);
113
+
114
+ //TODO JsvPreload 的回调会执行多次,所以需要一个标志来判断是否已经执行过
115
+ let loadDone = false;
116
+ const handlePreloadDone = (resultMap) => {
117
+ if (loadDone) return;
118
+ loadDone = true;
119
+ console.log("ccht 图片预加载完成", resultMap);
120
+ imageW.value = resultMap[props.imgUrl].width;
121
+ imageH.value = resultMap[props.imgUrl].height;
122
+ appliedTrans.value = transform.value;
123
+ isPreloadDone.value = true;
124
+ };
125
+
126
+ let onAnimEnd = (normalEnd) => {
127
+ console.log("ccht 动画结束", transform.value);
128
+ if (normalEnd) {
129
+ appliedTrans.value = transform.value;
130
+ }
131
+ appliedAnim.value = null;
132
+ };
133
+
134
+ let translateMap = {
135
+ left: leftTranslate,
136
+ right: rightTranslate,
137
+ center: centerTranslate,
138
+ };
139
+ /**
140
+ * 滑动
141
+ * @param {"left" | "right" | "center"} to 结束位置
142
+ */
143
+ function slide(to) {
144
+ if (
145
+ curPosition.value === to ||
146
+ (curPosition.value === "left" && to === "right") ||
147
+ (curPosition.value === "right" && to === "left")
148
+ ) {
149
+ console.warn(`滑动失败,当前位置:${curPosition.value},目标位置:${to}`);
150
+ return;
151
+ }
152
+ appliedTrans.value = null;
153
+ appliedAnim.value = `{from {transform: ${
154
+ translateMap[curPosition.value].value
155
+ };} to {transform: ${translateMap[to].value};}}`;
156
+ console.log("ccht slide ", curPosition.value, to, appliedAnim.value);
157
+ curPosition.value = to;
158
+ pandaAnim.value?.start(appliedAnim.value);
159
+ }
160
+
161
+ defineExpose({
162
+ slide,
163
+ });
164
+ </script>
@@ -42,56 +42,79 @@
42
42
  </template>
43
43
 
44
44
  <script setup>
45
+ /**
46
+ * @slot tabItem - 自定义标签项内容
47
+ * @property {Object} data - 当前标签项数据
48
+ * @property {Object} query - 查询参数对象
49
+ * @property {Function} onAction - 动作处理函数
50
+ *
51
+ * @slot content - 自定义内容区域
52
+ * @property {Object} data - 内容区域数据
53
+ * @property {Function} onEdge - 边缘事件处理函数
54
+ */
55
+
45
56
  import TabWidget from "./TabWidget.vue";
46
57
  import ViewSwiper from "./ViewSwiper.vue";
47
58
  import { ref, reactive, provide } from "vue";
48
59
  import { useFocusHub, EdgeDirection } from "jsview";
49
60
 
50
61
  const props = defineProps({
62
+ /** @type {String} 组件唯一标识名称 */
51
63
  name: {
52
64
  type: String,
53
65
  required: true,
54
66
  },
67
+ /** @type {Array} 标签数据源 */
55
68
  data: {
56
69
  type: Array,
57
70
  required: true,
58
71
  },
72
+ /** @type {Object} 标签栏布局配置 */
59
73
  tabLayout: {
60
74
  type: Object,
61
75
  required: true,
62
76
  },
77
+ /** @type {Object} 标签栏内边距配置 */
63
78
  tabPadding: {
64
79
  type: Object,
65
80
  required: true,
66
81
  },
82
+ /** @type {Number} 标签项之间的间隔 */
67
83
  tagItemGap: {
68
84
  type: Number,
69
85
  required: true,
70
86
  },
87
+ /** @type {Object} 内容区域布局配置 */
71
88
  contentLayout: {
72
89
  type: Object,
73
90
  required: true,
74
91
  },
92
+ /** @type {Function} 内容区域数据加载器 */
75
93
  contentDataLoader: {
76
94
  type: Function,
77
95
  required: true,
78
96
  },
97
+ /** @type {Number} 初始聚焦项的ID,默认0 */
79
98
  initFocusId: {
80
99
  type: Number,
81
100
  default: 0,
82
101
  },
102
+ /** @type {Number} 标签文字字体大小,默认30px */
83
103
  tabTextFontSize: {
84
104
  type: Number,
85
105
  default: 30,
86
106
  },
107
+ /** @type {Function} 内容区域获取焦点时的回调 */
87
108
  contentOnFocus: {
88
109
  type: Function,
89
110
  default: () => {},
90
111
  },
112
+ /** @type {Function} 内容区域失去焦点时的回调 */
91
113
  contentOnBlur: {
92
114
  type: Function,
93
115
  default: () => {},
94
- },
116
+ },
117
+ /** @type {String} 聚焦时的颜色,默认#e26c44 */
95
118
  creepFocusColor: {
96
119
  type: String,
97
120
  default: "#e26c44",
@@ -114,11 +137,19 @@ const tabFocus = ref(false);
114
137
  const modeIsKey = () => {
115
138
  return true;
116
139
  };
140
+
141
+ /**
142
+ * 处理组件获取焦点事件
143
+ */
117
144
  function onFocus() {
118
145
  console.log("ccht onFocus", focusName);
119
146
  focusHub.setFocus(focusName);
120
147
  }
121
148
 
149
+ /**
150
+ * 处理标签栏边缘事件
151
+ * @param {Object} edgeInfo - 边缘事件信息
152
+ */
122
153
  function tabOnEdge(edgeInfo) {
123
154
  console.log("testtest tab on edge");
124
155
  if (edgeInfo.direction == EdgeDirection.bottom) {
@@ -127,6 +158,10 @@ function tabOnEdge(edgeInfo) {
127
158
  }
128
159
  }
129
160
 
161
+ /**
162
+ * 处理内容区域边缘事件
163
+ * @param {Object} edgeInfo - 边缘事件信息
164
+ */
130
165
  function contentOnEdge(edgeInfo) {
131
166
  if (edgeInfo.direction == EdgeDirection.top) {
132
167
  focusHub.setFocus(tabName);
@@ -134,6 +169,9 @@ function contentOnEdge(edgeInfo) {
134
169
  }
135
170
  }
136
171
 
172
+ /**
173
+ * 处理按键抬起事件,更新当前标签ID
174
+ */
137
175
  const onDispatchKeyUp = () => {
138
176
  globalInfo.updateTabId = globalInfo.tabId;
139
177
  };
@@ -0,0 +1,104 @@
1
+ <template>
2
+ <div
3
+ :style="{
4
+ width: 1280,
5
+ height: 720,
6
+ backgroundColor: '#007788',
7
+ }"
8
+ ></div>
9
+ <tab-content
10
+ :name="name"
11
+ :data="testData"
12
+ :tabLayout="{ width: 120, height: 650 }"
13
+ :tabPadding="{ left: 20, right: 20, top: 20, height: 20 }"
14
+ :contentLayout="{ left: 140, top: 50, width: 1000, height: 600 }"
15
+ :tabItemGap="30"
16
+ :contentDataLoader="pageDataLoader"
17
+ :initFocusId="2"
18
+ :contentOnFocus="contentOnFocus"
19
+ :contentOnBlur="contentOnBlur"
20
+ creepFocusColor="#e26c44"
21
+ >
22
+ <template #tabItem="{ data, onAction, query }">
23
+ <item :data="data" :onAction="onAction" :query="query"></item>
24
+ </template>
25
+ <template #content="{ data, onEdge }">
26
+ <content-page
27
+ name="contentPage"
28
+ :pageData="data"
29
+ :onEdge="onEdge"
30
+ ></content-page>
31
+ </template>
32
+ </tab-content>
33
+ </template>
34
+
35
+ <script setup>
36
+ import TabContent from "./TabContent/TabContent.vue";
37
+ import { onMounted } from "vue";
38
+ import { useFocusHub } from "jsview";
39
+ /** 注意, tab数据中有子tab的, 子tab的数据必须在childTab字段下, 类似这里的testData */
40
+ import { testData } from "./testData.js";
41
+ import Item from "./Item.vue";
42
+ import ContentPage from "./ContentPage.vue";
43
+
44
+ const focusHub = useFocusHub();
45
+ const name = "tab-content";
46
+
47
+ const ironmanSmall =
48
+ "https://cdn.release.qcast.cn/JsViewFrameworkTester/JsViewVueSampleResources/DemoForOperator/PosterOverflow/App/ironman_small.png";
49
+ const spidermanSmall =
50
+ "https://cdn.release.qcast.cn/JsViewFrameworkTester/JsViewVueSampleResources/DemoForOperator/PosterOverflow/App/spiderman_small.png";
51
+ const captainSmall =
52
+ "https://cdn.release.qcast.cn/JsViewFrameworkTester/JsViewVueSampleResources/DemoForOperator/PosterOverflow/App/captain_small.png";
53
+
54
+ async function pageDataLoader(tabId) {
55
+ return {
56
+ title: "page " + tabId,
57
+ list: [
58
+ {
59
+ width: 360,
60
+ height: 290,
61
+ img: ironmanSmall,
62
+ },
63
+ {
64
+ width: 360,
65
+ height: 290,
66
+ img: spidermanSmall,
67
+ },
68
+ {
69
+ width: 360,
70
+ height: 290,
71
+ img: captainSmall,
72
+ },
73
+ {
74
+ width: 360,
75
+ height: 290,
76
+ img: ironmanSmall,
77
+ },
78
+ {
79
+ width: 360,
80
+ height: 290,
81
+ img: spidermanSmall,
82
+ },
83
+ {
84
+ width: 360,
85
+ height: 290,
86
+ img: captainSmall,
87
+ },
88
+ ],
89
+ };
90
+ }
91
+
92
+ function contentOnFocus() {
93
+ console.log("content on focus");
94
+ focusHub.setFocus("contentPage");
95
+ }
96
+
97
+ function contentOnBlur() {
98
+ console.log("content on blur");
99
+ }
100
+
101
+ onMounted(() => {
102
+ focusHub.setFocus(name);
103
+ });
104
+ </script>
@@ -0,0 +1,67 @@
1
+ <script setup>
2
+ import { MetroWidget, VERTICAL, useFocusHub } from "jsview";
3
+ import { ref, onMounted } from "vue";
4
+ import PageItem from "./PageItem.vue";
5
+
6
+ const props = defineProps({
7
+ pageData: Object,
8
+ name: String,
9
+ onEdge: Function,
10
+ });
11
+
12
+ console.log("content page on edge", props.pageData);
13
+
14
+ const provideData = () => {
15
+ return props.pageData.list;
16
+ };
17
+
18
+ const measures = (data) => {
19
+ return {
20
+ width: data.width,
21
+ height: data.height,
22
+ marginRight: 10,
23
+ marginBottom: 10,
24
+ };
25
+ };
26
+
27
+ const widgetLayout = {
28
+ left: 0,
29
+ top: 20,
30
+ width: 1280,
31
+ height: 600,
32
+ };
33
+
34
+ onMounted(() => {});
35
+ </script>
36
+
37
+ <template>
38
+ <div
39
+ :style="{
40
+ fontSize: 40,
41
+ width: 1280,
42
+ height: 80,
43
+ color: '#FFFFFF',
44
+ }"
45
+ >
46
+ {{ pageData.title }}
47
+ </div>
48
+
49
+ <metro-widget
50
+ :name="name"
51
+ :left="widgetLayout.left"
52
+ :top="widgetLayout.top"
53
+ :width="widgetLayout.width"
54
+ :height="widgetLayout.height"
55
+ :provideData="provideData"
56
+ :direction="VERTICAL"
57
+ :measures="measures"
58
+ :onEdge="onEdge"
59
+ :padding="{ left: 20, right: 30, top: 50, bottom: 50 }"
60
+ >
61
+ <template #renderItem="{ data, onAction }">
62
+ <page-item :data="data" :onAction="onAction" />
63
+ </template>
64
+ </metro-widget>
65
+ </template>
66
+
67
+ <style scoped></style>
@@ -0,0 +1,94 @@
1
+ <script setup>
2
+ import { ref, inject, shallowRef, onMounted, computed } from "vue";
3
+ const modeIsKey = inject("modeIsKey");
4
+ const tabFocus = inject("tabFocus");
5
+ const globalInfo = inject("globalInfo");
6
+ const colorList = ["#FFD700", "#FF1493", "#1E90FF"];
7
+ const props = defineProps({
8
+ data: Object,
9
+ query: Object,
10
+ onAction: Object,
11
+ });
12
+
13
+ const focused = ref(false);
14
+ const divRef = shallowRef();
15
+
16
+ const onFocus = () => {
17
+ focused.value = true;
18
+ };
19
+
20
+ const onBlur = () => {
21
+ focused.value = false;
22
+ };
23
+
24
+ const onClicked = () => {
25
+ console.log("item clicked", props.data);
26
+ };
27
+
28
+ const onGaze = () => {};
29
+
30
+ const onIgnore = () => {};
31
+
32
+ const isSlect = computed(() => {
33
+ if (modeIsKey()) {
34
+ return (
35
+ !tabFocus.value &&
36
+ !focused.value &&
37
+ globalInfo.updateTabId == props.data.indexId
38
+ );
39
+ } else {
40
+ return globalInfo.updateTabId == props.data.indexId;
41
+ }
42
+ });
43
+
44
+ props.onAction.register("onFocus", onFocus);
45
+ props.onAction.register("onBlur", onBlur);
46
+ props.onAction.register("onClick", onClicked);
47
+ props.onAction.register("onGaze", onGaze);
48
+ props.onAction.register("onIgnore", onIgnore);
49
+
50
+ // indexId为4时,是有子tab的电影tab
51
+ const fontSize = computed(() => {
52
+ return props.data.isSubTab && props.data.indexId != 4 ? 26 : 30;
53
+ });
54
+ const fontWeight = computed(() => {
55
+ return props.data.isSubTab && props.data.indexId != 4 ? "bold" : null;
56
+ });
57
+ const textColor = computed(() => {
58
+ return props.data.isSubTab && props.data.indexId != 4
59
+ ? colorList[props.data.indexId % 3]
60
+ : "#ffffff";
61
+ });
62
+
63
+ onMounted(() => {});
64
+ </script>
65
+
66
+ <template>
67
+ <div
68
+ :style="{
69
+ fontSize: fontSize,
70
+ width: data.width,
71
+ height: data.height,
72
+ color: textColor,
73
+ backgroundColor: isSlect ? 'rgba(211,115,78,0.4)' : 'rgba(0,0,0,0)',
74
+ borderRadius: 15,
75
+ textAlign: 'center',
76
+ lineHeight: data.height,
77
+ transform: focused ? 'scale3d(1.1,1.1,1)' : 'scale3d(1,1,1)',
78
+ fontWeight: fontWeight,
79
+ transition: 'transform 0.2s',
80
+ }"
81
+ >
82
+ <img
83
+ :src="data.icon"
84
+ :style="{
85
+ left: 10,
86
+ top: 10,
87
+ width: data.width - 20,
88
+ height: data.height - 20,
89
+ }"
90
+ />
91
+ </div>
92
+ </template>
93
+
94
+ <style scoped></style>
@@ -0,0 +1,40 @@
1
+ <script setup>
2
+ import { ref } from "vue";
3
+
4
+ const props = defineProps({
5
+ data: Object,
6
+ onAction: Object,
7
+ });
8
+
9
+ const focused = ref(false);
10
+
11
+ // 注册回调
12
+ const onFocus = () => {
13
+ focused.value = true;
14
+ };
15
+
16
+ const onBlur = () => {
17
+ focused.value = false;
18
+ };
19
+
20
+ const onClick = () => {
21
+ console.log("page item clicked:", props.data);
22
+ };
23
+
24
+ props.onAction.register("onFocus", onFocus);
25
+ props.onAction.register("onBlur", onBlur);
26
+ props.onAction.register("onClick", onClick);
27
+ </script>
28
+
29
+ <template>
30
+ <div
31
+ :style="{
32
+ width: data.width,
33
+ height: data.height,
34
+ backgroundImage: `url(${data.img})`,
35
+ borderRadius: 15,
36
+ transform: focused ? 'scale3d(1.1, 1.1, 1)' : 'scale3d(1, 1, 1)',
37
+ transition: 'transform 0.2s',
38
+ }"
39
+ />
40
+ </template>