@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,135 @@
1
+ #define PI 3.14159265359
2
+ #define RADIUS .05
3
+ #define LIGHT_DIR vec3(5,3,1)
4
+ #define SPECULAR_SHININESS 24.0
5
+ #define SPECULAR_COLOR vec3(1.0,1.0,1.0)
6
+ #define SPECULAR_POWER 10.0
7
+ //书籍范围的百分比
8
+ #define BOOK_BOUND vec4(0.00, 0.20, 1.00, 1.00)
9
+
10
+ // 优化的快速反正弦函数
11
+ float fastAsin(float x) {
12
+ // 使用更少的项来近似计算
13
+ // return x + (1.0 / 6.0) * x3 + (3.0 / 40.0) * x5 + (5.0 / 112.0) * x7;
14
+ return x + x*x*x*(1.0/6.0) + x*x*x*x*x*(3.0/40.0);
15
+ }
16
+
17
+ // 优化的矩形检测函数
18
+ bool inRect(vec2 uv, vec4 rect) {
19
+ return all(greaterThanEqual(uv, rect.xy)) && all(lessThanEqual(uv, rect.zw));
20
+ }
21
+
22
+ vec3 fakeSpine(vec3 col, float t, float darken)
23
+ {
24
+ return mix(col * darken, col, min(1.0, sqrt(abs(t) * 30.0)));
25
+ }
26
+
27
+ vec3 fakeNormal(float t, float center)
28
+ {
29
+ t -= center;
30
+ float interp = (1.0 - abs(t * 2.0)) * PI + PI * 0.75;
31
+
32
+ vec3 normal = vec3(abs(sin(interp)) ,0. , abs(cos(interp)));
33
+
34
+ return mix(normal, vec3(0.0, 0.0, 1.0), min(1.0, sqrt(abs(t) * 5.0)));
35
+ }
36
+
37
+ vec3 specular(vec3 viewDir, vec3 normal)
38
+ {
39
+ vec3 lightDir = normalize(LIGHT_DIR);
40
+ float dist = length(lightDir);
41
+ vec3 halfV = normalize(lightDir + normalize(viewDir));
42
+
43
+ float NdotH = dot(normal, halfV);
44
+ float intensity = pow(max(NdotH, 0.0), SPECULAR_SHININESS);
45
+
46
+ return intensity * SPECULAR_COLOR * SPECULAR_POWER / dist;
47
+ }
48
+
49
+ void mainImage(out vec4 fragColor, in vec2 fragCoord) {
50
+ vec2 aspect = iResolution.xy / iResolution.y;
51
+ vec2 uv = fragCoord / iResolution.y;
52
+ // vec2 mouse = iMouse.xy / iResolution.y;
53
+
54
+ vec4 bgColor = vec4(0.0, 0.0, 0.0, 0.0);
55
+
56
+ vec4 viewBounds = vec4(0., 0., aspect);
57
+ vec4 bookBounds = vec4(BOOK_BOUND.xy * aspect, BOOK_BOUND.zw * aspect);
58
+ vec2 bookSize = bookBounds.zw - bookBounds.xy;
59
+ vec2 bookAspect = bookSize.xy / bookSize.y;
60
+ vec4 bookUvBounds = vec4(0.0, 0.0, bookAspect);
61
+ vec2 bookUv = (uv - bookBounds.xy) / bookSize.y;
62
+ // mouse = (mouse - bookBounds.xy) / bookSize.y;
63
+
64
+ // 优化鼠标轨迹计算
65
+ float timeFact = 1. - iTime / iDuration;
66
+ vec2 mouse = vec2(timeFact, 1.2 * timeFact * (timeFact - 1.0) + 1.0) * bookAspect;
67
+ // 防止鼠标超出书本范围
68
+ mouse = clamp(mouse, vec2(0.0), bookAspect - vec2(1e-2));
69
+
70
+ //bookAspect为bookUv的右上角
71
+ vec2 mouseDir = normalize(bookAspect - mouse);
72
+ vec2 origin = mouse - mouseDir * mouse.x / abs(mouseDir.x);
73
+ vec2 axisPos = (mouse + bookAspect) * 0.5; // 使用乘法代替除法
74
+
75
+ float axisDist = length(axisPos - origin);
76
+
77
+ float proj = dot(bookUv - origin, mouseDir);
78
+ float dist = proj - axisDist;
79
+ vec2 linePoint = bookUv - dist * mouseDir;
80
+
81
+ float radius = clamp(2.0 * mouse.x * RADIUS, 0.0, RADIUS);
82
+
83
+ // 提前计算常用值
84
+ bool inBookBounds = inRect(uv, bookBounds);
85
+
86
+ if(dist > radius) {
87
+ if (inRect(uv, bookBounds)) {
88
+ fragColor = jsvTexture2D(iChannel1, bookUv / bookAspect);
89
+ } else {
90
+ fragColor = bgColor;
91
+ }
92
+ } else if(dist >= 0.0) {
93
+ //圆柱体部分
94
+ if (radius > 1e-5) {
95
+ float theta = fastAsin(dist / radius);
96
+ vec2 p1 = linePoint + mouseDir * theta * radius;
97
+ vec2 p2 = linePoint + mouseDir * (PI - theta) * radius;
98
+
99
+ vec2 uv2 = p2 / bookAspect;
100
+ uv2.x = 1.0 - uv2.x;
101
+
102
+ vec2 uv1 = p1 / bookAspect;
103
+
104
+ bool inP2 = inRect(p2, bookUvBounds);
105
+ bool inP1 = inRect(p1, bookUvBounds);
106
+
107
+ if(inP2) {
108
+ fragColor = jsvTexture2D(iChannel1, uv2);
109
+ fragColor.xyz += specular(vec3(0.0, 0.0, 1.0), fakeNormal(dist - radius * 0.5, 0.0)) * 0.2;
110
+ } else if(inP1) {
111
+ fragColor = jsvTexture2D(iChannel0, uv1);
112
+ } else {
113
+ fragColor = bgColor;
114
+ }
115
+ }
116
+ } else {
117
+ vec2 p = linePoint + mouseDir * (abs(dist) + PI * radius);
118
+ bool inP = inRect(p, bookUvBounds);
119
+
120
+ if (inP) {
121
+ vec2 uv = p / bookAspect;
122
+ uv.x = 1.0 - uv.x;
123
+ fragColor = jsvTexture2D(iChannel1, uv);
124
+ } else if (inRect(bookUv, bookUvBounds) ) {
125
+ vec2 uv2 = bookUv / bookAspect;
126
+ fragColor = jsvTexture2D(iChannel0, uv2);
127
+ } else {
128
+ fragColor = bgColor;
129
+ }
130
+ }
131
+
132
+ if (inBookBounds) {
133
+ fragColor.xyz = fakeSpine(fragColor.xyz, dist - radius, 0.0);
134
+ }
135
+ }
@@ -0,0 +1,82 @@
1
+ <template>
2
+ <div :style="pageStyle">
3
+ <div class="page-number">{{ index }}</div>
4
+ <div
5
+ class="page-detail"
6
+ :style="{
7
+ left: 30,
8
+ top: 30,
9
+ width: pageStyle.width - 60,
10
+ height: pageStyle.height - 60,
11
+ textOverflow: 'ellipsis',
12
+ backgroundColor: 'rgba(0,0,128,0.5)',
13
+ }"
14
+ >
15
+ {{ TextList[index % 3] }}
16
+ </div>
17
+ </div>
18
+ </template>
19
+
20
+ <script setup>
21
+ import { computed, onUnmounted, onMounted } from "vue";
22
+
23
+ const props = defineProps({
24
+ width: {
25
+ type: Number,
26
+ required: true,
27
+ },
28
+ height: {
29
+ type: Number,
30
+ required: true,
31
+ },
32
+ index: {
33
+ type: Number,
34
+ required: true,
35
+ },
36
+ flushTrigger: {
37
+ type: Function,
38
+ required: true,
39
+ },
40
+ });
41
+
42
+ const TextList = [
43
+ "以下是长句子:\n" +
44
+ "1.石室诗士施氏,嗜狮,誓食十狮。2.施氏时时适市视狮。3.十时,适十狮适市。4.是时,适施氏适市。5.施氏视是十狮,恃矢势,使是十狮逝世。6.氏拾是十狮尸,适石室。7.石室湿,氏使侍拭石室。8.石室拭,施氏始试食是十狮尸。9.食时,始识是十狮尸,实十石狮尸。10.试释是事。\n",
45
+ "以下是长句子:\n" + "君不见,黄河之水天上来,奔流到海不复回。\n",
46
+ "以下是长句子:\n" +
47
+ 'ABC انجليزي "abc" سعر الملابس 180 ABC انجليزي "abc" سعر الملابس 180 \n',
48
+ ];
49
+
50
+ console.log("页面构建(测试BookFlip用key来保持prevPage)" + props.index);
51
+
52
+ const pageStyle = computed(() => {
53
+ const randomColor = `#${Math.floor(Math.random() * 16777215)
54
+ .toString(16)
55
+ .padStart(6, "0")}`;
56
+ return {
57
+ width: `${props.width}`,
58
+ height: `${props.height}`,
59
+ backgroundColor: randomColor,
60
+ };
61
+ });
62
+
63
+ onMounted(() => {
64
+ console.log("页面挂载(测试BookFlip用key来保持prevPage)" + props.index);
65
+ props.flushTrigger(props.index); // 若有图片,要用jsvPreload进行图片预加载,并在预加载完成后调用flushTrigger
66
+ });
67
+
68
+ onUnmounted(() => {
69
+ console.log("页面销毁(测试BookFlip用key来保持prevPage)" + props.index);
70
+ });
71
+ </script>
72
+
73
+ <style scoped>
74
+ .page-number {
75
+ font-size: 24px;
76
+ color: rgba(255, 255, 255, 1);
77
+ }
78
+ .page-detail {
79
+ font-size: 30px;
80
+ color: rgb(207, 52, 168);
81
+ }
82
+ </style>
@@ -22,10 +22,32 @@ import { shallowRef } from "vue";
22
22
  import { buildBounce } from "./FreeMoveBuilder";
