@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
package/SprayView/App.vue CHANGED
@@ -18,7 +18,17 @@ import Star2 from "./assets/star2.png";
18
18
  import Star3 from "./assets/star3.png";
19
19
  import Star4 from "./assets/star4.png";
20
20
  //定义图片url列表
21
- const ImgData = [snow, GoldenCoin1, GoldenCoin2, RedPacket1, RedPacket2, Star1, Star2, Star3, Star4]
21
+ const ImgData = [
22
+ snow,
23
+ GoldenCoin1,
24
+ GoldenCoin2,
25
+ RedPacket1,
26
+ RedPacket2,
27
+ Star1,
28
+ Star2,
29
+ Star3,
30
+ Star4,
31
+ ];
22
32
  const sprayOk = {
23
33
  type: 0,
24
34
  particleNum: 50,
@@ -39,7 +49,7 @@ const sprayOk = {
39
49
 
40
50
  const sprayRotate = {
41
51
  type: 1,
42
- particleNum: 50,
52
+ particleNum: 100,
43
53
  deltaAngle: 0,
44
54
  deltaWidth: 0,
45
55
  deltaHeight: 50,
@@ -48,7 +58,7 @@ const sprayRotate = {
48
58
  speedMin: 5,
49
59
  speedMax: 10,
50
60
  lifeMin: 1000,
51
- lifeMax: 3000,
61
+ lifeMax: 1500,
52
62
  accelerateX: 0,
53
63
  accelerateY: -100,
54
64
  particleAddSpeed: 0.1,
@@ -89,7 +99,7 @@ const sprayCycle = {
89
99
  lifeMax: 3000,
90
100
  accelerateX: 0,
91
101
  accelerateY: 0,
92
- particleAddSpeed: 0.01,
102
+ particleAddSpeed: 0.1,
93
103
  enableFade: true,
94
104
  enableShrink: false,
95
105
  angularVelocityMin: 360,
@@ -122,11 +132,21 @@ const sprayFall = {
122
132
  };
123
133
 
124
134
  const okCount = ref(0);
135
+
136
+ let stopped = false;
125
137
  const onKeyDown = (ev) => {
126
138
  switch (ev.keyCode) {
127
139
  case 13:
128
140
  okCount.value++;
129
141
  return true;
142
+ case 38:
143
+ if (window.JsView) {
144
+ // 目前先只有native支持
145
+ // TODO: wasm版本上线后放开此限制
146
+ stopped ? testRef.value.start() : testRef.value.stop();
147
+ stopped = !stopped;
148
+ }
149
+ return true;
130
150
  }
131
151
  return false;
132
152
  };
@@ -139,30 +159,39 @@ const s = {
139
159
  color: "#ffffff",
140
160
  fontSize: 20,
141
161
  };
162
+
163
+ const testRef = ref();
142
164
  </script>
143
165
 
144
166
  <template>
145
167
  <div class="root">
146
- <jsv-focus-block autoFocus :onAction="{
147
- onKeyDown: onKeyDown,
148
- }">
168
+ <jsv-focus-block
169
+ autoFocus
170
+ :onAction="{
171
+ onKeyDown: onKeyDown,
172
+ }"
173
+ >
149
174
  <div :style="{ top: 20, left: 400 }">
150
- <div :style="{
151
- width: 40,
152
- height: 40,
153
- animation: 'cycle 3s linear infinite',
154
- }">
175
+ <div
176
+ :style="{
177
+ width: 40,
178
+ height: 40,
179
+ animation: 'cycle 3s linear infinite',
180
+ }"
181
+ >
155
182
  <jsv-spray :pointRes="`url(${snow})`" :sprayStyle="sprayCycle" />
156
183
  </div>
157
- <div :style="{
158
- top: 20,
159
- width: 400,
160
- height: 100,
161
- lineHeight: 100,
162
- textAlign: 'center',
163
- fontSize: 50,
164
- color: '#FFFFFF',
165
- }">
184
+ <div
185
+ :style="{
186
+ top: 20,
187
+ width: 400,
188
+ height: 100,
189
+ lineHeight: 100,
190
+ textAlign: 'center',
191
+ fontSize: 50,
192
+ color: '#FFFFFF',
193
+ }"
194
+ >
166
195
  粒子效果
167
196
  </div>
168
197
  <div class="describe">
@@ -170,21 +199,25 @@ const s = {
170
199
  </div>
171
200
  </div>
172
201
 
173
- <div :style="{
174
- left: 0,
175
- top: 200,
176
- width: 400,
177
- height: 600,
178
- overflow: 'hidden',
179
- }">
202
+ <div
203
+ :style="{
204
+ left: 0,
205
+ top: 200,
206
+ width: 400,
207
+ height: 600,
208
+ overflow: 'hidden',
209
+ }"
210
+ >
180
211
  <div :style="{ top: 150, left: 150 }">
