@shijiu/jsview-vue-samples 2.2.426-test.0 → 2.3.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 (170) hide show
  1. package/BakeViewDemo/AnimatePic.vue +1 -1
  2. package/Basic/components/text/TextDirection.vue +7 -1
  3. package/BasicFocusControl/components/BaseBlock.vue +65 -18
  4. package/BreakRender/assets/imageList.json +235 -235
  5. package/ColorSpace/App.vue +2 -2
  6. package/CoupletsTest/App.vue +1 -1
  7. package/CoupletsTest/widget/Banger/Banger.vue +3 -3
  8. package/CoupletsTest/widget/Banger/MaroonLoader.vue +5 -5
  9. package/CoupletsTest/widget/Couplets/Couplets.vue +4 -4
  10. package/CoupletsTest/widget/Fireworks/Fireworks.vue +13 -13
  11. package/CustomShader/App.vue +4 -4
  12. package/CustomShader/gaussianBlur.glsl +1 -1
  13. package/DashPath/App.vue +79 -0
  14. package/DashPath/AppForOperator.vue +35 -0
  15. package/DashPath/DashPath.vue +118 -0
  16. package/DemoForOperator/AnimPic/AnimPic.vue +47 -0
  17. package/DemoForOperator/AnimPic/App.vue +28 -0
  18. package/DemoForOperator/Banger/App.vue +26 -0
  19. package/DemoForOperator/Banger/Banger/Banger.vue +252 -0
  20. package/DemoForOperator/Banger/Banger/Maroon.vue +123 -0
  21. package/DemoForOperator/Banger/Banger/MaroonLoader.vue +78 -0
  22. package/DemoForOperator/Banger/Banger/SpriteDeal.js +30 -0
  23. package/DemoForOperator/Bounce/App.vue +43 -0
  24. package/DemoForOperator/Bounce/Bounce.vue +49 -0
  25. package/DemoForOperator/Bounce/FreeMoveBuilder.js +139 -0
  26. package/DemoForOperator/ChunLian/App.vue +47 -0
  27. package/DemoForOperator/ChunLian/Couplets.vue +248 -0
  28. package/DemoForOperator/EpisodeList/App.vue +80 -0
  29. package/DemoForOperator/EpisodeList/EpisodeList/Controller.vue +113 -0
  30. package/DemoForOperator/EpisodeList/EpisodeList/EpisodeList.vue +176 -0
  31. package/DemoForOperator/EpisodeList/GroupItem.vue +65 -0
  32. package/DemoForOperator/EpisodeList/ListItem.vue +48 -0
  33. package/DemoForOperator/Firework1/App.vue +25 -0
  34. package/DemoForOperator/Firework1/Fireworks.vue +358 -0
  35. package/DemoForOperator/Firework1/SpriteDeal.js +30 -0
  36. package/DemoForOperator/FlipPage/App.vue +75 -0
  37. package/DemoForOperator/FlipPage/FlipPage/FlipPage.vue +150 -0
  38. package/DemoForOperator/FlipPage/FlipPage/flipIn.glsl +41 -0
  39. package/DemoForOperator/FlipPage/FlipPage/flipOut.glsl +41 -0
  40. package/DemoForOperator/Focus/Alpha/AlphaFocusBox.vue +70 -0
  41. package/DemoForOperator/Focus/Alpha/AlphaPage.vue +40 -0
  42. package/DemoForOperator/Focus/Alpha/Item.vue +64 -0
  43. package/DemoForOperator/Focus/App.vue +124 -0
  44. package/DemoForOperator/Focus/CommonPageSetting.js +30 -0
  45. package/DemoForOperator/Focus/Item.vue +46 -0
  46. package/DemoForOperator/Focus/Light/Item.vue +67 -0
  47. package/DemoForOperator/Focus/Light/LightFocusBox.vue +46 -0
  48. package/DemoForOperator/Focus/Light/LightPage.vue +43 -0
  49. package/DemoForOperator/Focus/Light/utils/FrameCanvasStore.ts +68 -0
  50. package/DemoForOperator/Focus/Light/utils/RotateFrame.vue +146 -0
  51. package/DemoForOperator/Focus/Light/utils/circleHaloMask.png +0 -0
  52. package/DemoForOperator/Focus/Normal/Item.vue +64 -0
  53. package/DemoForOperator/Focus/Normal/NormalFocusBox.vue +53 -0
  54. package/DemoForOperator/Focus/Normal/NormalPage.vue +41 -0
  55. package/DemoForOperator/Focus/SwipeLight/Item.vue +73 -0
  56. package/DemoForOperator/Focus/SwipeLight/SwipeLightBox.vue +62 -0
  57. package/DemoForOperator/Focus/SwipeLight/SwipeLightPage.vue +44 -0
  58. package/DemoForOperator/FullscreenIn/App.vue +105 -0
  59. package/DemoForOperator/FullscreenIn/FullscreenPoster.vue +41 -0
  60. package/DemoForOperator/FullscreenIn/Item.vue +50 -0
  61. package/DemoForOperator/Genie/App.vue +78 -0
  62. package/DemoForOperator/Genie/geniePakcer/Genie.vue +699 -0
  63. package/DemoForOperator/Genie/geniePakcer/genieBottom.glsl +49 -0
  64. package/DemoForOperator/Genie/geniePakcer/genieLeft.glsl +50 -0
  65. package/DemoForOperator/Genie/geniePakcer/genieRight.glsl +57 -0
  66. package/DemoForOperator/Genie/geniePakcer/genieTop.glsl +50 -0
  67. package/DemoForOperator/GrayFilter/App.vue +51 -0
  68. package/DemoForOperator/GrayFilter/GrayFilter.vue +38 -0
  69. package/DemoForOperator/Jigsaw/App.vue +45 -0
  70. package/DemoForOperator/Jigsaw/JigsawFull.vue +100 -0
  71. package/DemoForOperator/Jigsaw/JigsawSingle.vue +86 -0
  72. package/DemoForOperator/Particle/App.vue +69 -0
  73. package/DemoForOperator/Particle/Drop/DropParticle.vue +176 -0
  74. package/DemoForOperator/Particle/Explode/ExplodeParticle.vue +99 -0
  75. package/DemoForOperator/PosterAnim/App.vue +125 -0
  76. package/DemoForOperator/PosterAnim/Bounce/BouncePage.vue +54 -0
  77. package/DemoForOperator/PosterAnim/Bounce/Item.vue +85 -0
  78. package/DemoForOperator/PosterAnim/Breath/BreathPage.vue +47 -0
  79. package/DemoForOperator/PosterAnim/Breath/Item.vue +58 -0
  80. package/DemoForOperator/PosterAnim/CommonPageSetting.js +30 -0
  81. package/DemoForOperator/PosterAnim/Item.vue +46 -0
  82. package/DemoForOperator/PosterAnim/PosterAnim.js +58 -0
  83. package/DemoForOperator/PosterAnim/Scale/Item.vue +72 -0
  84. package/DemoForOperator/PosterAnim/Scale/ScalePage.vue +48 -0
  85. package/DemoForOperator/PosterAnim/Shake/Item.vue +85 -0
  86. package/DemoForOperator/PosterAnim/Shake/ShakePage.vue +53 -0
  87. package/DemoForOperator/PosterOverflow/App.vue +116 -0
  88. package/DemoForOperator/PosterOverflow/Item.vue +67 -0
  89. package/DemoForOperator/PosterOverflow/PosterOverflow.vue +23 -0
  90. package/DemoForOperator/Ripple/App.vue +54 -0
  91. package/DemoForOperator/Ripple/Ripple.vue +50 -0
  92. package/DemoForOperator/ScalePoster/App.vue +4 -0
  93. package/DemoForOperator/ScalePoster/ScalePoster.vue +0 -0
  94. package/DemoForOperator/Sprite/App.vue +33 -0
  95. package/DemoForOperator/Sprite/Sprite.vue +90 -0
  96. package/DemoForOperator/Stretch/App.vue +103 -0
  97. package/DemoForOperator/Stretch/Stretch/Item.vue +192 -0
  98. package/DemoForOperator/Stretch/Stretch/Stretch.vue +168 -0
  99. package/DemoForOperator/TabContent/App.vue +89 -0
  100. package/DemoForOperator/TabContent/ContentPage.vue +66 -0
  101. package/DemoForOperator/TabContent/Item.vue +85 -0
  102. package/DemoForOperator/TabContent/PageItem.vue +40 -0
  103. package/DemoForOperator/TabContent/TabContent/CreepFocus.vue +160 -0
  104. package/DemoForOperator/TabContent/TabContent/Item.vue +63 -0
  105. package/DemoForOperator/TabContent/TabContent/TabContent.vue +146 -0
  106. package/DemoForOperator/TabContent/TabContent/TabItem.vue +368 -0
  107. package/DemoForOperator/TabContent/TabContent/TabWidget.vue +243 -0
  108. package/DemoForOperator/TabContent/TabContent/Util.js +3 -0
  109. package/DemoForOperator/TabContent/TabContent/ViewSwiper.vue +110 -0
  110. package/DemoForOperator/TabContent/testData.js +241 -0
  111. package/DemoForOperator/Vortex/App.vue +78 -0
  112. package/DemoForOperator/Vortex/Vortex/Vortex.vue +154 -0
  113. package/DemoForOperator/Vortex/Vortex/vortexIn.glsl +38 -0
  114. package/DemoForOperator/Vortex/Vortex/vortexOut.glsl +38 -0
  115. package/DemoForOperator/index.js +6 -0
  116. package/DemoForOperator/routeList.js +142 -0
  117. package/DemoHomepage/App.vue +50 -30
  118. package/DemoHomepage/components/Dialog.vue +1 -0
  119. package/DemoHomepage/components/TabFrame.vue +7 -0
  120. package/DemoHomepage/router.js +104 -81
  121. package/DemoHomepage/views/Homepage.vue +7 -2
  122. package/DivMetroPerformance/data.js +3 -3
  123. package/DriftScopeTest/App.vue +1 -1
  124. package/FilterDemo/AnimatePic.vue +1 -1
  125. package/FilterDemo/VideoLayer.vue +2 -2
  126. package/FullScreenFlex/TestFrame2.vue +1 -1
  127. package/GiftRain/App.vue +12 -12
  128. package/JsvPreDownloader/App.vue +4 -4
  129. package/MediaDemo/components/frames/AudioFrame.vue +1 -1
  130. package/MediaDemo/components/frames/VideoFrame.vue +1 -1
  131. package/MetroWidgetDemos/MassiveItems/ContentItem.vue +1 -1
  132. package/MetroWidgetDemos/MassiveItems/data.js +1 -1
  133. package/MetroWidgetDemos/PerformanceTest/data.js +3 -3
  134. package/MetroWidgetDemos/RefreshDemo/assets/imageList.json +235 -235
  135. package/MetroWidgetDemos/SkeletonDiagram/assets/imageList.json +235 -235
  136. package/MetroWidgetDemos/focusableItemMetroWidget/WidgetItem.vue +3 -1
  137. package/MetroWidgetDemos/routeList.js +17 -17
  138. package/Poster3d/App.vue +69 -0
  139. package/Poster3d/Poster3d.vue +92 -0
  140. package/PosterPacker/App.vue +3 -3
  141. package/PosterPacker/tools/vortexPacker/Vortex.vue +1 -1
  142. package/QrcodeDemo/App.vue +1 -1
  143. package/Ripple/App.vue +1 -1
  144. package/ScaleDownNeon/App.vue +4 -4
  145. package/SceneTransition/App.vue +2 -2
  146. package/SceneTransition/maskConfig/config2.js +12 -12
  147. package/SceneTransition/maskConfig/config3.js +14 -14
  148. package/SprayView/App.vue +96 -51
  149. package/SpringFestival/App.vue +73 -0
  150. package/SpringFestival/SpringFestivalScene/ChunLian.vue +211 -0
  151. package/SpringFestival/SpringFestivalScene/FreeMoveBuilder.js +139 -0
  152. package/SpringFestival/SpringFestivalScene/LanternAnim.js +60 -0
  153. package/SpringFestival/SpringFestivalScene/Rain.vue +137 -0
  154. package/SpringFestival/SpringFestivalScene/Scene.vue +218 -0
  155. package/SpringFestival/SpringFestivalScene/imageConfig.js +87 -0
  156. package/SpringFestival/SpringFestivalScene/index.js +1 -0
  157. package/Swiper/App.vue +28 -29
  158. package/Swiper/Item.vue +19 -0
  159. package/SwiperTest/App.vue +9 -9
  160. package/TestNativeSharedView/AckEventDefine.ts +82 -0
  161. package/TestNativeSharedView/App.vue +4 -6
  162. package/TestNativeSharedView/JsvDemoTester.js +131 -0
  163. package/TextureAnimation/App.vue +16 -6
  164. package/TextureAnimation/App3.vue +100 -0
  165. package/TextureAnimation/utils/FrameCanvasStore.ts +68 -0
  166. package/TextureAnimation/utils/RotateFrame.vue +146 -0
  167. package/TextureAnimation/utils/circleHaloMask.png +0 -0
  168. package/TombSweepingDayTest/Raining/RainScene.vue +4 -4
  169. package/ViewOpacity/App.vue +2 -2
  170. package/package.json +1 -1
