@shijiu/jsview-vue-samples 2.2.128 → 2.2.373

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 (105) hide show
  1. package/BakeViewDemo/App.vue +6 -1
  2. package/Basic/components/anim/AnimEasingCubicBezier.vue +56 -0
  3. package/Basic/components/anim/AnimGroup2.vue +33 -0
  4. package/Basic/components/panel/Panel2.vue +8 -3
  5. package/CoupletsTest/widget/Banger/Maroon.vue +4 -7
  6. package/CoupletsTest/widget/Fireworks/Fireworks.vue +52 -44
  7. package/CustomShader/App.vue +174 -0
  8. package/CustomShader/gaussianBlur.glsl +27 -0
  9. package/CustomShader/pageFlip.glsl +41 -0
  10. package/CustomShader/sdf.glsl +22 -0
  11. package/CustomShader/test.glsl +8 -0
  12. package/CustomShader/vortex.glsl +38 -0
  13. package/DemoHomepage/App.vue +50 -32
  14. package/DemoHomepage/components/Item.vue +23 -12
  15. package/DemoHomepage/index.d.ts +5 -2
  16. package/DemoHomepage/router.js +105 -72
  17. package/DispersedFocusControl/App.vue +67 -0
  18. package/DispersedFocusControl/Button.vue +76 -0
  19. package/DispersedFocusControl/data.js +44 -0
  20. package/DragBox/App.vue +148 -0
  21. package/DriftScopeTest/App.vue +128 -0
  22. package/FlexCellDemo/App.vue +47 -223
  23. package/FlexCellDemo/TestFrame1.vue +88 -0
  24. package/FlexCellDemo/TestFrame2.vue +100 -0
  25. package/FlexCellDemo/TestFrame3.vue +97 -0
  26. package/FlexCellDemo/TestFrame4.vue +60 -0
  27. package/FlexCellDemo/TestFrame5.vue +60 -0
  28. package/FlexCellDemo/images/6.jpg +0 -0
  29. package/FocusMoveStyle/App.vue +1 -0
  30. package/FocusMoveStyle/CreepFocus.vue +11 -1
  31. package/FocusMoveStyle/FoldableItem.vue +1 -1
  32. package/FreeMove/App.vue +62 -64
  33. package/FreeMoveLink/App.vue +2 -2
  34. package/FullScreenFlex/App.vue +42 -0
  35. package/FullScreenFlex/TestFrame2.vue +107 -0
  36. package/FullScreenFlex/images/1.png +0 -0
  37. package/HashHistory/App.vue +8 -4
  38. package/ImpactStop/App.vue +45 -45
  39. package/Input/App.vue +184 -97
  40. package/Input/InputPanel.vue +98 -82
  41. package/LatexFormula/App.vue +97 -10
  42. package/LongImage/App.vue +1 -2
  43. package/LongText/App.vue +2 -2
  44. package/LongText/LongTextScroll.vue +22 -22
  45. package/LongText/Scroll.vue +28 -9
  46. package/MetroWidgetDemos/RefreshDemo/App.vue +172 -56
  47. package/MetroWidgetDemos/RefreshDemo/ControlItem.vue +45 -0
  48. package/MetroWidgetDemos/RefreshDemo/Item.vue +20 -4
  49. package/MetroWidgetDemos/itemSizeUpdate/backward/Item.vue +1 -1
  50. package/MetroWidgetDemos/routeList.js +17 -17
  51. package/MindMap/App.vue +10 -1
  52. package/MindMap/data.js +34 -8
  53. package/Parkour/appConfig/jsview.config.mjs +0 -4
  54. package/PosterPacker/App.vue +207 -0
  55. package/PosterPacker/images/bg.jpg +0 -0
  56. package/PosterPacker/images/blue.png +0 -0
  57. package/PosterPacker/images/darkGreen.png +0 -0
  58. package/PosterPacker/images/left.png +0 -0
  59. package/PosterPacker/images/orange.png +0 -0
  60. package/PosterPacker/images/pink.png +0 -0
  61. package/PosterPacker/images/purple.png +0 -0
  62. package/PosterPacker/images/red.png +0 -0
  63. package/PosterPacker/images/right.png +0 -0
  64. package/PosterPacker/images/yellowGreen.png +0 -0
  65. package/PosterPacker/tools/geniePakcer/Genie.vue +686 -0
  66. package/PosterPacker/tools/geniePakcer/genieBottom.glsl +49 -0
  67. package/PosterPacker/tools/geniePakcer/genieLeft.glsl +50 -0
  68. package/PosterPacker/tools/geniePakcer/genieRight.glsl +57 -0
  69. package/PosterPacker/tools/geniePakcer/genieTop.glsl +50 -0
  70. package/PosterPacker/tools/particlePacker/Particle.vue +71 -0
  71. package/PosterPacker/tools/vortexPacker/Vortex.vue +135 -0
  72. package/PosterPacker/tools/vortexPacker/vortex.glsl +37 -0
  73. package/Preload/App.vue +1 -1
  74. package/SceneTransition/JsvSceneTransition.vue +30 -42
  75. package/ScrollBoxTest/App.vue +35 -86
  76. package/ScrollBoxTest/ClipBar.vue +154 -0
  77. package/ScrollBoxTest/DrawCircle.ts +25 -0
  78. package/ScrollBoxTest/NinePatchBar.vue +188 -0
  79. package/ScrollBoxTest/NoBackgroundBar.vue +125 -0
  80. package/ScrollBoxTest/SizeDivBar.vue +139 -0
  81. package/SprayMove/App.vue +75 -0
  82. package/SprayMove/SprayMove.vue +173 -0
  83. package/SprayView/App.vue +8 -9
  84. package/TestNativeSharedView/App.vue +6 -4
  85. package/TextShadowDemo/App.vue +3 -3
  86. package/TextureAnimation/App.vue +244 -148
  87. package/TextureAnimation/App2.vue +66 -14
  88. package/TextureAnimation/assets/blackWhiteTurntable.png +0 -0
  89. package/TextureAnimation/assets/circleHaloMask.png +0 -0
  90. package/TombSweepingDayTest/Raining/Rain.vue +8 -8
  91. package/TouchWidget/App.vue +79 -40
  92. package/TouchWidget/Item.vue +15 -3
  93. package/index.d.ts +1 -1
  94. package/package.json +1 -1
  95. package/MetroWidgetDemos/RefreshDemo/data.js +0 -16
  96. package/TextureAnimation/assets/mask.png +0 -0
  97. package/TextureAnimation/assets/php.jpg +0 -0
  98. package/TouchSample/App.vue +0 -136
  99. package/TouchSample/Item.vue +0 -102
  100. package/TouchSample/MetroWidgetHorizontal.vue +0 -144
  101. package/TouchSample/MetroWidgetVertical.vue +0 -144
  102. package/TouchSample/TouchContainerHorizontal.vue +0 -160
  103. package/TouchSample/TouchContainerVertical.vue +0 -160
  104. package/TouchSample/data.js +0 -81
  105. /package/TextureAnimation/assets/{php2.png → borderOpacity.png} +0 -0