181
212
  <div class="spray-ok">
182
213
  <div v-if="okCount > 0">
183
- <jsv-spray v-for="item in ImgData"
184
- :key="okCount"
185
- :pointRes="`url(${item})`"
186
- :sprayStyle="sprayOk"
187
- :ignoreClip="true" />
214
+ <jsv-spray
215
+ v-for="item in ImgData"
216
+ :key="okCount"
217
+ :pointRes="`url(${item})`"
218
+ :sprayStyle="sprayOk"
219
+ :ignoreClip="true"
220
+ />
188
221
  </div>
189
222
  </div>
190
223
  <div class="describe">
@@ -194,36 +227,48 @@ const s = {
194
227
  </div>
195
228
  </div>
196
229
  </div>
197
- <div :style="{
198
- left: 400,
199
- top: 200,
200
- width: 400,
201
- height: 600,
202
- overflow: 'hidden',
203
- }">
230
+ <div
231
+ :style="{
232
+ left: 400,
233
+ top: 200,
234
+ width: 400,
235
+ height: 600,
236
+ overflow: 'hidden',
237
+ }"
238
+ >
204
239
  <div :style="{ top: 150, left: 195 }">
205
240
  <div class="spray-rotate">
206
- <jsv-spray v-for="item in ImgData" :pointRes="`url(${item})`" :sprayStyle="sprayRotate" />
241
+ <jsv-spray
242
+ v-for="item in ImgData"
243
+ :pointRes="`url(${item})`"
244
+ :sprayStyle="sprayRotate"
245
+ />
207
246
  </div>
208
247
  <div class="describe">
209
248
  {{ `#粒子沿长边随机生成\n#初速度沿长边方向\n#受竖直方向的力作用` }}
210
249
  </div>
211
250
  </div>
212
251
  </div>
213
- <div :style="{
214
- left: 800,
215
- top: 200,
216
- width: 400,
217
- height: 600,
218
- overflow: 'hidden',
219
- }">
252
+ <div
253
+ :style="{
254
+ left: 800,
255
+ top: 200,
256
+ width: 400,
257
+ height: 600,
258
+ overflow: 'hidden',
259
+ }"
260
+ >
220
261
  <div :style="{ top: 150, left: 150 }">
221
262
  <div class="spray-move">
222
- <jsv-spray :pointRes="`url(${snow})`" :sprayStyle="sprayMove" />
263
+ <jsv-spray
264
+ ref="testRef"
265
+ :pointRes="`url(${snow})`"
266
+ :sprayStyle="sprayMove"
267
+ />
223
268
  </div>
224
269
  <div class="describe">
225
270
  {{
226
- `#粒子在方形随机生成\n#初速度方向为竖直向上方向正负20度内随机\n#受水平方向和竖直方向的力作用`
271
+ `#粒子在方形随机生成\n#按上键停止/开始喷射\n#初速度方向为竖直向上方向正负20度内随机\n#受水平方向和竖直方向的力作用`
227
272
  }}
228
273
  </div>
229
274
  </div>
@@ -327,4 +372,4 @@ const s = {
327
372
  color: #ffffff;
328
373
  font-size: 20;
329
374
  }