@@ -0,0 +1,33 @@
1
+ <script setup>
2
+ import Sprite from "./Sprite.vue";
3
+
4
+ const spriteSrc = "https://oss.image.qcast.cn/JsViewVideo/ImageTestSample/JsViewFrameworkDemo/sprite/egg_break.png";
5
+ const repeat = 3;
6
+ const layout = {
7
+ width: 600,
8
+ height: 600,
9
+ };
10
+ const onEnd = () => {
11
+ console.log("play end");
12
+ };
13
+ const duration = 0.8;
14
+ </script>
15
+
16
+ <template>
17
+ <div class="bgStyle"></div>
18
+ <Sprite
19
+ :spriteSrc="spriteSrc"
20
+ :repeat="repeat"
21
+ :layout="layout"
22
+ :onEnd="onEnd"
23
+ :duration="duration"
24
+ ></Sprite>
25
+ </template>
26
+
27
+ <style scoped>
28
+ .bgStyle {
29
+ width: 1280;
30
+ height: 720;
31
+ background-color: #4d5e8c;
32
+ }
33
+ </style>
@@ -0,0 +1,90 @@
1
+ <template>
2
+ <JsvSpriteLoader
3
+ v-if="show"
4
+ :imageUrl="spriteSrc"
5
+ :configUrl="jsonUrl"
6
+ :onConfigReady="preloadCallback"
7
+ :noNeedResource="false"
8
+ >
9
+ <JsvSpriteAnim
10
+ ref="spriteController"
11
+ :spriteInfo="spriteJsonInfo"
12
+ :loop="repeat"
13
+ :duration="duration"
14
+ :imageUrl="spriteSrc"
15
+ :spriteFrameSize="spriteOriginSize"
16
+ :viewSize="{ w: layout.width, h: layout.height }"
17
+ :onAnimEnd="onAnimEnd"
18
+ :autostart="true"
19
+ />
20
+ </JsvSpriteLoader>
21
+ </template>
22
+
23
+ <script setup>
24
+ import { computed, shallowRef, onMounted } from "vue";
25
+ import { JsvSpriteAnim, JsvSpriteLoader, JsvSpriteTools } from "jsview";
26
+
27
+ const props = defineProps({
28
+ spriteSrc: {
29
+ type: String,
30
+ },
31
+ repeat: {
32
+ type: Number,
33
+ },
34
+ layout: {
35
+ type: Object,
36
+ },
37
+ onEnd: {
38
+ type: Function,
39
+ },
40
+ duration: {
41
+ type: Number,
42
+ },
43
+ });
44
+
45
+ const spriteController = shallowRef();
46
+ const show = shallowRef(true);
47
+
48
+ const jsonUrl = computed(() => {
49
+ return props.spriteSrc + ".json";
50
+ });
51
+
52
+ const _formatInfo = (config_json) => {
53
+ const info = {
54
+ frames: [],
55
+ meta: {
56
+ size: config_json.meta.size,
57
+ },
58
+ };
59
+
60
+ let frames_ref = info.frames;
61
+
62
+ for (let i = 0; i < config_json.frames.length; i++) {
63
+ const target = config_json.frames[i].spriteSourceSize;
64
+ frames_ref.push({
65
+ target,
66
+ source: config_json.frames[i].frame,
67
+ });
68
+ }
69
+
70
+ return { info };
71
+ };
72
+
73
+ function onAnimEnd() {
74
+ show.value = false;
75
+ props.onEnd?.();
76
+ }
77
+
78
+ const spriteJsonInfo = shallowRef();
79
+ const spriteOriginSize = shallowRef();
80
+ const preloadCallback = (config_json, resolve_set) => {
81
+ spriteJsonInfo.value = _formatInfo(config_json).info;
82
+
83
+ // 调整设置的原图尺寸设置
84
+ const guessSize = JsvSpriteTools.guessOriginSize(spriteJsonInfo.value);
85
+ spriteOriginSize.value = guessSize;
86
+ resolve_set(); // 通知loader数组设置完成
87
+ };
88
+
89
+ onMounted(() => {});
90
+ </script>
@@ -0,0 +1,103 @@
1
+ <template>
2
+ <div
3
+ :style="{
4
+ width: 1280,
5
+ height: 720,
6
+ backgroundColor: '#007788',
7
+ }"
8
+ ></div>
9
+ <div
10
+ :style="{
11
+ left: 300,
12
+ top: 100,
13
+ }"
14
+ >
15
+ <Stretch
16
+ name="stretch"
17
+ :itemSizeInfo="itemSizeInfo"
18
+ :datas="datas"
19
+ :layout="layout"
20
+ :onItemClick="onItemClick"
21
+ :onEdge="onEdge"
22
+ :duration="0.3"
23
+ :initLargeIndex="0"
24
+ >
25
+ <template #itemLarge>
26
+ <div
27
+ :style="{
28
+ width: 320,
29
+ height: 180,
30
+ backgroundColor: '#0F0',
31
+ fontSize: 30,
32
+ lineHeight: 180,
33
+ }"
34
+ >
35
+ 测试文字测试文字测试文字
36
+ </div></template
37
+ >
38
+ <template #itemSmall>
39
+ <div
40
+ :style="{
41
+ width: 100,
42
+ height: 180,
43
+ backgroundColor: '#F00',
44
+ fontSize: 30,
45
+ lineHeight: 180,
46
+ }"
47
+ >
48
+ 测试文字
49
+ </div>
50
+ </template>
51
+ <template #itemLeftEdge>
52
+ <div
53
+ :style="{
54
+ width: 10,
55
+ height: 10,
56
+ backgroundColor: '#00F',
57
+ }"
58
+ ></div>
59
+ </template>
60
+ <template #itemRightEdge>
61
+ <div
62
+ :style="{
63
+ left: 90,
64
+ width: 10,
65
+ height: 10,
66
+ backgroundColor: '#00F',
67
+ }"
68
+ ></div>
69
+ </template>
70
+ </Stretch>
71
+ </div>
72
+ </template>
73
+
74
+ <script setup>
75
+ import Stretch from "./Stretch/Stretch.vue";
76
+ import { useFocusHub } from "jsview";
77
+ import { onMounted } from "vue";
78
+
79
+ const focusHub = useFocusHub();
80
+ const itemSizeInfo = {
81
+ smallWidth: 100,
82
+ largeWidth: 320,
83
+ marginRight: 10,
84
+ height: 180,
85
+ };
86
+ const datas = [{}, {}, {}];
87
+ const layout = {
88
+ width: 540,
89
+ height: 180,
90
+ };
91
+
92
+ const onItemClick = (index) => {
93
+ console.log("onItemClick", index);
94
+ };
95
+
96
+ const onEdge = (edgeInfo) => {
97
+ console.log("onEdge");
98
+ };
99
+
100
+ onMounted(() => {
101
+ focusHub.setFocus("stretch");
102
+ });
103
+ </script>
@@ -0,0 +1,192 @@
1
+ <!--
2
+ * @Author: ChenChanghua
3
+ * @Date: 2023-03-08 14:52:17
4
+ * @Description: file content
5
+ -->
6
+ <script>
7
+ let animToken = 0;
8
+ </script>
9
+ <script setup>
10
+ import { ref, watch, inject, computed, onBeforeUnmount } from "vue";
11
+ import { getKeyFramesGroup } from "jsview";
12
+
13
+ const props = defineProps({
14
+ data: Object,
15
+ onAction: Object,
16
+ query: Object,
17
+ size: {
18
+ type: Object,
19
+ },
20
+ largeSize: {
21
+ type: Object,
22
+ },
23
+ duration: {
24
+ type: Number,
25
+ default: 200,
26
+ },
27
+ resizeDelay: {
28
+ type: Number,
29
+ default: 0,
30
+ },
31
+ onItemClick: {
32
+ type: Function,
33
+ },
34
+ });
35
+
36
+ const focused = ref(false);
37
+ const largeItemIndex = inject("largeItemIndex");
38
+
39
+ const isLarge = ref(props.query.index == largeItemIndex.value);
40
+ const showLarge = ref(isLarge.value);
41
+ const width = ref(isLarge.value ? props.largeSize.width : props.size.width);
42
+ const height = ref(isLarge.value ? props.largeSize.height : props.size.height);
43
+ const duration = props.duration;
44
+ const transitionStr = `left ${duration / 1000}s, width ${duration / 1000}s`;
45
+ const animInfo = {
46
+ anchor: 0.5,
47
+ duration: duration,
48
+ onEnd: () => {
49
+ console.log("resize end", props.query.index);
50
+ },
51
+ };
52
+
53
+ const animation = ref(null);
54
+ const scaleupAnim = `stretch_item_scale_up_keep_center_${animToken++}`;
55
+ const scaledownAnim = `stretch_item_scale_down_keep_center_${animToken++}`;
56
+
57
+ const xOffset = (props.size.width - props.largeSize.width) / 2;
58
+ const yOffset = (props.size.height - props.largeSize.height) / 2;
59
+ const scaleupBody = `@keyframes ${scaleupAnim} { from {transform: translate3d(${xOffset}, ${yOffset}, 0);} to {transform: translate3d(0, 0, 0);} }`;
60
+ const scaledownBody = `@keyframes ${scaledownAnim} { from {transform: translate3d(0, 0, 0);} to {transform: translate3d(${xOffset}, ${yOffset}, 0);}}`;
61
+
62
+ const styleSheets = getKeyFramesGroup();
63
+ styleSheets.insertRule(scaleupBody);
64
+ styleSheets.insertRule(scaledownBody);
65
+ function onAnimEnd() {
66
+ animation.value = null;
67
+ }
68
+
69
+ const rightEdgeTransition = `left ${duration / 1000}s linear`;
70
+ const rightSlotPosition = computed(() => {
71
+ return {
72
+ top: 0,
73
+ left: isLarge.value ? props.largeSize.width - props.size.width : 0,
74
+ };
75
+ });
76
+ watch(
77
+ () => largeItemIndex.value,
78
+ (newV) => {
79
+ if (newV == props.query.index) {
80
+ if (!isLarge.value) {
81
+ isLarge.value = true;
82
+ showLarge.value = true;
83
+ animation.value = `${scaleupAnim} ${duration / 1000}s linear`;
84
+
85
+ width.value = props.largeSize.width;
86
+ height.value = props.largeSize.height;
87
+
88
+ props.query.updateItemSize(
89
+ props.query.index,
90
+ {
91
+ width: width.value,
92
+ height: height.value,
93
+ },
94
+ animInfo
95
+ );
96
+ }
97
+ } else {
98
+ if (isLarge.value) {
99
+ isLarge.value = false;
100
+ width.value = props.size.width;
101
+ height.value = props.size.height;
102
+ animation.value = `${scaledownAnim} ${duration / 1000}s linear`;
103
+
104
+ props.query.updateItemSize(
105
+ props.query.index,
106
+ {
107
+ width: width.value,
108
+ height: height.value,
109
+ },
110
+ animInfo
111
+ );
112
+ }
113
+ }
114
+ }
115
+ );
116
+
117
+ function onTransitionDone() {
118
+ if (!isLarge.value) {
119
+ showLarge.value = false;
120
+ }
121
+ }
122
+
123
+ let timeoutHandler = -1;
124
+ const onFocus = () => {
125
+ focused.value = true;
126
+ timeoutHandler = setTimeout(() => {
127
+ largeItemIndex.value = props.query.index;
128
+ }, props.resizeDelay);
129
+ };
130
+
131
+ const onBlur = () => {
132
+ focused.value = false;
133
+ clearTimeout(timeoutHandler);
134
+ timeoutHandler = -1;
135
+ };
136
+
137
+ const onClick = () => {
138
+ props.onItemClick(props.query.index);
139
+ };
140
+
141
+ props.onAction.register("onFocus", onFocus);
142
+ props.onAction.register("onBlur", onBlur);
143
+ props.onAction.register("onClick", onClick);
144
+
145
+ onBeforeUnmount(() => {
146
+ styleSheets.removeRule(scaleupAnim);
147
+ styleSheets.removeRule(scaledownAnim);
148
+ });
149
+ </script>
150
+
151
+ <template>
152
+ <div
153
+ :style="{
154
+ width: width,
155
+ height: height,
156
+ transition: transitionStr,
157
+ overflow: 'hidden',
158
+ }"
159
+ @transitionend="onTransitionDone"
160
+ >
161
+ <div
162
+ :style="{
163
+ width: width,
164
+ height: height,
165
+ animation: animation,
166
+ }"
167
+ @animationend="onAnimEnd"
168
+ >
169
+ <div v-if="showLarge">
170
+ <slot name="large"></slot>
171
+ </div>
172
+ <div v-else>
173
+ <slot name="small"></slot>
174
+ </div>
175
+ </div>
176
+ </div>
177
+ <div :style="{ width: size.width, hieght: size.height }">
178
+ <slot name="left"></slot>
179
+ </div>
180
+
181
+ <div
182
+ :style="{
183
+ left: rightSlotPosition.left,
184
+ top: rightSlotPosition.top,
185
+ width: size.width,
186
+ hieght: size.height,
187
+ transition: rightEdgeTransition,
188
+ }"
189
+ >
190
+ <slot name="right"></slot>
191
+ </div>
192
+ </template>
@@ -0,0 +1,168 @@
1
+ <!--
2
+ * @Author: ChenChanghua
3
+ * @Date: 2023-03-08 14:52:08
4
+ * @Description: file content
5
+ -->
6
+ <script setup>
7
+ import {
8
+ ListWidget,
9
+ HORIZONTAL,
10
+ useFocusHub,
11
+ FixPositionSlide,
12
+ EdgeDirection,
13
+ } from "jsview";
14
+ import Item from "./Item.vue";
15
+ import { ref, provide, onMounted } from "vue";
16
+
17
+ const props = defineProps({
18
+ name: {
19
+ type: String,
20
+ required: true,
21
+ },
22
+ // { smallWidth: 0, largeWidth: 0, height: 0, marginRight: 10}
23
+ itemSizeInfo: {
24
+ type: Object,
25
+ required: true,
26
+ },
27
+ datas: {
28
+ type: Array,
29
+ required: true,
30
+ },
31
+ layout: {
32
+ type: Object,
33
+ required: true,
34
+ },
35
+ initLargeIndex: {
36
+ type: Number,
37
+ default: 0,
38
+ },
39
+ onFocus: {
40
+ type: Function,
41
+ },
42
+ onBlur: {
43
+ type: Function,
44
+ },
45
+ onEdge: {
46
+ type: Function,
47
+ },
48
+ onItemClick: {
49
+ type: Function,
50
+ },
51
+ //动画时长, 单位秒
52
+ duration: {
53
+ type: Number,
54
+ default: 0.2,
55
+ },
56
+ });
57
+
58
+ //一大多小
59
+ const itemMargin = props.itemSizeInfo.marginRight ?? 10;
60
+ const itemWidthSum =
61
+ props.itemSizeInfo.largeWidth +
62
+ props.itemSizeInfo.smallWidth * (props.datas.length - 1) +
63
+ (props.datas.length - 1) * itemMargin;
64
+ if (props.layout.width < itemWidthSum) {
65
+ console.error(
66
+ "Stretch: sum of item size must be smaller than component layout width."
67
+ );
68
+ }
69
+ if (props.layout.height < props.itemSizeInfo.height) {
70
+ console.error(
71
+ "Stretch: item height must be smaller than component layout height."
72
+ );
73
+ }
74
+ const padding = {
75
+ left: (props.layout.width - itemWidthSum) / 2,
76
+ right: (props.layout.width - itemWidthSum) / 2,
77
+ top: (props.layout.height - props.itemSizeInfo.height) / 2,
78
+ bottom: (props.layout.height - props.itemSizeInfo.height) / 2,
79
+ };
80
+
81
+ const fixPositionSlide = new FixPositionSlide();
82
+ const largeItemIndex = ref(props.initLargeIndex);
83
+ provide("largeItemIndex", largeItemIndex);
84
+ const provideData = () => {
85
+ const data = [];
86
+ for (let i = 0; i < props.datas.length; ++i) {
87
+ data.push({
88
+ width:
89
+ i == props.initLargeIndex
90
+ ? props.itemSizeInfo.largeWidth
91
+ : props.itemSizeInfo.smallWidth,
92
+ height: props.itemSizeInfo.height,
93
+ marginRight: props.itemSizeInfo.marginRight,
94
+ data: props.datas[i],
95
+ });
96
+ }
97
+ return data;
98
+ };
99
+
100
+ const measures = (data) => {
101
+ return {
102
+ width: data.width,
103
+ height: data.height,
104
+ marginRight: data.marginRight,
105
+ };
106
+ };
107
+
108
+ const _onEdge = (edgeInfo) => {
109
+ props.onEdge?.(edgeInfo);
110
+ };
111
+
112
+ onMounted(() => {});
113
+ </script>
114
+
115
+ <template>
116
+ <div>
117
+ <list-widget
118
+ :name="name"
119
+ :left="layout.left"
120
+ :top="layout.top"
121
+ :width="layout.width"
122
+ :height="layout.height"
123
+ :provideData="provideData"
124
+ :direction="HORIZONTAL"
125
+ :initFocusId="props.initLargeIndex"
126
+ :slideSetting="fixPositionSlide"
127
+ :measures="measures"
128
+ :padding="padding"
129
+ :onEdge="_onEdge"
130
+ :disableClip="true"
131
+ >
132
+ <template #renderItem="{ data, onAction, query }">
133
+ <item
134
+ :data="data"
135
+ :onAction="onAction"
136
+ :query="query"
137
+ :size="{
138
+ width: itemSizeInfo.smallWidth,
139
+ height: itemSizeInfo.height,
140
+ }"
141
+ :largeSize="{
142
+ width: itemSizeInfo.largeWidth,
143
+ height: itemSizeInfo.height,
144
+ }"
145
+ :duration="duration * 1000"
146
+ :onItemClick="onItemClick"
147
+ >
148
+ <template #small>
149
+ <slot name="itemSmall" :data="data.data"></slot>
150
+ </template>
151
+ <template #large>
152
+ <slot name="itemLarge" :data="data.data"></slot>
153
+ </template>
154
+ <template #right="{ width }">
155
+ <slot
156
+ name="itemRightEdge"
157
+ :itemSmallWidth="width"
158
+ :data="data.data"
159
+ ></slot>
160
+ </template>
161
+ <template #left>
162
+ <slot name="itemLeftEdge" :data="data.data"></slot>
163
+ </template>
164
+ </item>
165
+ </template>
166
+ </list-widget>
167
+ </div>
168
+ </template>
@@ -0,0 +1,89 @@
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: 1200, height: 90 }"
13
+ :tabPadding="{ left: 20, right: 20, top: 20, height: 20 }"
14
+ :contentLayout="{ left: 20, top: 100, width: 1280, height: 500 }"
15
+ :tagItemGap="10"
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: 370,
60
+ height: 300,
61
+ img: ironmanSmall,
62
+ },
63
+ {
64
+ width: 370,
65
+ height: 300,
66
+ img: spidermanSmall,
67
+ },
68
+ {
69
+ width: 370,
70
+ height: 300,
71
+ img: captainSmall,
72
+ },
73
+ ],
74
+ };
75
+ }
76
+
77
+ function contentOnFocus() {
78
+ console.log("content on focus");
79
+ focusHub.setFocus("contentPage");
80
+ }
81
+
82
+ function contentOnBlur() {
83
+ console.log("content on blur");
84
+ }
85
+
86
+ onMounted(() => {
87
+ focusHub.setFocus(name);
88
+ });
89
+ </script>