@shijiu/jsview-vue-samples 1.9.888 → 1.9.915

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 (185) hide show
  1. package/AnimPicture/App.vue +10 -10
  2. package/Basic/App.vue +1 -1
  3. package/Basic/components/FontStyle.css +4 -4
  4. package/Basic/components/anim/AnimKeyframeBasic.vue +1 -1
  5. package/Basic/components/anim/AnimKeyframeComposite.vue +2 -2
  6. package/Basic/components/anim/AnimTransition.vue +4 -4
  7. package/Basic/components/div/DivClip.vue +0 -39
  8. package/Basic/components/div/DivCssScoped.vue +1 -1
  9. package/Basic/components/div/DivLayout.vue +1 -1
  10. package/Basic/components/div/DivRadius.vue +4 -4
  11. package/Basic/components/img/ImageGroup.vue +2 -2
  12. package/Basic/components/img/ImgLayout.vue +78 -14
  13. package/Basic/components/text/TextDirection.vue +9 -9
  14. package/Basic/components/text/TextEmoji.vue +7 -2
  15. package/Basic/components/text/TextFontStyle.vue +4 -4
  16. package/Basic/components/text/TextGroup1.vue +1 -1
  17. package/Basic/components/text/TextGroup2.vue +2 -2
  18. package/BasicFocusControl/App.vue +2 -2
  19. package/BasicFocusControl/components/BaseBlock.vue +2 -2
  20. package/BasicFocusControl/components/MainArea.vue +2 -2
  21. package/BasicFocusControl/components/SideBar.vue +2 -2
  22. package/Collision/App.vue +16 -16
  23. package/ColorSpace/App.vue +11 -11
  24. package/CssPreprocessor/App.vue +70 -0
  25. package/CssPreprocessor/Less/App.vue +32 -0
  26. package/CssPreprocessor/Less/PanelData.js +51 -0
  27. package/CssPreprocessor/Less/components/less-group1/LessComments.vue +34 -0
  28. package/CssPreprocessor/Less/components/less-group1/LessConditionals.vue +32 -0
  29. package/CssPreprocessor/Less/components/less-group1/LessOperations.vue +24 -0
  30. package/CssPreprocessor/Less/components/less-group1/LessVariables.vue +48 -0
  31. package/CssPreprocessor/Less/components/less-group2/LessIteration.vue +32 -0
  32. package/CssPreprocessor/Less/components/less-group2/LessMethods.vue +27 -0
  33. package/CssPreprocessor/Less/components/less-group3/LessExtends.vue +32 -0
  34. package/CssPreprocessor/Less/components/less-group3/LessNesting.vue +63 -0
  35. package/CssPreprocessor/Less/components/less-group4/LessKeyframes.vue +40 -0
  36. package/CssPreprocessor/Less/components/less-group4/LessMaps.vue +33 -0
  37. package/CssPreprocessor/Less/components/less-group4/LessMixins.vue +33 -0
  38. package/CssPreprocessor/Less/components/less-group5/LessImporting.vue +34 -0
  39. package/CssPreprocessor/Less/components/less-group5/TextSettings.less +4 -0
  40. package/CssPreprocessor/Scss/App.vue +32 -0
  41. package/CssPreprocessor/Scss/PanelData.js +51 -0
  42. package/CssPreprocessor/Scss/components/scss-group1/ScssComments.vue +34 -0
  43. package/CssPreprocessor/Scss/components/scss-group1/ScssConditionals.vue +36 -0
  44. package/CssPreprocessor/Scss/components/scss-group1/ScssOperations.vue +30 -0
  45. package/CssPreprocessor/Scss/components/scss-group1/ScssVariables.vue +48 -0
  46. package/CssPreprocessor/Scss/components/scss-group2/ScssIteration.vue +36 -0
  47. package/CssPreprocessor/Scss/components/scss-group2/ScssMethods.vue +84 -0
  48. package/CssPreprocessor/Scss/components/scss-group3/ScssExtends.vue +34 -0
  49. package/CssPreprocessor/Scss/components/scss-group3/ScssNesting.vue +75 -0
  50. package/CssPreprocessor/Scss/components/scss-group4/ScssKeyframes.vue +40 -0
  51. package/CssPreprocessor/Scss/components/scss-group4/ScssMaps.vue +35 -0
  52. package/CssPreprocessor/Scss/components/scss-group4/ScssMixins.vue +33 -0
  53. package/CssPreprocessor/Scss/components/scss-group5/ScssImporting.vue +34 -0
  54. package/CssPreprocessor/Scss/components/scss-group5/TextSettings.scss +4 -0
  55. package/CssPreprocessor/Stylus/App.vue +32 -0
  56. package/CssPreprocessor/Stylus/PanelData.js +51 -0
  57. package/CssPreprocessor/Stylus/components/stylus-group1/StylusComments.vue +34 -0
  58. package/CssPreprocessor/Stylus/components/stylus-group1/StylusConditionals.vue +36 -0
  59. package/CssPreprocessor/Stylus/components/stylus-group1/StylusOperations.vue +30 -0
  60. package/CssPreprocessor/Stylus/components/stylus-group1/StylusVariables.vue +47 -0
  61. package/CssPreprocessor/Stylus/components/stylus-group2/StylusIteration.vue +34 -0
  62. package/CssPreprocessor/Stylus/components/stylus-group2/StylusMethods.vue +78 -0
  63. package/CssPreprocessor/Stylus/components/stylus-group3/StylusExtends.vue +34 -0
  64. package/CssPreprocessor/Stylus/components/stylus-group3/StylusNesting.vue +63 -0
  65. package/CssPreprocessor/Stylus/components/stylus-group4/StylusKeyframes.vue +40 -0
  66. package/CssPreprocessor/Stylus/components/stylus-group4/StylusMaps.vue +33 -0
  67. package/CssPreprocessor/Stylus/components/stylus-group4/StylusMixins.vue +33 -0
  68. package/CssPreprocessor/Stylus/components/stylus-group5/StylusImporting.vue +34 -0
  69. package/CssPreprocessor/Stylus/components/stylus-group5/TextSettings.styl +4 -0
  70. package/CssPreprocessor/utils/ContentBlock.vue +43 -0
  71. package/CssPreprocessor/utils/ContentList.vue +34 -0
  72. package/CssPreprocessor/utils/FontStyle.css +19 -0
  73. package/CssPreprocessor/utils/Panel.vue +49 -0
  74. package/CssPreprocessor/utils/TitleBar.vue +29 -0
  75. package/DemoHomepage/App.vue +46 -11
  76. package/DemoHomepage/components/Dialog.vue +15 -15
  77. package/DemoHomepage/router.js +20 -12
  78. package/DemoHomepage/views/Homepage.vue +90 -102
  79. package/DivMetroPerformance/App.vue +150 -0
  80. package/DivMetroPerformance/Item.vue +58 -0
  81. package/DivMetroPerformance/assets/bg.jpg +0 -0
  82. package/DivMetroPerformance/assets/coupon_content.png +0 -0
  83. package/DivMetroPerformance/assets/coupon_left.png +0 -0
  84. package/DivMetroPerformance/assets/coupon_mid.png +0 -0
  85. package/DivMetroPerformance/assets/coupon_right.png +0 -0
  86. package/DivMetroPerformance/assets/focus_border.png +0 -0
  87. package/DivMetroPerformance/assets/holder_logo.png +0 -0
  88. package/DivMetroPerformance/assets/jrbm.png +0 -0
  89. package/DivMetroPerformance/assets/line_left.png +0 -0
  90. package/DivMetroPerformance/assets/line_mid.png +0 -0
  91. package/DivMetroPerformance/assets/line_right.png +0 -0
  92. package/DivMetroPerformance/assets/loading.png +0 -0
  93. package/DivMetroPerformance/assets/logo.png +0 -0
  94. package/DivMetroPerformance/assets/mcjx.png +0 -0
  95. package/DivMetroPerformance/assets/tao.png +0 -0
  96. package/DivMetroPerformance/assets/tmall.png +0 -0
  97. package/DivMetroPerformance/border.png +0 -0
  98. package/DivMetroPerformance/components/ContentItem.vue +385 -0
  99. package/DivMetroPerformance/components/MyTab.vue +129 -0
  100. package/DivMetroPerformance/data.js +124 -0
  101. package/DivMetroPerformance/utils/GridItem.vue +28 -0
  102. package/DivMetroPerformance/utils/GridPlate.vue +85 -0
  103. package/FilterDemo/AnimatePic.vue +3 -3
  104. package/FilterDemo/App.vue +3 -3
  105. package/FlipCard/App.vue +2 -2
  106. package/FlipCard/FlipCard.vue +2 -2
  107. package/GridDemo/Item.vue +13 -13
  108. package/HashHistory/App.vue +0 -1
  109. package/HashHistory/components/Item.vue +2 -2
  110. package/HashHistory/views/MainPage.vue +1 -1
  111. package/HashHistory/views/SubPage.vue +2 -2
  112. package/ImpactStop/App.vue +9 -11
  113. package/Input/InputPanel.vue +2 -4
  114. package/LongImage/App.vue +2 -2
  115. package/LongImage/Button.vue +1 -1
  116. package/LongImage/ButtonItem.vue +1 -1
  117. package/LongText/App.vue +3 -3
  118. package/LongText/Button.vue +1 -1
  119. package/LongText/ButtonItem.vue +1 -1
  120. package/LongText/LongTextScroll.vue +4 -4
  121. package/Marquee/longText.js +0 -2
  122. package/MaskClip/App.vue +4 -4
  123. package/MediaDemo/App.vue +127 -0
  124. package/MediaDemo/assets/audio-poster.png +0 -0
  125. package/MediaDemo/components/Button.vue +69 -0
  126. package/MediaDemo/components/Controllor.vue +279 -0
  127. package/MediaDemo/components/StatusBar.vue +100 -0
  128. package/MediaDemo/components/frames/AudioFrame.vue +39 -0
  129. package/MediaDemo/components/frames/AudioPoster.vue +48 -0
  130. package/MediaDemo/components/frames/MediaFrame.vue +153 -0
  131. package/MediaDemo/components/frames/VideoFrame.vue +39 -0
  132. package/MetroWidgetDemos/Advanced/ButtonItem.vue +4 -4
  133. package/MetroWidgetDemos/Advanced/widgets/Item.vue +5 -5
  134. package/MetroWidgetDemos/Advanced/widgets/WidgetItem.vue +2 -2
  135. package/MetroWidgetDemos/Advanced/widgets/Widgets.vue +57 -56
  136. package/MetroWidgetDemos/Item.vue +4 -5
  137. package/MetroWidgetDemos/PerformanceTest/App.vue +3 -3
  138. package/MetroWidgetDemos/PerformanceTest/components/ContentItem.vue +26 -26
  139. package/MetroWidgetDemos/PerformanceTest/components/MyTab.vue +15 -15
  140. package/MetroWidgetDemos/PingPong/AppPage.vue +2 -2
  141. package/MetroWidgetDemos/PingPong/TabItem.vue +2 -2
  142. package/MetroWidgetDemos/PingPong/ViewSwiper.vue +9 -9
  143. package/MetroWidgetDemos/Simple/RelativeTemplate.vue +2 -2
  144. package/MetroWidgetDemos/WidgetItem.vue +2 -2
  145. package/NinePatchDemo/App.vue +3 -3
  146. package/NinePatchDemo/Item.vue +5 -5
  147. package/Preload/App.vue +5 -5
  148. package/Preload/Item.vue +1 -1
  149. package/QrcodeDemo/App.vue +3 -3
  150. package/ScaleDownNeon/App.vue +9 -9
  151. package/SoundPool/App.vue +6 -9
  152. package/SprayView/App.vue +22 -22
  153. package/SpriteImage/App.vue +4 -4
  154. package/Swiper/App.vue +2 -8
  155. package/TextBox/App.vue +1 -2
  156. package/TextBox/RenderCenter.vue +16 -16
  157. package/TextBox/RenderLeft.vue +16 -16
  158. package/TextBox/RenderOneLine.vue +12 -12
  159. package/TextBox/RenderRight.vue +16 -16
  160. package/TextShadowDemo/App.vue +4 -4
  161. package/TextureAnimation/App.vue +1 -17
  162. package/TextureAnimation/App2.vue +3 -3
  163. package/TextureSize/App.vue +8 -8
  164. package/ThrowMoveDemo/AccelerateDemo.vue +4 -4
  165. package/ThrowMoveDemo/LRParabolicDemo.vue +4 -4
  166. package/ThrowMoveDemo/TargetDemo.vue +4 -4
  167. package/ThrowMoveDemo/UDParabolicDemo.vue +4 -4
  168. package/TouchSample/App.vue +2 -2
  169. package/TouchSample/Item.vue +2 -2
  170. package/TouchSample/MetroWidgetHorizontal.vue +3 -3
  171. package/TouchSample/MetroWidgetVertical.vue +3 -3
  172. package/TouchSample/TouchContainerHorizontal.vue +2 -2
  173. package/TouchSample/TouchContainerVertical.vue +2 -2
  174. package/TransitPage/App.vue +1 -1
  175. package/VideoDemo/App.vue +4 -4
  176. package/VideoDemo/components/Button.vue +1 -1
  177. package/VideoDemo/components/Controllor.vue +2 -2
  178. package/VideoDemo/components/VideoFrame.vue +1 -1
  179. package/VisibleSensorDemo/App.vue +7 -7
  180. package/assets/bmpDemo.bmp +0 -0
  181. package/assets/jpegDemo.jpeg +0 -0
  182. package/assets/pngDemo.png +0 -0
  183. package/assets/pngNoAlphaDemo.png +0 -0
  184. package/assets/webpDemo.webp +0 -0
  185. package/package.json +6 -1