330
- </style>
375
+ </style>
@@ -0,0 +1,73 @@
1
+ <!--
2
+ * @Author: ChenChanghua
3
+ * @Date: 2022-01-25 09:56:46
4
+ * @LastEditors: Please set LastEditors
5
+ -->
6
+ <script setup>
7
+ import { DefaultKeyCodeMap, jJsvRuntimeBridge } from "jsview";
8
+ import { useRouter } from "vue-router";
9
+ import { SprFestivalScene } from "./SpringFestivalScene";
10
+ import { onMounted } from "vue";
11
+
12
+ const router = useRouter();
13
+
14
+ const fncOnKeyDown = (ev) => {
15
+ if (
16
+ ev.keyCode == 8 ||
17
+ ev.keyCode == 27 ||
18
+ ev.keyCode == DefaultKeyCodeMap.Back
19
+ ) {
20
+ router.go(-1); // 有router时,是从DemoHomepage进入,回退
21
+ return true;
22
+ }
23
+ switch (ev.keyCode) {
24
+ case DefaultKeyCodeMap.Up:
25
+ case DefaultKeyCodeMap.Down:
26
+ case DefaultKeyCodeMap.left:
27
+ case DefaultKeyCodeMap.Right:
28
+ case DefaultKeyCodeMap.Ok:
29
+ return true;
30
+ }
31
+ };
32
+
33
+ let cRunningInBox = typeof window.JsView != "undefined";
34
+
35
+ onMounted(() => {
36
+ jJsvRuntimeBridge.notifyPageLoaded();
37
+ });
38
+ </script>
39
+
40
+ <template>
41
+ <jsv-focus-block
42
+ autoFocus
43
+ :onAction="{
44
+ onKeyDown: fncOnKeyDown,
45
+ }"
46
+ >
47
+ <div
48
+ v-if="cRunningInBox"
49
+ :style="{
50
+ width: 1920,
51
+ height: 1080,
52
+ transform: 'scale3d(0.67,0.67,1)',
53
+ transformOrigin: 'left top',
54
+ }"
55
+ >
56
+ <SprFestivalScene />
57
+ </div>
58
+ <div
59
+ v-else
60
+ id="LudlScale"
61
+ :style="{
62
+ top: 210,
63
+ left: 490,
64
+ width: 300,
65
+ height: 300,
66
+ fontSize: 25,
67
+ lineHeight: 300,
68
+ }"
69
+ >
70
+ {{ "PC不支持此组件显示" }}
71
+ </div>
72
+ </jsv-focus-block>
73
+ </template>
@@ -0,0 +1,211 @@
1
+ <script>
2
+ import { getKeyFramesGroup } from "jsview";
3
+
4
+ const animNamePrefix = "__2025__chunjie__";
5
+ const moveDownAnimName = animNamePrefix + "move_down";
6
+ const clipResizeAnimName = animNamePrefix + "clip_resize";
7
+
8
+ const styleShell = getKeyFramesGroup();
9
+
10
+ const scrollTopOffset = 51;
11
+ function buildMove(totalTime, frameList) {
12
+ let moveFrameDefines = [];
13
+ let heightFrameDefines = [];
14
+ for (let i = 0; i < frameList.length; i++) {
15
+ let frameItem = frameList[i];
16
+ let percent = Math.floor((frameItem.timeStamp / totalTime) * 10000) / 100;
17
+ moveFrameDefines.push(
18
+ `${percent}%{top:${frameItem.height + scrollTopOffset}}`
19
+ );
20
+ heightFrameDefines.push(`${percent}%{height:${frameItem.height}}`);
21
+ }
22
+ let moveAnimStr = `@keyframes ${moveDownAnimName} {`;
23
+ for (let i = 0; i < moveFrameDefines.length; i++) {
24
+ moveAnimStr += moveFrameDefines[i];
25
+ }
26
+ moveAnimStr += `}`;
27
+ console.log("move anim: " + moveAnimStr);
28
+
29
+ let resizeAnimStr = `@keyframes ${clipResizeAnimName} {`;
30
+ for (let i = 0; i < heightFrameDefines.length; i++) {
31
+ resizeAnimStr += heightFrameDefines[i];
32
+ }
33
+ resizeAnimStr += `}`;
34
+ console.log("resize anim: " + resizeAnimStr);
35
+
36
+ return [moveAnimStr, resizeAnimStr];
37
+ }
38
+ const totalHeight = 874;
39
+ const keyframeList = [
40
+ { height: 0, timeStamp: 0 },
41
+ { height: totalHeight, timeStamp: 1300 },
42
+ { height: Math.round(totalHeight * 0.95), timeStamp: 1450 },
43
+ { height: totalHeight, timeStamp: 1600 },
44
+ { height: Math.round(totalHeight * 0.98), timeStamp: 1800 },
45
+ { height: totalHeight, timeStamp: 2000 },
46
+ ];
47
+
48
+ let inited = false;
49
+ function initChunLianAnim() {
50
+ if (!inited) {
51
+ const [moveAnimStr, resizeAnimStr] = buildMove(2000, keyframeList);
52
+ styleShell.insertRule(moveAnimStr);
53
+ styleShell.insertRule(resizeAnimStr);
54
+ inited = true;
55
+ }
56
+ }
57
+
58
+ function releaseChunLianAnim() {
59
+ styleShell.removeRule(moveDownAnimName);
60
+ styleShell.removeRule(clipResizeAnimName);
61
+ inited = false;
62
+ }
63
+ export { initChunLianAnim, releaseChunLianAnim };
64
+ </script>
65
+
66
+ <script setup>
67
+ import { ref, onMounted, onBeforeUnmount } from "vue";
68
+
69
+ const props = defineProps({
70
+ isLeft: {
71
+ type: Boolean,
72
+ default: false,
73
+ },
74
+ left: {
75
+ type: Number,
76
+ default: 0,
77
+ },
78
+ top: {
79
+ type: Number,
80
+ default: 0,
81
+ },
82
+ contentImage: {
83
+ type: String,
84
+ required: true,
85
+ },
86
+ scrollImage: {
87
+ type: Array,
88
+ required: true,
89
+ },
90
+ duration: {
91
+ type: Number,
92
+ default: 2000,
93
+ },
94
+ autoStart: {
95
+ type: Boolean,
96
+ default: true,
97
+ },
98
+ onAnimEnd: {
99
+ type: Function,
100
+ },
101
+ });
102
+
103
+ const flipScrollTransform = props.isLeft ? "scale3d(-1,1,1)" : null;
104
+ const moveDownAnim = ref(null);
105
+ const clipResizeAnim = ref(null);
106
+ const clipHeight = ref(0);
107
+ const scrollTop = ref(53);
108
+ function onMoveDownAnimDone() {
109
+ scrollTop.value = 52 + 873;
110
+ }
111
+
112
+ function onClipResizeAnimDone() {
113
+ clipHeight.value = 874;
114
+ props.onAnimEnd?.();
115
+ }
116
+
117
+ const start = () => {
118
+ moveDownAnim.value = `${moveDownAnimName} ${props.duration / 1000}s`;
119
+ clipResizeAnim.value = `${clipResizeAnimName} ${props.duration / 1000}s`;
120
+ };
121
+
122
+ onMounted(() => {
123
+ if (props.autoStart) {
124
+ start();
125
+ }
126
+ });
127
+
128
+ defineExpose({
129
+ start,
130
+ });
131
+ </script>
132
+
133
+ <template>
134
+ <div
135
+ :style="{
136
+ left: props.left,
137
+ top: props.top,
138
+ }"
139
+ >
140
+ <div
141
+ id="clipview"
142
+ :style="{
143
+ width: 209,
144
+ height: clipHeight,
145
+ top: 53,
146
+ left: (265 - 209) / 2,
147
+ overflow: 'hidden',
148
+ animation: clipResizeAnim,
149
+ }"
150
+ @animationend="onClipResizeAnimDone"
151
+ >
152
+ <div
153
+ class="chun_lian_size"
154
+ :style="{
155
+ backgroundImage: props.contentImage,
156
+ }"
157
+ ></div>
158
+ </div>
159
+
160
+ <div
161
+ class="juan_zhou_size"
162
+ :style="{
163
+ transform: flipScrollTransform,
164
+ transformOrigin: 'center top',
165
+ }"
166
+ >
167
+ <div
168
+ class="juan_zhou_size"
169
+ :style="{
170
+ backgroundImage: `url(${props.scrollImage[0]})`,
171
+ }"
172
+ ></div>
173
+ <div
174
+ class="juan_zhou_size"
175
+ :style="{
176
+ top: scrollTop,
177
+ backgroundImage: `url(${props.scrollImage[1]})`,
178
+ animation: moveDownAnim,
179
+ }"
180
+ @animationend="onMoveDownAnimDone"
181
+ ></div>
182
+ </div>
183
+ </div>
184
+ </template>
185
+ <style>
186
+ .chun_lian_size {
187
+ width: 209;
188
+ height: 874;
189
+ }
190
+ .juan_zhou_size {
191
+ width: 265;
192
+ height: 55;
193
+ }
194
+ @keyframes chun_lian_anim {
195
+ from {
196
+ height: 0;
197
+ }
198
+ to {
199
+ height: 874;
200
+ }
201
+ }
202
+
203
+ @keyframes juan_zhou_anim {
204
+ from {
205
+ top: 51;
206
+ }
207
+ to {
208
+ top: 925;
209
+ }
210
+ }
211
+ </style>
@@ -0,0 +1,139 @@
1
+ const SQRT2VAL = Math.sqrt(2)
2
+
3
+
4
+ // 获取原地起跳抛物的处理
5
+ function getParabola(
6
+ cmds,
7
+ condGroupId, // 后续改为specName
8
+ xSpeed,
9
+ ySpeed,
10
+ gravity,
11
+ times,
12
+ onLandCmds
13
+ ) {
14
+ let actCmds;
15
+ if (times > 0) {
16
+ actCmds = getParabola(
17
+ cmds,
18
+ condGroupId,
19
+ xSpeed,
20
+ ySpeed / SQRT2VAL,
21
+ gravity,
22
+ times - 1,
23
+ onLandCmds
24
+ );
25
+ } else {
26
+ actCmds = onLandCmds;
27
+ }
28
+
29
+ return [
30
+ cmds.state().removeConditionByName(sFloorConditionName),
31
+ // (state: any) => {
32
+ // console.log(`State on t=${Date.now()} land y=${ySpeed} setStartOffsetPos times=${times}`,
33
+ // JSON.stringify(state))
34
+ // },
35
+ cmds.state().setStartPos(undefined, -1), // 离开接触点
36
+ cmds.action().setSpdAndAccel(xSpeed, ySpeed, 0, gravity),
37
+
38
+ // 下一帧再重启condition,避免当前帧的判断循环中仍然激活condition
39
+ cmds
40
+ .condition(condGroupId)
41
+ .onNextTick()
42
+ .then([
43
+ cmds
44
+ .condition(condGroupId, false, sFloorConditionName)
45
+ .reachPosition(undefined, 0)
46
+ .then([
47
+ ...actCmds,
48
+ ]),
49
+ ]),
50
+ ];
51
+ }
52
+
53
+ const sFloorConditionName = "floorCond";
54
+ const sWallConditionName = "wallCond";
55
+
56
+ /*
57
+ 弹跳处理
58
+ */
59
+ export function buildBounce(
60
+ cmds,// FreeMove的cmds句柄
61
+ condGroupId,
62
+ startX, // 起始位置和目标位置的偏差, 单位px
63
+ startY, // 起始位置和目标位置的偏差, 单位px
64
+ times, // 整数,落点数(弹起次数-1)
65
+ gravity, // y轴的加速度, 建议设置成0.8
66
+ onEnd,
67
+ ) {
68
+ let xDistance = startX - 0;
69
+ let yDistance = startY - 0;
70
+
71
+ if (times < 1) {
72
+ times = 1;
73
+ console.log("at least 1 times");
74
+ }
75
+
76
+ // 每个碰撞点之间的x的距离为
77
+ // sx * (1 + 1/sqrt(2) + 1/sqrt(2)^2 + ...) (=次数的数列)
78
+ // sx 为第一次下落过程x轴走过的距离
79
+ let sqrt2 = 1 / SQRT2VAL;
80
+ let sxSubBase = 2;
81
+ let sxSub = sxSubBase / 2;
82
+ for (let i = 0; i < times - 1; i++) {
83
+ sxSubBase = sxSubBase * sqrt2;
84
+ sxSub += sxSubBase;
85
+ }
86
+ let sx = -(xDistance / sxSub);
87
+
88
+ // 求首次下落使用的时间, 按照 s = 1/2*a*t^2的公式求解
89
+ let t1st = Math.sqrt(Math.abs(yDistance) * 2 / gravity);
90
+
91
+ // 求x的速度
92
+ let vx = sx / t1st;
93
+
94
+ // 求第一次落点的y速度
95
+ let vy1st = gravity * t1st;
96
+
97
+ let onLandCmds = [
98
+ cmds.action().teleportTo(0, 0),
99
+ // cmds.action().stopMoving(true),
100
+ cmds.state().removeConditionByGroup(condGroupId),
101
+ (...args) => {
102
+ onEnd?.(...args);
103
+ }
104
+ ];
105
+
106
+ let parabolaCmds;
107
+ if (times > 1) {
108
+ // 递归创建所有运动处理
109
+ parabolaCmds = getParabola(cmds, condGroupId, vx, -vy1st / SQRT2VAL, gravity, times - 2, onLandCmds);
110
+ } else {
111
+ parabolaCmds = onLandCmds;
112
+ }
113
+
114
+ let wallname = xDistance > 0 ? "left" : "right";
115
+
116
+ let cmdsArray = [
117
+ // 清理掉所有condition,除了group的外,还有wallposition
118
+ // 但后续specName的bug修正后,可以用specName来控制动画,只清理group即可
119
+ cmds.state().removeConditionByGroup(condGroupId),
120
+
121
+ // wallPosition用于规避运动路程计算超出(times越大超出越多)时,解决动画结尾的回弹问题
122
+ cmds.condition(condGroupId, true, sWallConditionName).wallPosition(wallname, 0, undefined).then([
123
+ cmds.action().teleportTo(0, undefined),
124
+ cmds.action().setSpdAndAccel(0, undefined, undefined, undefined),
125
+ ]),
126
+
127
+ // 启动从起始点的抛物下落动画
128
+ cmds.state().setStartPos(startX, startY),
129
+ cmds.action().setSpdAndAccel(vx, 0, 0, gravity),
130
+ cmds
131
+ .condition(condGroupId, false, sFloorConditionName)
132
+ .reachPosition(undefined, 0)
133
+ .then([
134
+ ...parabolaCmds
135
+ ])
136
+ ];
137
+
138
+ return cmdsArray;
139
+ }