@shijiu/jsview-vue-samples 2.1.482-test.0 → 2.2.128
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.
- package/BakeViewDemo/AnimatePic.vue +93 -0
- package/BakeViewDemo/App.vue +109 -0
- package/ClickDivDemo/App.vue +150 -0
- package/DemoHomepage/components/Dialog.vue +37 -11
- package/DemoHomepage/components/TabFrame.vue +8 -1
- package/DemoHomepage/router.js +76 -34
- package/DemoHomepage/views/Homepage.vue +30 -13
- package/FocusMoveStyle/App.vue +21 -4
- package/FocusMoveStyle/FoldableItem.vue +39 -12
- package/FreeMoveChildAttract/App.vue +105 -0
- package/FreeMoveLink/App.vue +55 -0
- package/FreeMoveResize/App.vue +102 -0
- package/LongText/App.vue +1 -3
- package/LongText/LongTextScroll.vue +124 -67
- package/LongTextLatex/App.vue +93 -0
- package/LongTextLatex/Button.vue +50 -0
- package/LongTextLatex/ButtonItem.vue +44 -0
- package/LongTextLatex/LongTextScroll.vue +189 -0
- package/LongTextLatex/Scroll.vue +14 -0
- package/Marquee/longText.js +1 -1
- package/MetroWidgetDemos/MassiveItems/App.vue +87 -0
- package/MetroWidgetDemos/MassiveItems/ContentItem.vue +388 -0
- package/MetroWidgetDemos/MassiveItems/Item.vue +203 -0
- package/MetroWidgetDemos/MassiveItems/WidgetItem.vue +101 -0
- package/MetroWidgetDemos/MassiveItems/data.js +17 -0
- package/MetroWidgetDemos/PingPong/AppPage.vue +19 -9
- package/MetroWidgetDemos/SeamlessSlide/App.vue +156 -0
- package/MetroWidgetDemos/SeamlessSlide/ControlItem.vue +45 -0
- package/MetroWidgetDemos/SeamlessSlide/Controller.vue +110 -0
- package/MetroWidgetDemos/SeamlessSlide/Item.vue +43 -0
- package/MetroWidgetDemos/routeList.js +12 -0
- package/SceneTransition/App.vue +10 -2
- package/ScrollBoxTest/App.vue +160 -0
- package/TestNativeSharedView/App.vue +166 -73
- package/TextureAnimation/App2.vue +52 -7
- package/TombSweepingDayTest/App.vue +11 -0
- package/TombSweepingDayTest/Raining/Rain.vue +69 -0
- package/TombSweepingDayTest/Raining/RainScene.vue +131 -0
- package/package.json +1 -1
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
JsvNativeSharedDiv,
|
|
4
|
+
JsvFocusBlock,
|
|
5
|
+
jJsvRuntimeBridge,
|
|
6
|
+
enableNativeViewListener,
|
|
7
|
+
disableNativeViewListener,
|
|
8
|
+
} from "jsview";
|
|
9
|
+
import { onBeforeUnmount, onMounted, reactive, watch, shallowRef } from "vue";
|
|
4
10
|
|
|
5
11
|
let state = reactive({
|
|
6
12
|
outX: 20,
|
|
@@ -18,29 +24,35 @@ let _TestData = [
|
|
|
18
24
|
let _Index = 0;
|
|
19
25
|
|
|
20
26
|
//给两个div给定不同的响应式变量
|
|
21
|
-
let view1 = shallowRef(
|
|
22
|
-
let view2 = shallowRef(
|
|
23
|
-
let isShow=shallowRef(false)
|
|
24
|
-
let isStop=shallowRef(false)
|
|
27
|
+
let view1 = shallowRef("null");
|
|
28
|
+
let view2 = shallowRef("null");
|
|
29
|
+
let isShow = shallowRef(false);
|
|
30
|
+
let isStop = shallowRef(false);
|
|
25
31
|
//创造出需要的四个属性的对象
|
|
26
32
|
const obj = (newValue) => {
|
|
27
|
-
const resultObj = {}
|
|
28
|
-
const newObj = JSON.parse(
|
|
33
|
+
const resultObj = {};
|
|
34
|
+
const newObj = JSON.parse(
|
|
35
|
+
newValue
|
|
36
|
+
.replace(/(\w+)\=/g, '"$1":')
|
|
37
|
+
.replace(/'/g, '"')
|
|
38
|
+
.replace(/^Bundle\[/, "")
|
|
39
|
+
.replace(/\]$/, "")
|
|
40
|
+
);
|
|
29
41
|
for (const key in newObj) {
|
|
30
|
-
if (key ==
|
|
42
|
+
if (key == "height" || key == "width" || key == "x" || key == "y") {
|
|
31
43
|
resultObj[key] = newObj[key];
|
|
32
44
|
}
|
|
33
45
|
}
|
|
34
|
-
return resultObj
|
|
35
|
-
}
|
|
46
|
+
return resultObj;
|
|
47
|
+
};
|
|
36
48
|
//监听
|
|
37
49
|
watch(view1, (n, o) => {
|
|
38
|
-
view1 = obj(n)
|
|
39
|
-
})
|
|
50
|
+
view1 = obj(n);
|
|
51
|
+
});
|
|
40
52
|
watch(view2, (n, o) => {
|
|
41
|
-
view2 = obj(n)
|
|
42
|
-
isShow.value=true
|
|
43
|
-
})
|
|
53
|
+
view2 = obj(n);
|
|
54
|
+
isShow.value = true;
|
|
55
|
+
});
|
|
44
56
|
// 每2秒进行位置变化以测试位置信息更新
|
|
45
57
|
let loopTimer = setInterval(() => {
|
|
46
58
|
_Index = (_Index + 1) % 3;
|
|
@@ -59,7 +71,7 @@ let _ResiterCallbackId2 = -1;
|
|
|
59
71
|
|
|
60
72
|
let getId = (id) => {
|
|
61
73
|
if (_ReisterId !== id) {
|
|
62
|
-
_ResiterCallbackId1 = enableNativeViewListener(id, view1)
|
|
74
|
+
_ResiterCallbackId1 = enableNativeViewListener(id, view1);
|
|
63
75
|
_ReisterId = id;
|
|
64
76
|
}
|
|
65
77
|
};
|
|
@@ -79,7 +91,7 @@ let getId2 = (id) => {
|
|
|
79
91
|
timeout2 = setTimeout(() => {
|
|
80
92
|
timeout2 = -1;
|
|
81
93
|
disableNativeViewListener(_ResiterCallbackId2);
|
|
82
|
-
isStop.value=true
|
|
94
|
+
isStop.value = true;
|
|
83
95
|
_ResiterCallbackId2 = -1;
|
|
84
96
|
}, 10000);
|
|
85
97
|
}, 1000);
|
|
@@ -110,116 +122,197 @@ onBeforeUnmount(() => {
|
|
|
110
122
|
disableNativeViewListener(_ResiterCallbackId2);
|
|
111
123
|
_ResiterCallbackId2 = -1;
|
|
112
124
|
}
|
|
113
|
-
})
|
|
125
|
+
});
|
|
114
126
|
|
|
115
127
|
onMounted(() => {
|
|
116
128
|
console.log("TestNativeSharedView mounted");
|
|
117
129
|
jJsvRuntimeBridge.notifyPageLoaded();
|
|
118
|
-
})
|
|
119
|
-
|
|
130
|
+
});
|
|
120
131
|
</script>
|
|
121
132
|
|
|
122
133
|
<template>
|
|
123
134
|
<jsv-focus-block autoFocus>
|
|
124
135
|
<!-- 一个无限动画元素,来测试卡顿 -->
|
|
125
|
-
<div
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
136
|
+
<div
|
|
137
|
+
:style="{
|
|
138
|
+
top: 100,
|
|
139
|
+
left: 1000,
|
|
140
|
+
height: 150,
|
|
141
|
+
width: 150,
|
|
142
|
+
backgroundColor: '#334455',
|
|
143
|
+
animation: 'test-anim-rotate 1s infinite linear',
|
|
144
|
+
}"
|
|
145
|
+
/>
|
|
133
146
|
<!-- 显示参数 -->
|
|
134
|
-
<div
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
<div
|
|
148
|
+
:style="{
|
|
149
|
+
top: 400,
|
|
150
|
+
left: 1000,
|
|
151
|
+
width: 256,
|
|
152
|
+
height: 240,
|
|
153
|
+
backgroundColor: 'rgba(27,38,151,0.8)',
|
|
154
|
+
}"
|
|
155
|
+
>
|
|
156
|
+
<div
|
|
157
|
+
:style="{
|
|
158
|
+
top: 0,
|
|
159
|
+
left: 0,
|
|
160
|
+
width: 120,
|
|
161
|
+
height: 30,
|
|
162
|
+
color: '#FFFFFF',
|
|
163
|
+
fontSize: 20,
|
|
164
|
+
textAlign: 'center',
|
|
165
|
+
}"
|
|
166
|
+
>
|
|
167
|
+
{{ "view1的参数" }}
|
|
168
|
+
</div>
|
|
169
|
+
<div
|
|
170
|
+
v-for="(value, key, index) in view1"
|
|
171
|
+
:style="{
|
|
172
|
+
top: 30 + index * 40,
|
|
173
|
+
left: 10,
|
|
174
|
+
width: 100,
|
|
175
|
+
height: 40,
|
|
176
|
+
fontSize: 20,
|
|
177
|
+
color: '#FFFFFF',
|
|
178
|
+
textAlign: 'center',
|
|
179
|
+
}"
|
|
180
|
+
>
|
|
181
|
+
{{ key }}:{{ value }}
|
|
182
|
+
</div>
|
|
183
|
+
<div
|
|
184
|
+
:style="{
|
|
185
|
+
top: 0,
|
|
186
|
+
left: 130,
|
|
187
|
+
width: 120,
|
|
188
|
+
height: 30,
|
|
189
|
+
color: '#FFFFFF',
|
|
190
|
+
fontSize: 20,
|
|
191
|
+
textAlign: 'center',
|
|
192
|
+
}"
|
|
193
|
+
>
|
|
194
|
+
{{ "view2的参数" }}
|
|
195
|
+
</div>
|
|
150
196
|
<div v-if="isShow">
|
|
151
|
-
|
|
197
|
+
<div
|
|
198
|
+
v-for="(value, key, index) in view2"
|
|
199
|
+
:style="{
|
|
152
200
|
top: 30 + index * 40,
|
|
153
201
|
left: 130,
|
|
154
202
|
width: 100,
|
|
155
203
|
height: 40,
|
|
156
204
|
fontSize: 20,
|
|
157
205
|
color: '#FFFFFF',
|
|
158
|
-
textAlign: 'center'
|
|
159
|
-
}"
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
fontSize: 20,
|
|
165
|
-
color: '#FFFFFF',
|
|
166
|
-
textAlign: 'center'}">{{ isStop ? "监听停止":"" }}</div>
|
|
167
|
-
</div>
|
|
168
|
-
<div
|
|
169
|
-
v-else
|
|
206
|
+
textAlign: 'center',
|
|
207
|
+
}"
|
|
208
|
+
>
|
|
209
|
+
{{ key }}:{{ value }}
|
|
210
|
+
</div>
|
|
211
|
+
<div
|
|
170
212
|
:style="{
|
|
171
|
-
top:
|
|
213
|
+
top: 200,
|
|
172
214
|
left: 130,
|
|
173
215
|
width: 100,
|
|
174
216
|
height: 40,
|
|
175
217
|
fontSize: 20,
|
|
176
218
|
color: '#FFFFFF',
|
|
177
|
-
textAlign: 'center'
|
|
219
|
+
textAlign: 'center',
|
|
220
|
+
}"
|
|
221
|
+
>
|
|
222
|
+
{{ isStop ? "监听停止" : "" }}
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
<div
|
|
226
|
+
v-else
|
|
227
|
+
:style="{
|
|
228
|
+
top: 30 + 2 * 30,
|
|
229
|
+
left: 130,
|
|
230
|
+
width: 100,
|
|
231
|
+
height: 40,
|
|
232
|
+
fontSize: 20,
|
|
233
|
+
color: '#FFFFFF',
|
|
234
|
+
textAlign: 'center',
|
|
235
|
+
}"
|
|
236
|
+
>
|
|
237
|
+
{{ "未监听" }}
|
|
238
|
+
</div>
|
|
178
239
|
</div>
|
|
179
240
|
|
|
180
|
-
|
|
181
|
-
|
|
241
|
+
<div
|
|
242
|
+
:style="{
|
|
182
243
|
left: state.outX,
|
|
183
244
|
top: state.outY,
|
|
184
245
|
backgroundColor: '#00FF00',
|
|
185
246
|
width: 600,
|
|
186
247
|
height: 600,
|
|
187
|
-
}"
|
|
188
|
-
|
|
248
|
+
}"
|
|
249
|
+
>
|
|
250
|
+
<div
|
|
251
|
+
:style="{
|
|
252
|
+
left: state.inX,
|
|
253
|
+
top: state.inY,
|
|
254
|
+
width: 500,
|
|
255
|
+
height: 500,
|
|
256
|
+
backgroundColor: 'rgba(255, 255, 0, 1.0)',
|
|
257
|
+
}"
|
|
258
|
+
/>
|
|
259
|
+
<jsv-native-shared-div
|
|
260
|
+
:getId="getId"
|
|
261
|
+
:style="{
|
|
189
262
|
left: state.inX,
|
|
190
263
|
top: state.inY,
|
|
191
264
|
width: 500,
|
|
192
265
|
height: 500,
|
|
193
|
-
}"
|
|
194
|
-
|
|
266
|
+
}"
|
|
267
|
+
>
|
|
268
|
+
<div
|
|
269
|
+
:style="{
|
|
195
270
|
backgroundColor: '#00FF00',
|
|
196
271
|
left: 50,
|
|
197
272
|
top: 40,
|
|
198
273
|
width: 30,
|
|
199
274
|
height: 30,
|
|
200
|
-
}"
|
|
275
|
+
}"
|
|
276
|
+
/>
|
|
201
277
|
</jsv-native-shared-div>
|
|
202
278
|
</div>
|
|
203
|
-
<div
|
|
279
|
+
<div
|
|
280
|
+
:style="{
|
|
204
281
|
left: state.outX + 200,
|
|
205
282
|
top: state.outY,
|
|
206
283
|
backgroundColor: '#00FF00',
|
|
207
284
|
width: 600,
|
|
208
285
|
height: 600,
|
|
209
|
-
}"
|
|
210
|
-
|
|
286
|
+
}"
|
|
287
|
+
>
|
|
288
|
+
<div
|
|
289
|
+
:style="{
|
|
211
290
|
left: state.inX,
|
|
212
291
|
top: state.inY,
|
|
213
292
|
width: 500,
|
|
214
293
|
height: 500,
|
|
215
|
-
|
|
216
|
-
|
|
294
|
+
backgroundColor: 'rgba(255, 255, 0, 1.0)',
|
|
295
|
+
}"
|
|
296
|
+
/>
|
|
297
|
+
<jsv-native-shared-div
|
|
298
|
+
:getId="getId2"
|
|
299
|
+
:style="{
|
|
300
|
+
left: state.inX,
|
|
301
|
+
top: state.inY,
|
|
302
|
+
width: 500,
|
|
303
|
+
height: 500,
|
|
304
|
+
}"
|
|
305
|
+
:corner="8"
|
|
306
|
+
>
|
|
307
|
+
<div
|
|
308
|
+
:style="{
|
|
217
309
|
backgroundColor: '#00FF00',
|
|
218
310
|
left: 50,
|
|
219
311
|
top: 40,
|
|
220
312
|
width: 30,
|
|
221
313
|
height: 30,
|
|
222
|
-
}"
|
|
314
|
+
}"
|
|
315
|
+
/>
|
|
223
316
|
</jsv-native-shared-div>
|
|
224
317
|
</div>
|
|
225
318
|
</jsv-focus-block>
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
-
import { ref } from "vue";
|
|
2
|
+
import { ref, shallowRef, onBeforeUnmount } from "vue";
|
|
3
3
|
import { useRouter } from "vue-router";
|
|
4
4
|
import {
|
|
5
5
|
JsvTextureAnim,
|
|
6
6
|
DECORATE_NINEPATCH_ALPHA_MIX,
|
|
7
|
+
JsvTextureStoreApi,
|
|
7
8
|
} from "jsview";
|
|
8
9
|
import img from "./assets/light.png";
|
|
9
10
|
import img2 from "./assets/light2.png";
|
|
10
11
|
import mask from "./assets/mask.png";
|
|
11
12
|
import { getDataUrl } from "../CommonUtils/ResourceData";
|
|
12
13
|
//无网络环境下使用
|
|
13
|
-
const DemoResourceBase = getDataUrl()
|
|
14
|
+
const DemoResourceBase = getDataUrl();
|
|
14
15
|
|
|
15
16
|
const getRandom = (start, end) => {
|
|
16
17
|
return Math.round(Math.random() * (end - start) + start);
|
|
@@ -24,7 +25,37 @@ const top = ref(80);
|
|
|
24
25
|
const rotateAnimation =
|
|
25
26
|
"{from {transform: rotate3d(0,0,1,0);} to {transform: rotate3d(0,0,1,360deg);}}";
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
// 设置设定模拟绘制.9图
|
|
29
|
+
let canvasRef;
|
|
30
|
+
let sourceId = shallowRef("");
|
|
31
|
+
let sampleImageWidth = 90;
|
|
32
|
+
canvasRef = JsvTextureStoreApi.canvasTexture(
|
|
33
|
+
sampleImageWidth,
|
|
34
|
+
sampleImageWidth
|
|
35
|
+
); // 创建画布
|
|
36
|
+
|
|
37
|
+
let circleInnerDiameter = 70; // 环形内直径, 为所要包括图形的borderRadius的一倍
|
|
38
|
+
let circleLineWidth = 6; // 线宽
|
|
39
|
+
let circleRadius = Math.floor(circleInnerDiameter / 2 + circleLineWidth / 2); // 绘制线是圆圈的轨迹中线
|
|
40
|
+
let customPath = canvasRef.circlePath(
|
|
41
|
+
Math.floor(sampleImageWidth / 2),
|
|
42
|
+
Math.floor(sampleImageWidth / 2),
|
|
43
|
+
circleRadius
|
|
44
|
+
); // 创建圆环绘制路径,圆形在画布的中心点位置
|
|
45
|
+
canvasRef.drawColor("rgba(0,0,0,0)"); // 画布绘制半透明底色
|
|
46
|
+
customPath.stroke(circleLineWidth, "#FF00FF7F"); // 以给定线宽绘制圆环
|
|
47
|
+
sourceId = canvasRef.commit(); // texture和div的textureStore绑定
|
|
48
|
+
|
|
49
|
+
const ninePatchDecorator1 = {
|
|
50
|
+
type: DECORATE_NINEPATCH_ALPHA_MIX,
|
|
51
|
+
url: `jsvtexturestore://${sourceId}`,
|
|
52
|
+
imageWidth: sampleImageWidth, // 等同于画布宽
|
|
53
|
+
centerWidth: 2, // 固定为1或2, 但1在PC上绘制可能有异常
|
|
54
|
+
borderOutset: Math.floor((sampleImageWidth - circleInnerDiameter) / 2), // (画布 - 圆环内直径) / 2
|
|
55
|
+
animTime: 0.5,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const ninePatchDecorator2 = {
|
|
28
59
|
type: DECORATE_NINEPATCH_ALPHA_MIX,
|
|
29
60
|
url: `url(${mask})`,
|
|
30
61
|
imageWidth: 86,
|
|
@@ -37,6 +68,7 @@ const texCoord = {
|
|
|
37
68
|
width: 600,
|
|
38
69
|
height: 600,
|
|
39
70
|
};
|
|
71
|
+
|
|
40
72
|
const onKeyDown = (ev) => {
|
|
41
73
|
// 8:Backspace, 27:Escape, 10000:盒子返回键
|
|
42
74
|
if (ev.keyCode == 8 || ev.keyCode == 27 || ev.keyCode == 10000) {
|
|
@@ -49,6 +81,10 @@ const onKeyDown = (ev) => {
|
|
|
49
81
|
}
|
|
50
82
|
return true;
|
|
51
83
|
};
|
|
84
|
+
|
|
85
|
+
onBeforeUnmount(() => {
|
|
86
|
+
JsvTextureStoreApi.deleteTexture(sourceId);
|
|
87
|
+
});
|
|
52
88
|
</script>
|
|
53
89
|
<template>
|
|
54
90
|
<jsv-focus-block
|
|
@@ -57,7 +93,6 @@ const onKeyDown = (ev) => {
|
|
|
57
93
|
:style="{
|
|
58
94
|
width: 1280,
|
|
59
95
|
height: 720,
|
|
60
|
-
backgroundImage: DemoResourceBase ?`${DemoResourceBase}/BackgroundLongmao.jpg` :'https://qcast-image.oss-cn-qingdao.aliyuncs.com/JsViewVideo/ImageTestSample/BackgroundLongmao.jpg',
|
|
61
96
|
}"
|
|
62
97
|
>
|
|
63
98
|
<div
|
|
@@ -76,6 +111,16 @@ const onKeyDown = (ev) => {
|
|
|
76
111
|
.9型的旋转焦点框,OK键进行随机位置+尺寸变换
|
|
77
112
|
</div>
|
|
78
113
|
<div>
|
|
114
|
+
<div
|
|
115
|
+
:style="{
|
|
116
|
+
left: left,
|
|
117
|
+
top: top,
|
|
118
|
+
width: width,
|
|
119
|
+
height: height,
|
|
120
|
+
backgroundColor: 'rgba(0, 255, 0, 0.7)',
|
|
121
|
+
borderRadius: Math.floor(circleInnerDiameter / 2),
|
|
122
|
+
}"
|
|
123
|
+
/>
|
|
79
124
|
<jsv-texture-anim
|
|
80
125
|
:src="img"
|
|
81
126
|
:left="left"
|
|
@@ -87,7 +132,7 @@ const onKeyDown = (ev) => {
|
|
|
87
132
|
:duration="2000"
|
|
88
133
|
:repeat="-1"
|
|
89
134
|
:autoStart="true"
|
|
90
|
-
:decorate="
|
|
135
|
+
:decorate="ninePatchDecorator1"
|
|
91
136
|
></jsv-texture-anim>
|
|
92
137
|
</div>
|
|
93
138
|
<div>
|
|
@@ -102,8 +147,8 @@ const onKeyDown = (ev) => {
|
|
|
102
147
|
:duration="2000"
|
|
103
148
|
:repeat="-1"
|
|
104
149
|
:autoStart="true"
|
|
105
|
-
:decorate="
|
|
150
|
+
:decorate="ninePatchDecorator2"
|
|
106
151
|
></jsv-texture-anim>
|
|
107
152
|
</div>
|
|
108
153
|
</jsv-focus-block>
|
|
109
|
-
</template>
|
|
154
|
+
</template>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<JsvFreeMoveActor
|
|
3
|
+
:top="-myHeight"
|
|
4
|
+
:left="myLeft"
|
|
5
|
+
:width="2"
|
|
6
|
+
:height="myHeight"
|
|
7
|
+
ref="myRef"
|
|
8
|
+
>
|
|
9
|
+
<div
|
|
10
|
+
:style="{
|
|
11
|
+
width: 2,
|
|
12
|
+
height: myHeight,
|
|
13
|
+
backgroundImage: `jsvtexturestore://${sourceId}`,
|
|
14
|
+
}"
|
|
15
|
+
></div>
|
|
16
|
+
</JsvFreeMoveActor>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script setup>
|
|
20
|
+
import { shallowRef, onBeforeUnmount, onMounted } from "vue";
|
|
21
|
+
import { JsvTextureStoreApi, JsvFreeMoveActor } from "jsview";
|
|
22
|
+
let canvasRef;
|
|
23
|
+
let sourceId = shallowRef("");
|
|
24
|
+
const canvasTexture = JsvTextureStoreApi.canvasTexture(10, 200);
|
|
25
|
+
canvasTexture.drawLine(0, 0, 0, 200, 10, "rgba(255, 255, 255, 0.5)");
|
|
26
|
+
canvasRef = canvasTexture.commit();
|
|
27
|
+
sourceId.value = canvasRef;
|
|
28
|
+
//随机长度函数(限制在80-160)
|
|
29
|
+
const randomHeight = () => {
|
|
30
|
+
return Math.floor(Math.random() * 80) + 80;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
//随机left值
|
|
34
|
+
const randomLeft = () => {
|
|
35
|
+
return Math.floor(Math.random() * 1280);
|
|
36
|
+
};
|
|
37
|
+
const myHeight = randomHeight();
|
|
38
|
+
const myLeft = randomLeft();
|
|
39
|
+
|
|
40
|
+
let myRef = shallowRef(null);
|
|
41
|
+
let myControl;
|
|
42
|
+
let randomInteger = Math.floor(Math.random() * 200) + 1;
|
|
43
|
+
|
|
44
|
+
onMounted(() => {
|
|
45
|
+
myControl = myRef.value.control;
|
|
46
|
+
myControl.run([
|
|
47
|
+
myControl
|
|
48
|
+
.condition()
|
|
49
|
+
.onNextTick(randomInteger)
|
|
50
|
+
.then([
|
|
51
|
+
myControl.action().setSpeed(undefined, 9),
|
|
52
|
+
myControl.action(3).setAccel(undefined, 0.13),
|
|
53
|
+
]),
|
|
54
|
+
myControl
|
|
55
|
+
.condition(undefined, true)
|
|
56
|
+
.reachPosition(undefined, 620)
|
|
57
|
+
.then([
|
|
58
|
+
myControl.action().teleportTo(undefined, -580 - myHeight),
|
|
59
|
+
myControl.action().setSpeed(undefined, 9),
|
|
60
|
+
myControl.action(3).setAccel(undefined, 0.13),
|
|
61
|
+
]),
|
|
62
|
+
]);
|
|
63
|
+
});
|
|
64
|
+
onBeforeUnmount(() => {
|
|
65
|
+
JsvTextureStoreApi.deleteTexture(sourceId.value);
|
|
66
|
+
});
|
|
67
|
+
</script>
|
|
68
|
+
|
|
69
|
+
<style lang="scss" scoped></style>
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<JsvAudio
|
|
3
|
+
key="AudioBg"
|
|
4
|
+
:src="musicBg"
|
|
5
|
+
:loop="true"
|
|
6
|
+
:onRef="onRef"
|
|
7
|
+
:onLoad="audioOnLoad"
|
|
8
|
+
/>
|
|
9
|
+
<JsvRipple :width="1280" :height="720" ref="rippleViewRef">
|
|
10
|
+
<jsv-focus-block autoFocus>
|
|
11
|
+
<img
|
|
12
|
+
:src="bg"
|
|
13
|
+
:style="{ width: 1280, height: 720 }"
|
|
14
|
+
:onLoad="funcBackgroundOnLoaded"
|
|
15
|
+
/>
|
|
16
|
+
<div
|
|
17
|
+
:style="{
|
|
18
|
+
width: 100,
|
|
19
|
+
height: 100,
|
|
20
|
+
backgroundImage: title,
|
|
21
|
+
left: 900,
|
|
22
|
+
top: 40,
|
|
23
|
+
}"
|
|
24
|
+
></div>
|
|
25
|
+
<!-- 随机位置和长度的雨滴 -->
|
|
26
|
+
<Rain v-for="(item, index) in 60" />
|
|
27
|
+
<!-- 波纹效果 -->
|
|
28
|
+
</jsv-focus-block>
|
|
29
|
+
</JsvRipple>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<script setup>
|
|
33
|
+
import Rain from "./Rain.vue";
|
|
34
|
+
import { JsvRipple, JsvRippleShape, JsvAudio, JsvSoundPool } from "jsview";
|
|
35
|
+
import { shallowRef, onMounted, onBeforeUnmount } from "vue";
|
|
36
|
+
const bg =
|
|
37
|
+
"https://qcast-image.oss-cn-qingdao.aliyuncs.com/JsViewVideo/ImageTestSample/TombSweepingDayTest/qingming_bg.jpg";
|
|
38
|
+
const title =
|
|
39
|
+
"https://qcast-image.oss-cn-qingdao.aliyuncs.com/JsViewVideo/ImageTestSample/TombSweepingDayTest/qingming_title.png";
|
|
40
|
+
const musicBg =
|
|
41
|
+
"https://qcast-image.oss-cn-qingdao.aliyuncs.com/JsViewVideo/VideoTestSample/rain_background.mp3";
|
|
42
|
+
let timer = { id: -1, id2: -1 };
|
|
43
|
+
const soundPool = new JsvSoundPool(10);
|
|
44
|
+
let rippleViewRef = shallowRef(null);
|
|
45
|
+
const genSource = () => {
|
|
46
|
+
let leftOrRight = Math.random() >= 0.5 ? true : false;
|
|
47
|
+
if (leftOrRight) {
|
|
48
|
+
return [
|
|
49
|
+
Math.floor(Math.random() * (336 - 214 + 1)) + 214,
|
|
50
|
+
Math.round(Math.random() * 200 + 400),
|
|
51
|
+
Math.round(Math.random() * 100 + 20),
|
|
52
|
+
];
|
|
53
|
+
} else {
|
|
54
|
+
return [
|
|
55
|
+
Math.floor(Math.random() * (1066 - 960 + 1)) + 960,
|
|
56
|
+
Math.round(Math.random() * 200 + 400),
|
|
57
|
+
Math.round(Math.random() * 100 + 20),
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
//背景音频ref
|
|
62
|
+
let _BgAudio = null;
|
|
63
|
+
//水波音效
|
|
64
|
+
const mySound =
|
|
65
|
+
"https://qcast-image.oss-cn-qingdao.aliyuncs.com/JsViewVideo/VideoTestSample/rain_tiktok.mp3";
|
|
66
|
+
//音效ref
|
|
67
|
+
let mySoundControl = null;
|
|
68
|
+
//音效回调
|
|
69
|
+
soundPool.request(`url(${mySound})`, null, 1, (state, audioController) => {
|
|
70
|
+
if (state === 0) {
|
|
71
|
+
mySoundControl = audioController;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
//音频回调
|
|
75
|
+
const onRef = (ref) => {
|
|
76
|
+
_BgAudio = ref;
|
|
77
|
+
};
|
|
78
|
+
const audioOnLoad = () => {
|
|
79
|
+
console.log("audio on load");
|
|
80
|
+
_BgAudio.play();
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
let backgrounLoaded = false;
|
|
84
|
+
const funcBackgroundOnLoaded = () => {
|
|
85
|
+
backgrounLoaded = true;
|
|
86
|
+
console.log("bg image loaded");
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
onMounted(() => {
|
|
90
|
+
if (rippleViewRef.value !== null) {
|
|
91
|
+
timer.id = setInterval(() => {
|
|
92
|
+
if (backgrounLoaded) {
|
|
93
|
+
// 图片加载完成后再追加波纹,规避绘出黑色的波圈
|
|
94
|
+
const p = genSource();
|
|
95
|
+
rippleViewRef.value.addSource(
|
|
96
|
+
...p,
|
|
97
|
+
{
|
|
98
|
+
type: JsvRippleShape.CIRCLE,
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
timeDecay: 0.5,
|
|
102
|
+
distanceDecay: 8,
|
|
103
|
+
speed: 60,
|
|
104
|
+
frequency: 2,
|
|
105
|
+
waveNum: 2,
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
timer.id2 = setTimeout(() => {
|
|
110
|
+
mySoundControl.play();
|
|
111
|
+
}, 1000);
|
|
112
|
+
}
|
|
113
|
+
}, 3000);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
onBeforeUnmount(() => {
|
|
117
|
+
if (timer.id !== -1) {
|
|
118
|
+
clearInterval(timer.id);
|
|
119
|
+
timer.id = -1;
|
|
120
|
+
}
|
|
121
|
+
if (timer.id2 !== -1) {
|
|
122
|
+
clearTimeout(timer.id2);
|
|
123
|
+
timer.id2 = -1;
|
|
124
|
+
}
|
|
125
|
+
soundPool.destroy();
|
|
126
|
+
_BgAudio?.pause();
|
|
127
|
+
_BgAudio?.unload();
|
|
128
|
+
});
|
|
129
|
+
</script>
|
|
130
|
+
|
|
131
|
+
<style scoped></style>
|