23
23
 
24
24
  const props = defineProps({
25
+ /**
26
+ * 图片资源路径
27
+ * @type {String}
28
+ * @required
29
+ * @example
30
+ * // 正确用法
31
+ * src: "/images/ball.png"
32
+ */
25
33
  src: {
26
34
  type: String,
27
35
  required: true,
28
36
  },
37
+
38
+ /**
39
+ * 布局配置对象
40
+ * @type {Object}
41
+ * @required
42
+ * @typedef {Object} LayoutConfig
43
+ * @property {number} top - 组件顶部位置(单位:px)
44
+ * @property {number} left - 组件左侧位置(单位:px)
45
+ * @property {number} width - 组件宽度(单位:px)
46
+ * @property {number} height - 组件高度(单位:px)
47
+ * @example
48
+ * // 正确配置示例
49
+ * { top: 100, left: 200, width: 50, height: 50 }
50
+ */
29
51
  layout: {
30
52
  type: Object,
31
53
  required: true,
@@ -35,14 +57,24 @@ const props = defineProps({
35
57
  let actorRef = shallowRef(null);
36
58
  let vLeftSnakeControl = null;
37
59
 
60
+ /**
61
+ * 启动弹跳动画
62
+ * @param {number} left - 目标位置X坐标(单位:px)
63
+ * @param {number} top - 目标位置Y坐标(单位:px)
64
+ * @param {number} bounceTimes - 弹跳次数(建议1-5次)
65
+ * @description 调用此方法后组件会从当前位置向目标位置执行弹跳动画
66
+ * @example
67
+ * // 在(200,300)位置弹跳3次
68
+ * start(200, 300, 3)
69
+ */
38
70
  function startSnakeAnim(left, top, bounceTimes) {
39
- // showSnake.value = true;
40
71
  vLeftSnakeControl = actorRef.value.control;
41
72
  vLeftSnakeControl.run((cmds) => [
42
73
  ...buildBounce(cmds, 1, left, top, bounceTimes, 2.0, (state) => {}),
43
74
  ]);
44
75
  }
45
76
 
77
+ // 暴露给父组件的方法
46
78
  defineExpose({
47
79
  start: startSnakeAnim,
48
80
  });
@@ -103,7 +103,17 @@ import {
103
103
  buildPreloadInfo,
104
104
  } from "jsview";
105
105
  import { shallowRef, onBeforeUnmount, watch } from "vue";
106
+
106
107
  const props = defineProps({
108
+ /**
109
+ * 春联图片资源配置对象
110
+ * @type {Object}
111
+ * @property {string} leftContent - 左侧春联图片URL
112
+ * @property {string} rightContent - 右侧春联图片URL
113
+ * @property {string} scrollSprite - 滚轴精灵图URL
114
+ * @property {string} scrollStatic - 静态滚轴图片URL
115
+ * @required
116
+ */
107
117
  sourceMap: {
108
118
  type: Object,
109
119
  require: true,
@@ -116,6 +126,14 @@ const props = defineProps({
116
126
  );
117
127
  },
118
128
  },
129
+
130
+ /**
131
+ * 春联尺寸配置
132
+ * @type {Object}
133
+ * @property {number} width - 春联宽度
134
+ * @property {number} height - 春联高度
135
+ * @required
136
+ */
119
137
  size: {
120
138
  type: Object,
121
139
  required: true,
@@ -123,6 +141,14 @@ const props = defineProps({
123
141
  return "width" in value && "height" in value;
124
142
  },
125
143
  },
144
+
145
+ /**
146
+ * 左侧春联位置配置
147
+ * @type {Object}
148
+ * @property {number} left - 左侧春联的水平位置
149
+ * @property {number} top - 左侧春联的垂直位置
150
+ * @required
151
+ */
126
152
  leftPosition: {
127
153
  type: Object,
128
154
  require: true,
@@ -130,6 +156,14 @@ const props = defineProps({
130
156
  return "left" in value && "top" in value;
131
157
  },
132
158
  },
159
+
160
+ /**
161
+ * 右侧春联位置配置
162
+ * @type {Object}
163
+ * @property {number} left - 右侧春联的水平位置
164
+ * @property {number} top - 右侧春联的垂直位置
165
+ * @required
166
+ */
133
167
  rightPosition: {
134
168
  type: Object,
135
169
  require: true,
@@ -137,7 +171,16 @@ const props = defineProps({
137
171
  return "left" in value && "top" in value;
138
172
  },
139
173
  },
140
- duration: { type: Number, require: true },
174
+
175
+ /**
176
+ * 动画持续时间(单位:秒)
177
+ * @type {Number}
178
+ * @required
179
+ */
180
+ duration: {
181
+ type: Number,
182
+ require: true
183
+ }
141
184
  });
142
185
  const layouts = [{ ...props.leftPosition, isLeft: true }, props.rightPosition];
143
186
  let myShow = shallowRef(false);
@@ -0,0 +1,130 @@
1
+ <!--
2
+ * @Author: ChenChanghua
3
+ * @Date: 2023-03-08 14:52:08
4
+ * @Description: file content
5
+ -->
6
+ <script setup>
7
+ import { MetroWidget, VERTICAL, useFocusHub } from "jsview";
8
+ import Item from "./Item.vue";
9
+ import { onMounted, shallowRef } from "vue";
10
+
11
+ const TAG = "MetroWidgetDemo";
12
+
13
+ const focusHub = useFocusHub();
14
+
15
+ const provideData = () => {
16
+ const data = [
17
+ {
18
+ width: 50,
19
+ height: 50,
20
+ marginRight: 10,
21
+ index: 0,
22
+ },
23
+ {
24
+ width: 50,
25
+ height: 50,
26
+ marginRight: 10,
27
+ index: 1,
28
+ },
29
+ {
30
+ width: 50,
31
+ height: 50,
32
+ marginRight: 10,
33
+ index: 2,
34
+ spriteSrc:
35
+ "https://cdn.release.qcast.cn/JsViewFrameworkTester/JsViewVueSampleResources/DemoForOperator/ClickSpriteAnim/good.png",
36
+ },
37
+ ];
38
+ return data;
39
+ };
40
+
41
+ const measures = (data) => {
42
+ return {
43
+ width: data.width,
44
+ height: data.height,
45
+ marginRight: data.marginRight,
46
+ marginBottom: data.marginBottom,
47
+ };
48
+ };
49
+
50
+ // callbacks
51
+ const onEdge = (edgeInfo) => {
52
+ console.log(TAG, "onEdge", edgeInfo);
53
+ };
54
+
55
+ const onFocus = () => {
56
+ console.log(TAG, "onFocus");
57
+ };
58
+
59
+ const onBlur = () => {
60
+ console.log(TAG, "onBlur");
61
+ };
62
+
63
+ const onScroll = (start, range, totalSize) => {
64
+ console.log(TAG, "onScroll", start, range, totalSize);
65
+ };
66
+
67
+ const widgetLayout = {
68
+ left: (1280 - 180) / 2,
69
+ top: 100,
70
+ width: 180,
71
+ height: 300,
72
+ };
73
+
74
+ onMounted(() => {
75
+ //组件mount后设置焦点
76
+ focusHub.setFocus("mainMw");
77
+ });
78
+
79
+ const widgetRef = shallowRef(null);
80
+ window.widgetRef = widgetRef;
81
+
82
+ const show = shallowRef(false);
83
+ setTimeout(() => {
84
+ show.value = true;
85
+ }, 1000);
86
+ </script>
87
+
88
+ <template>
89
+ <div
90
+ :style="{
91
+ width: 1280,
92
+ height: 720,
93
+ backgroundColor: '#007788',
94
+ }"
95
+ />
96
+ <metro-widget
97
+ v-if="show"
98
+ ref="widgetRef"
99
+ name="mainMw"
100
+ :left="widgetLayout.left"
101
+ :top="widgetLayout.top"
102
+ :width="widgetLayout.width"
103
+ :height="widgetLayout.height"
104
+ :provideData="provideData"
105
+ :direction="VERTICAL"
106
+ :measures="measures"
107
+ :onEdge="onEdge"
108
+ :onFocus="onFocus"
109
+ :onBlur="onBlur"
110
+ :onScroll="onScroll"
111
+ >
112
+ <template #renderItem="{ data, onAction }">
113
+ <item :data="data" :onAction="onAction" />
114
+ </template>
115
+ </metro-widget>
116
+
117
+ <div
118
+ :style="{
119
+ width: 1280,
120
+ height: 80,
121
+ lineHeight: 80,
122
+ backgroundColor: '#00000077',
123
+ fontSize: 30,
124
+ textAlign: 'center',
125
+ color: '#ffffff',
126
+ }"
127
+ >
128
+ 第三项摁OK会有动画
129
+ </div>
130
+ </template>
@@ -0,0 +1,74 @@
1
+ <!--
2
+ * @Author: ChenChanghua
3
+ * @Date: 2023-03-08 14:52:17
4
+ * @Description: file content
5
+ -->
6
+ <script setup>
7
+ import { ref, shallowRef } from "vue";
8
+ import Sprite from "../Sprite/Sprite.vue";
9
+
10
+ const props = defineProps({
11
+ data: Object,
12
+ onAction: Object,
13
+ });
14
+
15
+ const focused = ref(false);
16
+ const spriteController = shallowRef(null);
17
+ // 注册回调
18
+ const onFocus = () => {
19
+ focused.value = true;
20
+ };
21
+ const onBlur = () => {
22
+ focused.value = false;
23
+ };
24
+ const onClick = () => {
25
+ spriteController.value?.play();
26
+ };
27
+ props.onAction.register("onFocus", onFocus);
28
+ props.onAction.register("onBlur", onBlur);
29
+ props.onAction.register("onClick", onClick);
30
+
31
+ const onAnimEnd = () => {
32
+ console.log("anim end");
33
+ };
34
+ </script>
35
+
36
+ <template>
37
+ <div
38
+ :style="{
39
+ width: data.width,
40
+ height: data.height,
41
+ backgroundColor: focused ? '#22222299' : '#00000000',
42
+ borderRadius: Math.round(data.width / 2),
43
+ }"
44
+ ></div>
45
+ <Sprite
46
+ v-if="data.spriteSrc"
47
+ ref="spriteController"
48
+ :spriteSrc="data.spriteSrc"
49
+ :repeat="0"
50
+ :layout="{
51
+ width: data.width,
52
+ height: data.height,
53
+ }"
54
+ :onEnd="onAnimEnd"
55
+ :duration="1"
56
+ endFrame="end"
57
+ :autoStart="false"
58
+ ></Sprite>
59
+ <div
60
+ v-else
61
+ :style="{
62
+ width: data.width,
63
+ height: data.height,
64
+ fontSize: 30,
65
+ color: '#ffffff',
66
+ textAlign: 'center',
67
+ lineHeight: data.height,
68
+ backgroundColor: '#ffffff33',
69
+ borderRadius: Math.round(data.width / 2),
70
+ }"
71
+ >
72
+ {{ data.index }}
73
+ </div>
74
+ </template>