@@ -0,0 +1,127 @@
1
+ <script>
2
+ import { provide, reactive, watch } from 'vue'
3
+ import { Options, Vue } from "vue-class-component";
4
+ import AudioFrame from "./components/frames/AudioFrame";
5
+ import VideoFrame from "./components/frames/VideoFrame";
6
+ import Controllor from "./components/Controllor";
7
+ import StatusBar from "./components/StatusBar";
8
+
9
+ @Options({
10
+ components: {
11
+ AudioFrame,
12
+ VideoFrame,
13
+ Controllor,
14
+ StatusBar,
15
+ },
16
+ })
17
+
18
+ class App extends Vue {
19
+ constructor(props) {
20
+ super(props);
21
+
22
+ this.mediaCtrl = reactive({
23
+ type: 'video',
24
+ autoplay: true,
25
+ seek: 0,
26
+ loop: false,
27
+ mute: false,
28
+ volume: 0,
29
+ playbackRate: 1,
30
+
31
+ playTrigger: 0,
32
+ loadTrigger: 0,
33
+ })
34
+ this.mediaTime = reactive({
35
+ currentTime: 0,
36
+ duration: 0,
37
+ })
38
+ this.mediaStatus = reactive({
39
+ playState: '',
40
+ playbackRate: '',
41
+ objectFit: '',
42
+ volume: '',
43
+ playing: false,
44
+ })
45
+ this.videoCtrl = reactive({
46
+ layout: {},
47
+ objectFit: null,
48
+ visibility: 'visible',
49
+ })
50
+
51
+ const updateCaption = () => {
52
+ this.caption = (this.mediaCtrl.type == 'audio' ? App.Caption.audioInfo : App.Caption.videoInfo);
53
+ };
54
+ watch(() => this.mediaCtrl.type, updateCaption);
55
+ updateCaption();
56
+
57
+ provide('mediaCtrl', this.mediaCtrl)
58
+ provide('mediaTime', this.mediaTime)
59
+ provide('mediaStatus', this.mediaStatus)
60
+ provide('videoCtrl', this.videoCtrl)
61
+ }
62
+
63
+ static Caption = {
64
+ videoInfo: "名称: Video\n"
65
+ + "功能描述:\n"
66
+ + "1. 播放 / 暂停\n"
67
+ + "2. 前进 / 后退\n"
68
+ + "3. 时间 / 时长\n"
69
+ + "4. 循环 / 静音 / 倍速\n"
70
+ + "5. ObjectFit调整\n",
71
+ audioInfo: "名称: Audio\n"
72
+ + "功能描述:\n"
73
+ + "1. 播放 / 暂停\n"
74
+ + "2. 前进 / 后退\n"
75
+ + "3. 时间 / 时长 / 倍速\n"
76
+ + "4. 循环 / 静音\n"
77
+ }
78
+ }
79
+
80
+ export default App;
81
+ </script>
82
+
83
+ <template>
84
+ <div
85
+ :style="{
86
+ top: 0, left: 0,
87
+ width: 1280, height: 720,
88
+ backgroundColor: 'rgb(222,211,140,0.5)'
89
+ }"
90
+ >
91
+
92
+ <AudioFrame v-if="mediaCtrl.type == 'audio'"/>
93
+ <VideoFrame v-else />
94
+
95
+ <!-- :key="mediaCtrl.type" => JsView bug,当mediaCtrl.type属性变化时,为了保证显示在VideoFrame前面 -->
96
+ <div class="caption" :key="mediaCtrl.type">
97
+ {{ caption }}
98
+ </div>
99
+ <Controllor class="controllor"/>
100
+ <StatusBar class="statusbar"/>
101
+ </div>
102
+ </template>
103
+
104
+ <style scoped>
105
+ .caption {
106
+ text-align: left;
107
+ font-size: 24;
108
+ line-height: 30;
109
+ color: #FFFFFF;
110
+ left: 40;
111
+ top: 20;
112
+ width: 300;
113
+ height: 210;
114
+ background-color: rgba(27,38,151,0.6);
115
+ }
116
+
117
+ .controllor {
118
+ left: 40;
119
+ top: 540;
120
+ }
121
+
122
+ .statusbar {
123
+ left: 40;
124
+ top: 650;
125
+ }
126
+
127
+ </style>
@@ -0,0 +1,69 @@
1
+ <script>
2
+ import { Options, Vue } from "vue-class-component";
3
+
4
+ @Options({
5
+ props: {
6
+ style: Object,
7
+ autoFocus: Boolean,
8
+ name: String,
9
+ onClick: Function,
10
+ }
11
+ })
12
+
13
+ class Button extends Vue {
14
+ constructor(props) {
15
+ super(props);
16
+
17
+ this.hasFocused = false;
18
+ }
19
+
20
+ onFocus() {
21
+ this.hasFocused = true;
22
+ }
23
+
24
+ onBlur() {
25
+ this.hasFocused = false;
26
+ }
27
+
28
+ onKeyDown(ev) {
29
+ if(ev.keyCode === 13) { // Enter
30
+ this.onClick?.();
31
+ return true;
32
+ }
33
+ return false;
34
+ }
35
+
36
+ getAction() {
37
+ return {
38
+ onFocus: this.onFocus,
39
+ onBlur: this.onBlur,
40
+ onKeyDown: this.onKeyDown
41
+ }
42
+ }
43
+ }
44
+
45
+ export default Button;
46
+ </script>
47
+
48
+ <template>
49
+ <jsv-focus-block :name="name" :autoFocus="autoFocus?'':undefined"
50
+ :onAction="getAction()"
51
+ >
52
+ <div class="item"
53
+ :style="{
54
+ ...style,
55
+ backgroundColor: hasFocused ? '#FFFF00' : '#A8A8A8',
56
+ }"
57
+ >
58
+ <slot/>
59
+ </div>
60
+ </jsv-focus-block>
61
+ </template>
62
+
63
+ <style scoped>
64
+ .item {
65
+ text-align: center;
66
+ font-size: 24;
67
+ line-height: 40;
68
+ }
69
+ </style>
@@ -0,0 +1,279 @@
1
+ <script>
2
+ import { inject } from 'vue'
3
+ import { Options, Vue } from "vue-class-component";
4
+ import Button from "./Button.vue";
5
+
6
+ @Options({
7
+ props: {
8
+ style: { type: Object, default: {width:1400,height:50} },
9
+ },
10
+ components: {
11
+ Button,
12
+ },
13
+ })
14
+
15
+ class Controllor extends Vue {
16
+ constructor(props) {
17
+ super(props);
18
+
19
+ this.mediaCtrl = inject('mediaCtrl');
20
+ this.mediaTime = inject('mediaTime');
21
+ this.mediaStatus = inject('mediaStatus');
22
+ this.videoCtrl = inject('videoCtrl');
23
+
24
+ this.buttonList = this.getButtonList();
25
+
26
+ this.playbackRateData = [
27
+ { name: "1.0", playbackRate: 1.0 },
28
+ { name: "2.0", playbackRate: 2.0 },
29
+ { name: "4.0", playbackRate: 4.0 },
30
+ { name: "0.5", playbackRate: 0.5 },
31
+ { name: "0.25", playbackRate: 0.25 },
32
+ { name: "-1.0", playbackRate: -1.0 },
33
+ ];
34
+ this.playbackRateIndex = 0;
35
+
36
+ this.objectFitData = [
37
+ { name: "contain-horizontal", objectFit: "contain", width: 1200 },
38
+ { name: "contain-vertical", objectFit: "contain", width: 400 },
39
+ { name: "fill", objectFit: "fill", width: 1200 },
40
+ { name: "cover-horizontal", objectFit: "cover", width: 1200 },
41
+ { name: "cover-vertical", objectFit: "cover", width: 400 },
42
+ ];
43
+ this.objectFitIndex = 0;
44
+
45
+ this.buttonRowCount = 7;
46
+ this.focusedItemIndex = 0;
47
+ }
48
+
49
+ created() {
50
+ this.setPlaybackRate(0);
51
+ this.setObjectFit(0);
52
+ }
53
+
54
+ onKeyDown(ev) {
55
+ // 8:Backspace, 27:Escape, 10000:盒子返回键
56
+ if(ev.keyCode == 8 || ev.keyCode == 27 || ev.keyCode == 10000) {
57
+ this.$router?.go(-1); // 有router时,回退
58
+ return true;
59
+ }
60
+
61
+ let focusStep = 0;
62
+ let autoFindNext = false;
63
+ switch (ev.keyCode) {
64
+ case 37: // Left
65
+ focusStep = -1;
66
+ autoFindNext = true;
67
+ break;
68
+ case 39: // Right
69
+ focusStep = 1;
70
+ autoFindNext = true;
71
+ break;
72
+ case 38: // Up
73
+ focusStep = -this.buttonRowCount;
74
+ break;
75
+ case 40: // Down
76
+ focusStep = this.buttonRowCount;
77
+ break;
78
+ default:
79
+ break;
80
+ }
81
+
82
+ const buttonData = this.getButtonData();
83
+ const buttonAllCount = this.buttonRowCount * 2;
84
+ let newFocusIdx = this.focusedItemIndex;
85
+ let nextFocusItem = null;
86
+ while(true) {
87
+ newFocusIdx = (newFocusIdx + focusStep + buttonAllCount) % buttonAllCount;
88
+ if(!buttonData[newFocusIdx]?.name) {
89
+ if(autoFindNext) {
90
+ continue;
91
+ } else {
92
+ break;
93
+ }
94
+ }
95
+
96
+ nextFocusItem = ev.ownerNode.findBlockByName('controllor.' + 'btn-' + newFocusIdx);
97
+ break;
98
+ };
99
+
100
+ if(nextFocusItem) {
101
+ nextFocusItem.requestFocus();
102
+ this.focusedItemIndex = newFocusIdx;
103
+ return true;
104
+ }
105
+
106
+ return false;
107
+ }
108
+
109
+ getButtonList() {
110
+ const buttonList = [{
111
+ name: "To AudioMode",
112
+ onClick: () => {
113
+ this.mediaCtrl.type = (this.mediaCtrl.type == 'audio' ? 'video' : 'audio');
114
+ this.mediaCtrl.autoplay = true; // 自动播放
115
+ this.mediaCtrl.mute = false; // 关闭静音
116
+ this.mediaCtrl.loop = false; // 关闭循环
117
+ this.mediaTime.currentTime = 0;
118
+ this.mediaTime.duration = 0;
119
+ this.mediaCtrl.playTrigger = 0; // 停止并初始化播放
120
+ this.setPlaybackRate(0);
121
+ this.setObjectFit(0);
122
+ this.videoCtrl.visibility = 'visible';
123
+ if(this.mediaCtrl.type == 'audio') {
124
+ this.mediaStatus.objectFit = '';
125
+ this.videoCtrl.visibility = '';
126
+ }
127
+
128
+ this.focusedItemIndex = 0;
129
+ },
130
+ isModeButton: true,
131
+ }, {
132
+ name: "Play",
133
+ onClick: () => {
134
+ this.mediaCtrl.playTrigger = ++this.mediaCtrl.playTrigger; /* 为了触发ref更新 */
135
+ },
136
+ isPlayButton: true,
137
+ }, {
138
+ name: "Rewind <<",
139
+ onClick: () => {
140
+ this.mediaCtrl.seek = (this.mediaCtrl.seek !== -10 ? -10 : -10.1/* 为了触发ref更新 */);
141
+ }
142
+ }, {
143
+ name: "Forward >>",
144
+ onClick: () => {
145
+ this.mediaCtrl.seek = (this.mediaCtrl.seek !== +10 ? +10 : +10.1/* 为了触发ref更新 */);
146
+ }
147
+ }, {
148
+ name: "Reload",
149
+ onClick: () => {
150
+ this.mediaCtrl.loadTrigger = ++this.mediaCtrl.loadTrigger; /* 为了触发ref更新 */
151
+ },
152
+ }, {
153
+ name: "Loop Off",
154
+ onClick: () => {
155
+ this.mediaCtrl.loop = !this.mediaCtrl.loop;
156
+ },
157
+ isLoopButton: true,
158
+ }, {
159
+ name: "ObjectFit",
160
+ onClick: this.setObjectFit.bind(this)
161
+ }, {
162
+ // 空,按钮对其用
163
+ }, {
164
+ name: "Mute Off",
165
+ onClick: () => {
166
+ this.mediaCtrl.mute = !this.mediaCtrl.mute;
167
+ },
168
+ isMuteButton: true,
169
+ }, {
170
+ name: "Volume",
171
+ onClick: () => {
172
+ this.mediaCtrl.volume = (this.mediaCtrl.volume !== 0.2 ? 0.2 : 0.21/* 为了触发ref更新 */);
173
+ }
174
+ }, {
175
+ name: "Rate",
176
+ onClick: this.setPlaybackRate.bind(this)
177
+ }, {
178
+ name: "Visibility",
179
+ onClick: () => {
180
+ this.videoCtrl.visibility = (this.videoCtrl.visibility != 'visible' ? 'visible' : 'hidden');
181
+ },
182
+ },
183
+ ];
184
+
185
+ return buttonList;
186
+ }
187
+
188
+ getButtonData() {
189
+ const buttonWidth = 158;
190
+ const buttonHeight = 40;
191
+ const buttonSpacing = 15;
192
+
193
+ let data = [];
194
+ const length = this.buttonList.length;
195
+ for(let idx = 0; idx < length; idx++) {
196
+ let button = this.buttonList[idx];
197
+ if(this.mediaCtrl.type == 'audio'
198
+ && (button.name == 'ObjectFit'
199
+ || button.name == 'Visibility')) { // 只有video方式可以做ObjectFit和visibility
200
+ button = {};
201
+ }
202
+
203
+ data.push({
204
+ ...button,
205
+ layout: {
206
+ left: (buttonWidth + buttonSpacing) * (idx % this.buttonRowCount),
207
+ top: (buttonHeight + buttonSpacing) * Math.floor(idx / this.buttonRowCount),
208
+ width: buttonWidth,
209
+ height: buttonHeight,
210
+ }
211
+ });
212
+ }
213
+ return data;
214
+ }
215
+
216
+ setPlaybackRate(index) {
217
+ if(typeof index === 'number') {
218
+ this.playbackRateIndex = index;
219
+ } else {
220
+ this.playbackRateIndex = (++this.playbackRateIndex % this.playbackRateData.length);
221
+ }
222
+ const data = this.playbackRateData[this.playbackRateIndex];
223
+ this.mediaStatus.playbackRate = data.name;
224
+ this.mediaCtrl.playbackRate = data.playbackRate;
225
+ }
226
+
227
+ setObjectFit(index) {
228
+ if(typeof index === 'number') {
229
+ this.objectFitIndex = index;
230
+ } else {
231
+ this.objectFitIndex = (++this.objectFitIndex % this.objectFitData.length);
232
+ }
233
+ const data = this.objectFitData[this.objectFitIndex];
234
+ this.mediaStatus.objectFit = data.name;
235
+ this.videoCtrl.objectFit = data.objectFit;
236
+ this.videoCtrl.layout = {
237
+ left: (1280 - data.width) / 2, top: 20,
238
+ width: data.width, height: 500,
239
+ }
240
+ }
241
+
242
+ getShowName(item) {
243
+ if(item.isModeButton) {
244
+ return this.mediaCtrl.type == 'audio' ? "To VideoMode" : "To AudioMode";
245
+ } else if(item.isPlayButton) {
246
+ return this.mediaStatus.playing ? 'Pause' : 'Play'
247
+ } else if(item.isLoopButton) {
248
+ return this.mediaCtrl.loop ? 'Loop Off' : 'Loop On'
249
+ } else if(item.isMuteButton) {
250
+ return this.mediaCtrl.mute ? 'Mute Off' : 'Mute On'
251
+ }
252
+
253
+ return item.name;
254
+ }
255
+ }
256
+
257
+ export default Controllor;
258
+ </script>
259
+
260
+ <template>
261
+ <div :style="style" :key="mediaCtrl.type + mediaCtrl.loop + mediaCtrl.mute + mediaStatus.playing">
262
+ <jsv-focus-block namespace="controllor" :onKeyDown="onKeyDown">
263
+ <div v-for="(item,index) in getButtonData()" :key="index">
264
+ <Button v-if="item.name"
265
+ :style="{ left: item.layout.left, top: item.layout.top,
266
+ width:item.layout.width, height:item.layout.height }"
267
+ :autoFocus="index === focusedItemIndex"
268
+ :name="'btn-' + index"
269
+ :onClick="item.onClick"
270
+ >
271
+ {{ getShowName(item) }}
272
+ </Button>
273
+ </div>
274
+ </jsv-focus-block>
275
+ </div>
276
+ </template>
277
+
278
+ <style scoped>
279
+ </style>
@@ -0,0 +1,100 @@
1
+ <script>
2
+ import { inject } from 'vue'
3
+ import { Options, Vue } from "vue-class-component";
4
+
5
+ @Options({
6
+ })
7
+ class StatusBar extends Vue {
8
+ constructor(props) {
9
+ super(props);
10
+
11
+ this.mediaCtrl = inject('mediaCtrl');
12
+ this.mediaTime = inject('mediaTime');
13
+ this.mediaStatus = inject('mediaStatus');
14
+ this.videoCtrl = inject('videoCtrl');
15
+ }
16
+ }
17
+
18
+ export default StatusBar;
19
+ </script>
20
+
21
+ <template>
22
+ <div>
23
+ <div class="text progress">
24
+ {{ 'progress:' + Math.ceil(mediaTime.currentTime) + '/' + Math.ceil(mediaTime.duration) }}
25
+ </div>
26
+ <div class="text mute">
27
+ {{ mediaCtrl.mute ? 'muted' : '-' }}
28
+ </div>
29
+ <div class="text volume">
30
+ {{ 'volume:' + mediaStatus.volume }}
31
+ </div>
32
+ <div class="text rate">
33
+ {{ mediaStatus.playbackRate }}
34
+ </div>
35
+ <div class="text visibility" :key="videoCtrl.visibility">
36
+ {{ videoCtrl.visibility }}
37
+ </div>
38
+ <div class="text loop">
39
+ {{ mediaCtrl.loop ? 'looping' : '-' }}
40
+ </div>
41
+ <div class="text objectFit" :key="mediaStatus.objectFit">
42
+ {{ mediaStatus.objectFit }}
43
+ </div>
44
+ <div class="text status">
45
+ {{ 'status: ' + mediaStatus.playState }}
46
+ </div>
47
+ </div>
48
+ </template>
49
+
50
+ <style scoped>
51
+ .text {
52
+ color: #FF0000;
53
+ font-size: 24;
54
+ width: 158;
55
+ height: 40;
56
+ }
57
+
58
+ .progress {
59
+ left: 0;
60
+ width: 300;
61
+ }
62
+
63
+ .mute {
64
+ left: 173; /* (158+15)*1 */
65
+ text-align: center;
66
+ }
67
+
68
+ .volume {
69
+ left: 346; /* (158+15)*2 */
70
+ text-align: center;
71
+ }
72
+
73
+ .rate {
74
+ left: 519; /* (158+15)*3 */
75
+ text-align: center;
76
+ }
77
+
78
+ .visibility {
79
+ left: 692; /* (158+15)*4 */
80
+ text-align: center;
81
+ }
82
+
83
+ .loop {
84
+ left: 865; /* (158+15)*5 */
85
+ text-align: center;
86
+ }
87
+
88
+ .objectFit {
89
+ left: 1020; /* (158+15)*6-x */
90
+ width: 190;
91
+ text-align: center;
92
+ }
93
+
94
+ .status {
95
+ left: 0;
96
+ top: 30;
97
+ width: 800;
98
+ }
99
+
100
+ </style>
@@ -0,0 +1,39 @@
1
+ <script>
2
+ import { inject, watch } from 'vue'
3
+ import { Options, Vue } from "vue-class-component";
4
+ import AudioPoster from "./AudioPoster";
5
+ import MediaFrame from "./MediaFrame";
6
+
7
+ @Options({
8
+ components: {
9
+ AudioPoster,
10
+ MediaFrame,
11
+ },
12
+ })
13
+ class AudioFrame extends Vue {
14
+ constructor(props) {
15
+ super(props);
16
+
17
+ this.mediaStatus = inject('mediaStatus');
18
+
19
+ this.audioUrl = "http://qcast-image.oss-cn-qingdao.aliyuncs.com/JsViewVideo/VideoTestSample/demo_test.mp3";
20
+ // is.audioUrl = "http://192.168.1.99/videos/empty.mp3";
21
+ }
22
+ }
23
+
24
+ export default AudioFrame;
25
+ </script>
26
+
27
+ <template>
28
+ <MediaFrame
29
+ tagName="audio"
30
+ :src="audioUrl"
31
+ />
32
+
33
+ <AudioPoster
34
+ :playing="this.mediaStatus.playing"
35
+ />
36
+ </template>
37
+
38
+ <style scoped>
39
+ </style>
@@ -0,0 +1,48 @@
1
+ <script>
2
+ import { inject, watch } from 'vue'
3
+ import { Options, Vue } from "vue-class-component";
4
+ import posterImgPath from '../../assets/audio-poster.png';
5
+
6
+ @Options({
7
+ props: {
8
+ playing: Boolean
9
+ }
10
+ })
11
+ class AudioPoster extends Vue {
12
+ constructor(props) {
13
+ super(props);
14
+
15
+ this.posterImgPath = posterImgPath;
16
+ }
17
+
18
+ onPlayPauseChanged(play) {
19
+ console.warn('onPlayPauseChanged() ' + play);
20
+ }
21
+ }
22
+
23
+ export default AudioPoster;
24
+ </script>
25
+
26
+ <template>
27
+ <div
28
+ :style="{
29
+ left: 380,
30
+ top: 10,
31
+ width: 512,
32
+ height: 512,
33
+ backgroundImage: posterImgPath,
34
+ animation: (playing ? 'PosterRotate 6s infinite linear' : null),
35
+ }"
36
+ />
37
+ </template>
38
+
39
+ <style scoped>
40
+ @keyframes PosterRotate {
41
+ from {
42
+ transform: rotate3d(0, 0, 1, 0deg);
43
+ }
44
+ to {
45
+ transform: rotate3d(0, 0, 1, 360deg);
46
+ }
47
+ }
48
+ </style>