@@ -0,0 +1,686 @@
1
+ <script setup>
2
+ /**
3
+ * @file Genie组件说明
4
+ * Genie:收缩或者放出效果的组件
5
+ * props说明:
6
+ * @prop {Number} width (必填) 组件的基础宽度
7
+ * @prop {Number} height (必填) 组件的基础高度
8
+ * @prop {Number} top (非必填) 组件的基础top
9
+ * @prop {Number} left (非必填) 组件的基础left
10
+ * @prop {String} imgUrl (必填) 组件的图片来源
11
+ * @prop {Number} time (非必填) 组件的动画时长
12
+ * @prop {Object} position (必填) 组件收缩点的坐标
13
+ * @prop {String} direction (必填) 组件动画方向
14
+ * @prop {Function} animationEnd (非必填) 组件做完一次动画后的回调
15
+ * @prop {Boolean} initShow (必填) 组件初始状态
16
+ * methods:
17
+ * @method switcher 暴露出去的方法 交替组件内部显示情况
18
+ *
19
+ */
20
+
21
+ import genieLeft from "./genieLeft.glsl?raw";
22
+ import genieRight from "./genieRight.glsl?raw";
23
+ import genieBottom from "./genieBottom.glsl?raw";
24
+ import genieTop from "./genieTop.glsl?raw";
25
+ import {
26
+ shallowRef,
27
+ computed,
28
+ onMounted,
29
+ onUnmounted,
30
+ onBeforeUnmount,
31
+ watchEffect,
32
+ } from "vue";
33
+ import { JsvFragShaderView, getKeyFramesGroup } from "jsview";
34
+ const props = defineProps({
35
+ width: { type: Number, require: true },
36
+ height: { type: Number, require: true },
37
+ imgUrl: { type: String, require: true },
38
+ left: { type: Number, default: 0 },
39
+ top: { type: Number, default: 0 },
40
+ time: { type: Number, default: 2 },
41
+ position: { type: Object, require: true },
42
+ size: { type: Number, default: 1 },
43
+ direction: { type: String, require: true },
44
+ aniEnd: { type: Function, default: () => {} },
45
+ initShow: { type: Boolean, require: true },
46
+ });
47
+
48
+ let rShow = shallowRef(false);
49
+ let rFlag = shallowRef(true);
50
+ //是否第一次动画
51
+ let initAni = true;
52
+ //动画
53
+ const cStyleShell = getKeyFramesGroup();
54
+ //动画字符串
55
+ let rAniStr = shallowRef("release");
56
+ //位移动画中心点方向
57
+ let vTransformDirection = "";
58
+ //形变比例
59
+ let vTransformScale = 1;
60
+ //自动播放控制
61
+ let autoControl = shallowRef(false);
62
+ //shader模型
63
+ let vTempMode = "";
64
+ let vShaderMode = "";
65
+ //替换
66
+ let rReplacedShader = shallowRef("");
67
+ //动画
68
+ let vContract;
69
+ let vRelease;
70
+ //位移量
71
+ let vDistanceX;
72
+ let vDistanceY;
73
+ //shader动画的参数
74
+ let vRange1;
75
+ let vRange2;
76
+
77
+ //在组件外部的八种情况
78
+ //左上方
79
+ if (props.position.x < 0 && props.position.y < 0) {
80
+ vDistanceX = props.position.x;
81
+ vDistanceY = props.position.y;
82
+ //释放的动画
83
+ vRelease = `@keyframes release {
84
+ 0% {
85
+ transform: translate3d(${vDistanceX},${vDistanceY}, 0);
86
+ }
87
+ 70%{
88
+ transform: translate3d(${vDistanceX},${vDistanceY}, 0);
89
+ }
90
+ 80% {
91
+ transform: translate3d(0, 0, 0);
92
+ }
93
+ 100% {
94
+ transform: translate3d(0, 0, 0);
95
+ }
96
+ }`;
97
+ vContract = `@keyframes contract {
98
+ 0% {
99
+ transform: translate3d(0, 0, 0);
100
+ }
101
+ 30% {
102
+ transform: translate3d(0, 0, 0);
103
+ }
104
+ 40%{
105
+ transform: translate3d(${vDistanceX}, ${vDistanceY}, 0);
106
+ }
107
+ 100% {
108
+ transform: translate3d(${vDistanceX}, ${vDistanceY}, 0);
109
+ }
110
+ }`;
111
+ if (props.direction == "horizontal") {
112
+ vShaderMode = genieLeft;
113
+ vRange1 = 1 - 1 / props.height;
114
+ vRange2 = 1 - 2 / props.height;
115
+ console.log("range1", vRange1, vRange2);
116
+ } else if (props.direction == "vertical") {
117
+ vShaderMode = genieTop;
118
+ vRange1 = 1 / props.width;
119
+ vRange2 = 2 / props.width;
120
+ console.log("range1", vRange1, vRange2);
121
+ }
122
+ } else if (props.position.x < props.width && props.position.y < 0) {
123
+ //正上方
124
+ vDistanceY = props.position.y;
125
+ //释放的动画
126
+ vRelease = `@keyframes release {
127
+ 0% {
128
+ transform: translate3d(0,${vDistanceY}, 0);
129
+ }
130
+ 70% {
131
+ transform: translate3d(0,${vDistanceY}, 0);
132
+ }
133
+ 80%{
134
+ transform: translate3d(0, 0, 0);
135
+ }
136
+
137
+ 100% {
138
+ transform: translate3d(0, 0, 0);
139
+ }
140
+ }`;
141
+ vContract = `@keyframes contract {
142
+ 0% {
143
+ transform: translate3d(0, 0, 0);
144
+ }
145
+ 30% {
146
+ transform: translate3d($0, 0, 0);
147
+ }
148
+ 40%{
149
+ transform: translate3d($0, ${vDistanceY}, 0);
150
+ }
151
+ 100% {
152
+ transform: translate3d(0, ${vDistanceY}, 0);
153
+ }
154
+ }`;
155
+
156
+ vShaderMode = genieTop;
157
+
158
+ vRange1 = (props.position.x + 1) / props.width;
159
+ vRange2 = props.position.x / props.width;
160
+ } else if (props.position.x > props.width && props.position.y < 0) {
161
+ //右上角
162
+ if (props.direction == "horizontal") {
163
+ vDistanceX = props.position.x - props.width;
164
+ vDistanceY = props.position.y;
165
+ vShaderMode = genieRight;
166
+ vRange1 = 1 - 1 / props.height;
167
+ vRange2 = 1 - 2 / props.height;
168
+ console.log("range1", vRange1, vRange2);
169
+ } else if (props.direction == "vertical") {
170
+ vDistanceX = props.position.x - props.width;
171
+ vDistanceY = props.position.y;
172
+ vShaderMode = genieTop;
173
+ vRange2 = 1 - 2 / props.width;
174
+ vRange1 = 1 - 1 / props.width;
175
+ console.log("range1", vRange1, vRange2);
176
+ }
177
+ //释放的动画
178
+ vRelease = `@keyframes release {
179
+ 0% {
180
+ transform: translate3d(${vDistanceX},${vDistanceY}, 0);
181
+ }
182
+ 70% {
183
+ transform: translate3d(${vDistanceX},${vDistanceY}, 0);
184
+ }
185
+ 80%{
186
+ transform: translate3d(0, 0, 0);
187
+ }
188
+ 100% {
189
+ transform: translate3d(0, 0, 0);
190
+ }
191
+ }`;
192
+ vContract = `@keyframes contract {
193
+ 0% {
194
+ transform: translate3d(0, 0, 0);
195
+ }
196
+ 30% {
197
+ transform: translate3d(0, 0, 0);
198
+ }
199
+ 40%{
200
+ transform: translate3d(${vDistanceX}, ${vDistanceY}, 0);
201
+ }
202
+ 100% {
203
+ transform: translate3d(${vDistanceX}, ${vDistanceY}, 0);
204
+ }
205
+ }`;
206
+ } else if (
207
+ props.position.x < 0 &&
208
+ props.position.y > 0 &&
209
+ props.position.y <= props.height
210
+ ) {
211
+ //正左边
212
+ vDistanceX = props.position.x;
213
+ //释放的动画
214
+ vRelease = `@keyframes release {
215
+ 0% {
216
+ transform: translate3d(${vDistanceX},0, 0);
217
+ }
218
+ 70% {
219
+ transform: translate3d(${vDistanceX},0, 0);
220
+ }
221
+ 80%{
222
+ transform: translate3d(0, 0, 0);
223
+ }
224
+ 100% {
225
+ transform: translate3d(0, 0, 0);
226
+ }
227
+ }`;
228
+ vContract = `@keyframes contract {
229
+ 0% {
230
+ transform: translate3d(0, 0, 0);
231
+ }
232
+ 30% {
233
+ transform: translate3d(0, 0, 0);
234
+ }
235
+ 40%{
236
+ transform: translate3d(${vDistanceX},0, 0);
237
+ }
238
+ 100% {
239
+ transform: translate3d(${vDistanceX},0, 0);
240
+ }
241
+ }`;
242
+
243
+ vShaderMode = genieLeft;
244
+
245
+ vRange2 = 1 - props.position.y / props.height;
246
+ vRange1 = 1 - (props.position.y + 1) / props.height;
247
+ } else if (
248
+ props.position.x > props.width &&
249
+ props.position.y > 0 &&
250
+ props.position.y <= props.height
251
+ ) {
252
+ //正右边
253
+ vDistanceX = props.position.x - props.width;
254
+ vDistanceY = props.position.y;
255
+ vShaderMode = genieRight;
256
+ vRange1 = 1 - props.position.y / props.height;
257
+ vRange2 = 1 - (1 + props.position.y) / props.height;
258
+ //释放的动画
259
+ vRelease = `@keyframes release {
260
+ 0% {
261
+ transform: translate3d(${vDistanceX},0, 0);
262
+ }
263
+ 70% {
264
+ transform: translate3d(${vDistanceX},0, 0);
265
+ }
266
+ 80%{
267
+ transform: translate3d(0, 0, 0);
268
+ }
269
+ 100% {
270
+ transform: translate3d(0, 0, 0);
271
+ }
272
+ }`;
273
+ vContract = `@keyframes contract {
274
+ 0% {
275
+ transform: translate3d(0, 0, 0);
276
+ }
277
+ 30% {
278
+ transform: translate3d(0, 0, 0);
279
+ }
280
+ 40%{
281
+ transform: translate3d(${vDistanceX},0, 0);
282
+ }
283
+ 100% {
284
+ transform: translate3d(${vDistanceX},0, 0);
285
+ }
286
+ }`;
287
+ } else if (props.position.x < 0 && props.position.y > props.height) {
288
+ //左下方
289
+ if (props.direction == "horizontal") {
290
+ vDistanceX = props.position.x;
291
+ vDistanceY = props.position.y - props.height;
292
+ console.log(vDistanceX, vDistanceY);
293
+ vShaderMode = genieLeft;
294
+ vRange2 = 1 / props.height;
295
+ vRange1 = (1 + 1) / props.height;
296
+ console.log("range1", vRange1, vRange2);
297
+ } else if (props.direction == "vertical") {
298
+ vDistanceX = props.position.x;
299
+ vDistanceY = props.position.y - props.height;
300
+ vShaderMode = genieBottom;
301
+ vRange1 = 1 / props.width;
302
+ vRange2 = (1 + 1) / props.width;
303
+ console.log("range1", vRange1, vRange2);
304
+ }
305
+ //释放的动画
306
+ vRelease = `@keyframes release {
307
+ 0% {
308
+ transform: translate3d(${vDistanceX},${vDistanceY}, 0);
309
+ }
310
+ 70% {
311
+ transform: translate3d(${vDistanceX},${vDistanceY}, 0);
312
+ }
313
+ 80%{
314
+ transform: translate3d(0, 0, 0);
315
+ }
316
+ 100% {
317
+ transform: translate3d(0, 0, 0);
318
+ }
319
+ }`;
320
+ vContract = `@keyframes contract {
321
+ 0% {
322
+ transform: translate3d(0, 0, 0);
323
+ }
324
+ 30% {
325
+ transform: translate3d(0, 0, 0);
326
+ }
327
+ 40%{
328
+ transform: translate3d(${vDistanceX}, ${vDistanceY}, 0);
329
+ }
330
+ 100% {
331
+ transform: translate3d(${vDistanceX}, ${vDistanceY}, 0);
332
+ }
333
+ }`;
334
+ } else if (
335
+ props.position.x > 0 &&
336
+ props.position.x < props.width &&
337
+ props.position.y > props.height
338
+ ) {
339
+ //正下方
340
+ vDistanceY = props.position.y - props.height;
341
+ //释放的动画
342
+ vRelease = `@keyframes release {
343
+ 0% {
344
+ transform: translate3d(0,${vDistanceY}, 0);
345
+ }
346
+ 70% {
347
+ transform: translate3d(0,${vDistanceY}, 0);
348
+ }
349
+ 80%{
350
+ transform: translate3d(0, 0, 0);
351
+ }
352
+ 100% {
353
+ transform: translate3d(0, 0, 0);
354
+ }
355
+ }`;
356
+ vContract = `@keyframes contract {
357
+ 0% {
358
+ transform: translate3d(0, 0, 0);
359
+ }
360
+ 30% {
361
+ transform: translate3d(0, 0, 0);
362
+ }
363
+ 40%{
364
+ transform: translate3d($0, ${vDistanceY}, 0);
365
+ }
366
+ 100% {
367
+ transform: translate3d(0, ${vDistanceY}, 0);
368
+ }
369
+ }`;
370
+
371
+ vShaderMode = genieBottom;
372
+
373
+ vRange1 = props.position.x / props.width;
374
+ vRange2 = (props.position.x - 1) / props.width;
375
+ console.log("range1", vRange1, vRange2);
376
+ } else if (props.position.x > props.width && props.position.y > props.height) {
377
+ //右下方
378
+ if (props.direction == "horizontal") {
379
+ vDistanceX = props.position.x - props.width;
380
+ vDistanceY = props.position.y - props.height;
381
+ vShaderMode = genieRight;
382
+ vRange2 = 1 / props.height;
383
+ vRange1 = (1 + 1) / props.height;
384
+ console.log("range1", vRange1, vRange2);
385
+ } else if (props.direction == "vertical") {
386
+ vDistanceX = props.position.x - props.width;
387
+ vDistanceY = props.position.y - props.height;
388
+ vShaderMode = genieBottom;
389
+ vRange2 = 1 - 2 / props.width;
390
+ vRange1 = 1 - 1 / props.width;
391
+ console.log("range1", vRange1, vRange2);
392
+ }
393
+ //释放的动画
394
+ vRelease = `@keyframes release {
395
+ 0% {
396
+ transform: translate3d(${vDistanceX},${vDistanceY}, 0);
397
+ }
398
+ 70% {
399
+ transform: translate3d(${vDistanceX},${vDistanceY}, 0);
400
+ }
401
+ 80%{
402
+ transform: translate3d(0, 0, 0);
403
+ }
404
+ 100% {
405
+ transform: translate3d(0, 0, 0);
406
+ }
407
+ }`;
408
+ vContract = `@keyframes contract {
409
+ 0% {
410
+ transform: translate3d(0, 0, 0);
411
+ }
412
+ 30% {
413
+ transform: translate3d(0, 0, 0);
414
+ }
415
+ 40%{
416
+ transform: translate3d(${vDistanceX}, ${vDistanceY}, 0);
417
+ }
418
+ 100% {
419
+ transform: translate3d(${vDistanceX}, ${vDistanceY}, 0);
420
+ }
421
+ }`;
422
+ } else {
423
+ //在组件内
424
+ //根据传入进来的方向和中心点位置确定缩放动画
425
+ if (props.direction == "vertical") {
426
+ if (props.position.y < props.height / 2) {
427
+ vTransformDirection = "bottom center";
428
+ vShaderMode = genieTop;
429
+ vTransformScale = 1 - props.position.y / props.height;
430
+ } else {
431
+ vTransformDirection = "top center";
432
+ vShaderMode = genieBottom;
433
+ vTransformScale = props.position.y / props.height;
434
+ }
435
+ vRange1 = props.position.x / props.width;
436
+ vRange2 = (props.position.x - 1) / props.width;
437
+ } else if (props.direction == "horizontal") {
438
+ //解析坐标位置是否要进行移动动画
439
+ if (props.position.x < props.width / 2) {
440
+ vTransformDirection = "center right";
441
+ vShaderMode = genieLeft;
442
+ vTransformScale = 1 - props.position.x / props.width;
443
+ } else {
444
+ vTransformDirection = "center left";
445
+ vShaderMode = genieRight;
446
+ vTransformScale = props.position.x / props.width;
447
+ }
448
+ vRange1 = 1 - props.position.y / props.height;
449
+ vRange2 = 1 - (props.position.y + 1) / props.height;
450
+ }
451
+
452
+ if (props.direction == "horizontal") {
453
+ // //收的动画
454
+ vContract = `@keyframes contract {
455
+ 0% {
456
+ transform: scale3d(1, 1, 1);
457
+ transform-origin:${vTransformDirection};
458
+ }
459
+ 30% {
460
+ transform: scale3d(${vTransformScale}, 1, 1);
461
+ transform-origin:${vTransformDirection};
462
+ }
463
+ 100% {
464
+ transform: scale3d(${vTransformScale}, 1, 1);
465
+ transform-origin:${vTransformDirection};
466
+ }
467
+ }`;
468
+ // //释放的动画
469
+ vRelease = `@keyframes release {
470
+ 0% {
471
+ transform: scale3d(${vTransformScale}, 1, 1);
472
+ transform-origin:${vTransformDirection};
473
+ }
474
+ 70% {
475
+ transform: scale3d(${vTransformScale}, 1, 1);
476
+ transform-origin:${vTransformDirection};
477
+ }
478
+ 100% {
479
+ transform: scale3d(1, 1, 1);
480
+ transform-origin:${vTransformDirection};
481
+ }
482
+ }`;
483
+ } else if (props.direction == "vertical") {
484
+ //收的动画
485
+ vContract = `@keyframes contract {
486
+ 0% {
487
+ transform: scale3d(1, 1, 1);
488
+ transform-origin:${vTransformDirection};
489
+ }
490
+ 30% {
491
+ transform: scale3d(1,${vTransformScale}, 1);
492
+ transform-origin:${vTransformDirection};
493
+ }
494
+ 100% {
495
+ transform: scale3d(1, ${vTransformScale}, 1);
496
+ transform-origin:${vTransformDirection};
497
+ }
498
+ }`;
499
+ //释放的动画
500
+ vRelease = `@keyframes release {
501
+ 0% {
502
+ transform: scale3d(1,${vTransformScale}, 1);
503
+ transform-origin:${vTransformDirection};
504
+ }
505
+ 70% {
506
+ transform: scale3d(1,${vTransformScale}, 1);
507
+ transform-origin:${vTransformDirection};
508
+ }
509
+ 100% {
510
+ transform: scale3d(1, 1, 1);
511
+ transform-origin:${vTransformDirection};
512
+ }
513
+ }`;
514
+ }
515
+ }
516
+ //根据初始状态展示
517
+ if (props.initShow) {
518
+ rShow.value = true;
519
+ rFlag.value = false;
520
+ rAniStr.value = "contract";
521
+ vTempMode = vShaderMode.replace(/\$\{myTime\}/g, "iTime / iDuration");
522
+ } else {
523
+ rShow.value = false;
524
+ rFlag.value = false;
525
+ rAniStr.value = "release";
526
+ vTempMode = vShaderMode.replace(
527
+ /\$\{myTime\}/g,
528
+ "(iDuration - iTime) / iDuration"
529
+ );
530
+ }
531
+ rReplacedShader = vTempMode
532
+ .replace(/\$\{RANGE_1\}/g, vRange1)
533
+ .replace(/\$\{RANGE_2\}/g, vRange2);
534
+
535
+ //结束动画函数
536
+ const EndAni = () => {
537
+ if (rAniStr.value == "release") {
538
+ rFlag.value = false;
539
+ rShow.value = true;
540
+ } else {
541
+ rFlag.value = false;
542
+ rShow.value = false;
543
+ }
544
+ };
545
+ //配置
546
+ const cShaderSettings = {
547
+ name: "genieLeft",
548
+ shader: rReplacedShader,
549
+ uniforms: [],
550
+ textures: [
551
+ {
552
+ name: "iChannel0",
553
+ resource: props.imgUrl,
554
+ },
555
+ ],
556
+ duration: props.time * 1000,
557
+ onEnd: EndAni,
558
+ };
559
+
560
+ cStyleShell.insertRule(vContract);
561
+ cStyleShell.insertRule(vRelease);
562
+ let rWidgetRef = shallowRef(null);
563
+ const rShaderInfo = computed(() => {
564
+ return cShaderSettings;
565
+ });
566
+
567
+ let vNextTickStartAnimTimer = -1;
568
+
569
+ const switcher = () => {
570
+ if (initAni) {
571
+ rFlag.value = true;
572
+ console.log("初始");
573
+ if (vNextTickStartAnimTimer != -1) {
574
+ clearTimeout(vNextTickStartAnimTimer);
575
+ }
576
+ vNextTickStartAnimTimer = setTimeout(() => {
577
+ rShow.value = false;
578
+ rWidgetRef.value.startAnim();
579
+ vNextTickStartAnimTimer = -1;
580
+ }, 0);
581
+ initAni = false;
582
+ } else {
583
+ rFlag.value = true;
584
+ if (rAniStr.value == "release") {
585
+ rAniStr.value = "contract";
586
+ rReplacedShader = rReplacedShader.replace(
587
+ "(iDuration - iTime) / iDuration",
588
+ "iTime / iDuration"
589
+ );
590
+ cShaderSettings.shader = rReplacedShader;
591
+ } else {
592
+ rAniStr.value = "release";
593
+ rReplacedShader = rReplacedShader.replace(
594
+ "iTime / iDuration",
595
+ "(iDuration - iTime) / iDuration"
596
+ );
597
+ cShaderSettings.shader = rReplacedShader;
598
+ }
599
+ if (vNextTickStartAnimTimer != -1) {
600
+ clearTimeout(vNextTickStartAnimTimer);
601
+ }
602
+ vNextTickStartAnimTimer = setTimeout(() => {
603
+ rShow.value = false;
604
+ rWidgetRef.value.startAnim();
605
+ }, 0);
606
+ }
607
+ };
608
+ watchEffect(() => {
609
+ console.log("rShow", rShow.value);
610
+ });
611
+ onMounted(() => {
612
+ window.JsView?.enableFpsDisplay(true);
613
+ });
614
+
615
+ onUnmounted(() => {
616
+ if (vNextTickStartAnimTimer != -1) {
617
+ clearTimeout(vNextTickStartAnimTimer);
618
+ vNextTickStartAnimTimer = -1;
619
+ }
620
+
621
+ window.JsView?.enableFpsDisplay(false);
622
+ });
623
+ onBeforeUnmount(() => {
624
+ cStyleShell.removeRule("contract");
625
+ cStyleShell.removeRule("release");
626
+ });
627
+
628
+ //向父组件暴露方法
629
+ defineExpose({
630
+ switcher,
631
+ });
632
+ </script>
633
+ <template>
634
+ <!-- 测试div -->
635
+ <div
636
+ :style="{
637
+ top: props.top + props.position.y,
638
+ left: props.left + props.position.x,
639
+ width: props.size,
640
+ height: props.size,
641
+ backgroundColor: '#FFFFFF',
642
+ }"
643
+ ></div>
644
+
645
+ <!-- 组件 -->
646
+ <div
647
+ v-if="rFlag"
648
+ :style="{
649
+ left: props.left,
650
+ top: props.top,
651
+ width: props.width,
652
+ height: props.height,
653
+ animation: `${rAniStr} ${props.time}s`,
654
+ transformOrigin: vTransformDirection,
655
+ }"
656
+ @animationend="props.aniEnd"
657
+ >
658
+ <jsv-frag-shader-view
659
+ ref="rWidgetRef"
660
+ :style="{
661
+ left: 0,
662
+ top: 0,
663
+ width: props.width,
664
+ height: props.height,
665
+ }"
666
+ :duration="rShaderInfo.duration"
667
+ :shaderStr="rShaderInfo.shader"
668
+ :autoplay="false"
669
+ :textures="rShaderInfo.textures"
670
+ :onEnd="rShaderInfo.onEnd"
671
+ >
672
+ </jsv-frag-shader-view>
673
+ </div>
674
+ <div
675
+ v-if="rShow"
676
+ :style="{
677
+ left: props.left,
678
+ top: props.top,
679
+ width: props.width,
680
+ height: props.height,
681
+ backgroundImage: props.imgUrl,
682
+ }"
683
+ ></div>
684
+ </template>
685
+
686
+ <style lang="scss" scoped></style>