@shijiu/jsview-vue-samples 2.3.151-test.0 → 2.3.728-alpha.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 (244) hide show
  1. package/ABImageAlt/App.vue +114 -0
  2. package/ABImageAlt/Item.vue +133 -0
  3. package/{MetroWidgetDemos/SkeletonDiagram/assets/imageList.json → ABImageAlt/assets/imageList.js} +9 -1
  4. package/ABImageAlt/data.js +17 -0
  5. package/AI_Check_Rules.txt +5 -0
  6. package/AnimPicture/App.vue +20 -10
  7. package/ApicSwitch/App.vue +90 -0
  8. package/ApicSwitch/TabItem.vue +65 -0
  9. package/ApicSwitch/WebpShow.vue +24 -0
  10. package/ApicSwitch/data.js +50 -0
  11. package/Basic/AI_skills_update.md +1 -0
  12. package/Basic/components/div/ColorFormatTest.vue +93 -0
  13. package/Basic/components/div/DivRadius.vue +97 -15
  14. package/Basic/components/div/DivTag3Group.vue +30 -0
  15. package/Basic/components/img/ImageType.vue +65 -0
  16. package/Basic/components/panel/Panel2.vue +13 -1
  17. package/Basic/components/text/TextAlign.vue +7 -1
  18. package/BlobLoadTest/App.vue +201 -0
  19. package/BreakLinesApi/App.vue +82 -0
  20. package/CanvasDrawChart/App.vue +11 -0
  21. package/CanvasDrawChart/Graph1.vue +104 -0
  22. package/CanvasDrawChart/Graph2.vue +115 -0
  23. package/DemoForOperator/Blur/Blur.vue +1 -1
  24. package/DemoForOperator/Blur/BlurInOut/BlurInOut.vue +49 -23
  25. package/DemoForOperator/Blur/BlurInOut/StaticBgSlide.vue +1 -1
  26. package/DemoForOperator/Blur/BlurPopup/BlurPopup.vue +156 -20
  27. package/DemoForOperator/BookFlip/App.vue +1 -1
  28. package/DemoForOperator/Bounce/FreeMoveBuilder.js +1 -1
  29. package/DemoForOperator/Firework1/App.vue +12 -1
  30. package/DemoForOperator/Firework1/Fireworks.vue +18 -0
  31. package/DemoForOperator/FlipPage/FlipPage/FlipPage.vue +1 -0
  32. package/DemoForOperator/Focus/Alpha/Item.vue +1 -0
  33. package/DemoForOperator/Focus/Light/Item.vue +1 -0
  34. package/DemoForOperator/Focus/Normal/Item.vue +1 -0
  35. package/DemoForOperator/Genie/App.vue +20 -6
  36. package/DemoForOperator/Genie/App2.vue +61 -0
  37. package/DemoForOperator/Genie/geniePakcer/GenieImage.vue +298 -0
  38. package/DemoForOperator/Genie/geniePakcer/GenieSlot.vue +292 -0
  39. package/DemoForOperator/Genie/geniePakcer/GenieTools.ts +463 -0
  40. package/DemoForOperator/Jigsaw/JigsawFull.vue +12 -7
  41. package/DemoForOperator/Jigsaw/JigsawSingle.vue +13 -7
  42. package/DemoForOperator/LongChatBox/App.vue +13 -13
  43. package/DemoForOperator/LongChatBox/Bubble.vue +78 -66
  44. package/DemoForOperator/LongChatBox/LongChat.vue +67 -36
  45. package/DemoForOperator/LongChatBox/testData.js +7 -44
  46. package/DemoForOperator/Sound/Bounce/FreeMoveBuilder.js +1 -1
  47. package/DemoForOperator/routeList.js +8 -2
  48. package/DemoHomepage/App.vue +74 -1
  49. package/DemoHomepage/components/BodyFrame.vue +5 -0
  50. package/DemoHomepage/components/TabFrame.vue +1 -1
  51. package/DemoHomepage/router.js +749 -165
  52. package/DemoHomepage/views/Homepage.vue +60 -2
  53. package/DemoHomepage/watchTest.vue +50 -0
  54. package/DomRenderer/App.vue +133 -0
  55. package/FilterDemo/AnimatePic.vue +63 -17
  56. package/FilterDemo/App.vue +3 -3
  57. package/FlexCellDemo/AI_skills_update.md +4 -0
  58. package/FlexCellDemo/TestFrame1.vue +12 -2
  59. package/FlexCellDemo/TestFrame2.vue +10 -1
  60. package/FlexCellDemo/TestFrame3.vue +114 -59
  61. package/FpsLimit/App.vue +102 -0
  62. package/FreeMove/App.vue +24 -279
  63. package/FreeMove/TestScene1.vue +260 -0
  64. package/FreeMove/TestScene3.vue +431 -0
  65. package/FreeMoveChildAttract/App.vue +18 -8
  66. package/FreeMoveLink/App.vue +51 -22
  67. package/Hover/App.vue +144 -0
  68. package/HttpRequestSSE/SSEReader.js +200 -0
  69. package/ImpactStop/App.vue +2 -2
  70. package/Input/FullKeyboard.vue +3 -3
  71. package/Input/InputPanel.vue +63 -3
  72. package/JsvLine/App.vue +53 -38
  73. package/LatexDemo/App.vue +3 -1
  74. package/LatexFormula/App.vue +196 -0
  75. package/LongImage/App.vue +1 -1
  76. package/LongImage/LongImageScroll.vue +111 -46
  77. package/LongImage/Scroll.vue +28 -9
  78. package/LongText/LongTextScroll.vue +14 -1
  79. package/Markdown/App.vue +36 -0
  80. package/Markdown/Bubble.vue +109 -0
  81. package/Markdown/LongChat.vue +216 -0
  82. package/Markdown/data.js +633 -0
  83. package/MetroWidgetDemos/AI_skills_update.md +2 -0
  84. package/MetroWidgetDemos/EpgFlowListType/App.vue +206 -0
  85. package/MetroWidgetDemos/EpgFlowListType/components/ContentCard.vue +105 -0
  86. package/MetroWidgetDemos/EpgFlowListType/components/FloorSection.vue +131 -0
  87. package/MetroWidgetDemos/EpgFlowListType/components/LeftTabItem.vue +41 -0
  88. package/MetroWidgetDemos/EpgFlowListType/data.js +78 -0
  89. package/MetroWidgetDemos/ListExpand/ChildItem.vue +130 -0
  90. package/MetroWidgetDemos/ListExpand/ExpandItem.vue +375 -0
  91. package/MetroWidgetDemos/ListExpand/ExpandItem1.vue +403 -0
  92. package/MetroWidgetDemos/ListExpand/assets/arrow-down.png +0 -0
  93. package/MetroWidgetDemos/ListExpand/assets/up-arrow.png +0 -0
  94. package/MetroWidgetDemos/ListExpand/components/WidgetListHandler.vue +150 -0
  95. package/MetroWidgetDemos/ListExpand/index.vue +88 -0
  96. package/MetroWidgetDemos/ListExpand/list.js +2421 -0
  97. package/MetroWidgetDemos/RefreshDemo/App.vue +14 -1
  98. package/MetroWidgetDemos/RenderAccelerate/App.vue +142 -0
  99. package/MetroWidgetDemos/RenderAccelerate/AppPage.vue +78 -0
  100. package/MetroWidgetDemos/RenderAccelerate/AppTab.vue +62 -0
  101. package/MetroWidgetDemos/RenderAccelerate/ContentItem.vue +409 -0
  102. package/MetroWidgetDemos/RenderAccelerate/Item.vue +67 -0
  103. package/MetroWidgetDemos/RenderAccelerate/TabItem.vue +100 -0
  104. package/MetroWidgetDemos/RenderAccelerate/ViewSwiper.vue +215 -0
  105. package/MetroWidgetDemos/RenderAccelerate/WidgetItem.vue +107 -0
  106. package/MetroWidgetDemos/SkeletonDiagram/App.vue +35 -8
  107. package/MetroWidgetDemos/SkeletonDiagram/Item.vue +11 -2
  108. package/MetroWidgetDemos/SkeletonDiagram/assets/imageList.js +245 -0
  109. package/MetroWidgetDemos/SkeletonDiagram/data.js +3 -3
  110. package/MetroWidgetDemos/SpatialNav/App.vue +177 -0
  111. package/MetroWidgetDemos/SpatialNav/Buttons.vue +83 -0
  112. package/MetroWidgetDemos/SpatialNav/CustomFocus.vue +57 -0
  113. package/MetroWidgetDemos/{TripleWidget → SpatialNav}/Item.vue +1 -8
  114. package/MetroWidgetDemos/{TripleWidget/WidgetItem.vue → SpatialNav/SimpleFloor.vue} +14 -45
  115. package/MetroWidgetDemos/SpatialNav/StepMw.vue +113 -0
  116. package/MetroWidgetDemos/SpatialNav/TabContent/TabContent.vue +185 -0
  117. package/MetroWidgetDemos/SpatialNav/TripleSection/TripleSection.vue +69 -0
  118. package/MetroWidgetDemos/SpatialNav/TripleSection/WidgetItem.vue +100 -0
  119. package/MetroWidgetDemos/SpatialNav/TvSection/List.vue +75 -0
  120. package/MetroWidgetDemos/SpatialNav/TvSection/TvSection.vue +91 -0
  121. package/MetroWidgetDemos/basic2/App.vue +407 -0
  122. package/MetroWidgetDemos/basic2/Item.vue +68 -0
  123. package/MetroWidgetDemos/direction/App.vue +22 -0
  124. package/MetroWidgetDemos/gazeFocusDiff/App.vue +126 -0
  125. package/MetroWidgetDemos/gazeFocusDiff/Item.vue +87 -0
  126. package/MetroWidgetDemos/minimalUsage/App.vue +66 -0
  127. package/MetroWidgetDemos/minimalUsage/Item.vue +54 -0
  128. package/MetroWidgetDemos/ninePatchFocusPage/App.vue +23 -7
  129. package/MetroWidgetDemos/ninePatchFocusPage/Item.vue +7 -5
  130. package/MetroWidgetDemos/ninePatchFocusPage/focusConstants.js +2 -0
  131. package/MetroWidgetDemos/routeList.js +216 -12
  132. package/MetroWidgetDemos/slideSetting/App.vue +288 -99
  133. package/MetroWidgetDemos/zIndex/App.vue +117 -0
  134. package/MetroWidgetDemos/zIndex/Item.vue +61 -0
  135. package/NinePatchTester/App.vue +24 -31
  136. package/PreDecode/App.vue +140 -0
  137. package/ReactiveTest/App.vue +115 -0
  138. package/ReactiveTest/Item.vue +92 -0
  139. package/ReactiveTest/assets/imageList.js +245 -0
  140. package/ReactiveTest/component/TestSmartDiv.vue +50 -0
  141. package/ReactiveTest/component/TestSmartDivSrcList.vue +74 -0
  142. package/ReactiveTest/component/TestSmartImage.vue +46 -0
  143. package/ReactiveTest/component/TestSmartImageSrcList.vue +90 -0
  144. package/ReactiveTest/component/TestSmartImageStyle.vue +41 -0
  145. package/ReactiveTest/data.js +49 -0
  146. package/ScreenToBlob/App.vue +250 -0
  147. package/ScrollBoxTest/App.vue +52 -28
  148. package/ScrollBoxTest/ClipBar.vue +64 -2
  149. package/ScrollBoxTest/NinePatchBar.vue +64 -2
  150. package/ScrollBoxTest/SizeDivBar.vue +64 -2
  151. package/SecTorTest/App.vue +9 -3
  152. package/SpringFestival/SpringFestivalScene/FreeMoveBuilder.js +3 -3
  153. package/SyncDecode/App.vue +137 -0
  154. package/TextSizeLimit/App.vue +211 -0
  155. package/TextureAnimation/App3.vue +11 -1
  156. package/TouchWidget/App.vue +90 -5
  157. package/TouchWidget/WidgetItem.vue +1 -0
  158. package/TransitPage/App.vue +2 -0
  159. package/assets/logo.png +0 -0
  160. package/package.json +1 -1
  161. package/DemoForOperator/BookFlip/BookFlip/FlipPage.vue +0 -179
  162. package/DemoForOperator/BookFlip/BookFlip/FlippingBook.vue +0 -310
  163. package/DemoForOperator/BookFlip/BookFlip/flip.glsl +0 -135
  164. package/DemoForOperator/Genie/geniePakcer/Genie.vue +0 -741
  165. package/DemoForOperator/LongChatBox/TextManager.ts +0 -147
  166. package/DemoForOperator/LongChatBox/VirtualList.vue +0 -298
  167. package/DemoForOperator/LongChatBox/utile.js +0 -331
  168. package/DivMetroPerformance/App.vue +0 -157
  169. package/DivMetroPerformance/Item.vue +0 -58
  170. package/DivMetroPerformance/assets/bg.jpg +0 -0
  171. package/DivMetroPerformance/assets/coupon_content.png +0 -0
  172. package/DivMetroPerformance/assets/coupon_left.png +0 -0
  173. package/DivMetroPerformance/assets/coupon_mid.png +0 -0
  174. package/DivMetroPerformance/assets/coupon_right.png +0 -0
  175. package/DivMetroPerformance/assets/focus_border.png +0 -0
  176. package/DivMetroPerformance/assets/holder_logo.png +0 -0
  177. package/DivMetroPerformance/assets/jrbm.png +0 -0
  178. package/DivMetroPerformance/assets/line_left.png +0 -0
  179. package/DivMetroPerformance/assets/line_mid.png +0 -0
  180. package/DivMetroPerformance/assets/line_right.png +0 -0
  181. package/DivMetroPerformance/assets/loading.png +0 -0
  182. package/DivMetroPerformance/assets/logo.png +0 -0
  183. package/DivMetroPerformance/assets/mcjx.png +0 -0
  184. package/DivMetroPerformance/assets/tao.png +0 -0
  185. package/DivMetroPerformance/assets/tmall.png +0 -0
  186. package/DivMetroPerformance/border.png +0 -0
  187. package/DivMetroPerformance/components/ContentItem.vue +0 -384
  188. package/DivMetroPerformance/components/MyTab.vue +0 -129
  189. package/DivMetroPerformance/data.js +0 -124
  190. package/DivMetroPerformance/utils/GridItem.vue +0 -28
  191. package/DivMetroPerformance/utils/GridPlate.vue +0 -85
  192. package/MediaDemo/App.vue +0 -127
  193. package/MediaDemo/assets/audio-poster.png +0 -0
  194. package/MediaDemo/components/Button.vue +0 -69
  195. package/MediaDemo/components/Controllor.vue +0 -286
  196. package/MediaDemo/components/StatusBar.vue +0 -100
  197. package/MediaDemo/components/frames/AudioFrame.vue +0 -39
  198. package/MediaDemo/components/frames/AudioPoster.vue +0 -48
  199. package/MediaDemo/components/frames/MediaFrame.vue +0 -153
  200. package/MediaDemo/components/frames/VideoFrame.vue +0 -39
  201. package/MetroWidgetDemos/TripleWidget/App.vue +0 -87
  202. package/MetroWidgetDemos/TripleWidget/SWidgetItem.vue +0 -99
  203. package/Parkour/App.vue +0 -13
  204. package/Parkour/Common/Context.js +0 -21
  205. package/Parkour/Common/MatchmanInfo.js +0 -62
  206. package/Parkour/Common/Random.js +0 -61
  207. package/Parkour/Common/Sound.js +0 -50
  208. package/Parkour/appConfig/HOW_TO_CONFIG.md +0 -20
  209. package/Parkour/appConfig/app.config.mjs +0 -5
  210. package/Parkour/appConfig/app_sign_private_key_sample.crt +0 -28
  211. package/Parkour/appConfig/app_sign_public_key_sample.pem +0 -9
  212. package/Parkour/appConfig/jsview.config.mjs +0 -39
  213. package/Parkour/assets/Bgimages/bg1.png +0 -0
  214. package/Parkour/assets/Bgimages/bg2.png +0 -0
  215. package/Parkour/assets/Bgimages/bg3.png +0 -0
  216. package/Parkour/assets/Bgimages/bg4.png +0 -0
  217. package/Parkour/assets/Bgimages/bg5.png +0 -0
  218. package/Parkour/assets/audio/jump.mp3 +0 -0
  219. package/Parkour/assets/audio/lose.mp3 +0 -0
  220. package/Parkour/assets/role_skin1/fail.json +0 -44
  221. package/Parkour/assets/role_skin1/fail.png +0 -0
  222. package/Parkour/assets/role_skin1/jump_down.json +0 -20
  223. package/Parkour/assets/role_skin1/jump_down.png +0 -0
  224. package/Parkour/assets/role_skin1/jump_up.json +0 -44
  225. package/Parkour/assets/role_skin1/jump_up.png +0 -0
  226. package/Parkour/assets/role_skin1/roll.json +0 -44
  227. package/Parkour/assets/role_skin1/roll.png +0 -0
  228. package/Parkour/assets/role_skin1/run.json +0 -52
  229. package/Parkour/assets/role_skin1/run.png +0 -0
  230. package/Parkour/components/Backdrop.vue +0 -61
  231. package/Parkour/components/GameSence.vue +0 -602
  232. package/Parkour/components/Matchman.vue +0 -85
  233. package/TextureAnimation/utils/FrameCanvasStore.ts +0 -68
  234. package/TextureAnimation/utils/RotateFrame.vue +0 -146
  235. package/TextureAnimation/utils/circleHaloMask.png +0 -0
  236. package/ThrowMoveDemo/AccelerateDemo.vue +0 -85
  237. package/ThrowMoveDemo/App.vue +0 -104
  238. package/ThrowMoveDemo/LRParabolicDemo.vue +0 -101
  239. package/ThrowMoveDemo/TargetDemo.vue +0 -87
  240. package/ThrowMoveDemo/UDParabolicDemo.vue +0 -92
  241. /package/{AnimPicture/assets → assets}/animated_webp.webp +0 -0
  242. /package/{AnimPicture/assets → assets}/ball_3.webp +0 -0
  243. /package/{AnimPicture/assets → assets}/girl_run.gif +0 -0
  244. /package/{AnimPicture/assets → assets}/quan.webp +0 -0
@@ -1,179 +0,0 @@
1
- <script setup>
2
- import { ref, computed } from "vue";
3
- import { JsvFragShaderView, JsvPreload, buildPreloadInfo } from "jsview";
4
- import pageFlipShader from "./flip.glsl?raw";
5
-
6
- // 定义组件的 props
7
- const props = defineProps({
8
- // 第一张图片资源
9
- imageFrom: {
10
- type: String,
11
- required: true,
12
- },
13
- // 第二张图片资源
14
- imageTo: {
15
- type: String,
16
- required: true,
17
- },
18
- // 初始页
19
- initPage: {
20
- type: String,
21
- default: "from",
22
- },
23
- // 动画持续时间
24
- duration: {
25
- type: Number,
26
- default: 3000,
27
- },
28
- // 宽度
29
- width: {
30
- type: Number,
31
- default: 1280,
32
- },
33
- // 高度
34
- height: {
35
- type: Number,
36
- default: 720,
37
- },
38
- // 书本范围, 单位为组件的百分比
39
- bookRect: {
40
- type: Object,
41
- default: () => ({
42
- left: 0.15,
43
- top: 0.05,
44
- right: 0.85,
45
- bottom: 0.95,
46
- }),
47
- validator: (value) => {
48
- return (
49
- value.left >= 0 &&
50
- value.top >= 0 &&
51
- value.right <= 1 &&
52
- value.bottom <= 1
53
- );
54
- },
55
- },
56
- });
57
-
58
- // 定义事件
59
- const emit = defineEmits(["animEnd"]);
60
-
61
- const curPage = ref(props.initPage == "to" ? 1 : 0); // 0: from, 1: to
62
- const rShowImg = ref(true);
63
- let duringAnim = false;
64
- const rImgUrl = computed(() => {
65
- return curPage.value == 0 ? props.imageFrom : props.imageTo;
66
- });
67
-
68
- const rImgLayout = computed(() => {
69
- const cBookRect = props.bookRect;
70
- return {
71
- left: cBookRect.left * props.width,
72
- top: cBookRect.top * props.height,
73
- width: (cBookRect.right - cBookRect.left) * props.width,
74
- height: (cBookRect.bottom - cBookRect.top) * props.height,
75
- };
76
- });
77
-
78
- // 修改着色器代码,替换书籍范围常量
79
- const rModifiedShader = computed(() => {
80
- // 替换着色器中的 BOOK_BOUND 定义
81
- return pageFlipShader.replace(
82
- "#define BOOK_BOUND vec4(0.15, 0.05, 0.85, 0.95)",
83
- `#define BOOK_BOUND vec4(${props.bookRect.left.toFixed(6)}, ${
84
- 1 - props.bookRect.bottom.toFixed(6)
85
- }, ${props.bookRect.right.toFixed(6)}, ${
86
- 1 - props.bookRect.top.toFixed(6)
87
- })`
88
- );
89
- });
90
-
91
- const rPageFlipSettings = computed(() => {
92
- return {
93
- name: "pageFlip",
94
- shader: rModifiedShader.value,
95
- uniforms: [],
96
- textures: [
97
- {
98
- name: "iChannel0",
99
- resource: props.imageFrom,
100
- },
101
- {
102
- name: "iChannel1",
103
- resource: props.imageTo,
104
- },
105
- ],
106
- duration: props.duration,
107
- onEnd: (id, cStatus) => {
108
- emit("animEnd", cStatus);
109
-
110
- curPage.value = curPage.value == 0 ? 1 : 0;
111
- rShowImg.value = true;
112
- duringAnim = false;
113
- },
114
- };
115
- });
116
-
117
- const rWidgetRef = ref();
118
- const rIsPreloadDone = ref(false);
119
- let vPendingAnim = false;
120
-
121
- const rPreloadList = computed(() => {
122
- return [buildPreloadInfo(props.imageFrom), buildPreloadInfo(props.imageTo)];
123
- });
124
-
125
- const handlePreloadDone = () => {
126
- console.log("图片预加载完成");
127
- rIsPreloadDone.value = true;
128
- if (vPendingAnim) {
129
- _startAnim();
130
- vPendingAnim = false;
131
- }
132
- };
133
-
134
- // 内部实际执行动画的方法
135
- const _startAnim = (reverse = false) => {
136
- console.log("开始翻页动画", reverse);
137
- duringAnim = true;
138
- rShowImg.value = false;
139
- rWidgetRef.value?.startAnim(undefined, undefined, reverse);
140
- };
141
-
142
- // 暴露组件方法给父组件
143
- defineExpose({
144
- /**
145
- * 翻页
146
- */
147
- flip: () => {
148
- if (duringAnim) {
149
- return;
150
- }
151
- if (rIsPreloadDone.value) {
152
- _startAnim(curPage.value == 1);
153
- } else {
154
- vPendingAnim = true;
155
- }
156
- },
157
- getCurPage: () => {
158
- return curPage == 0 ? "from" : "to";
159
- },
160
- });
161
- </script>
162
-
163
- <template>
164
- <jsv-preload
165
- :preloadList="rPreloadList"
166
- :onPreloadDone="handlePreloadDone"
167
- ></jsv-preload>
168
- <jsv-frag-shader-view
169
- ref="rWidgetRef"
170
- :style="{ left: 0, top: 0, width: width, height: height }"
171
- :duration="rPageFlipSettings.duration"
172
- :shaderStr="rPageFlipSettings.shader"
173
- :autoplay="false"
174
- :textures="rPageFlipSettings.textures"
175
- :onEnd="rPageFlipSettings.onEnd"
176
- :hideAfterEnd="false"
177
- ></jsv-frag-shader-view>
178
- <img v-if="rShowImg" :src="rImgUrl" :style="rImgLayout" />
179
- </template>
@@ -1,310 +0,0 @@
1
- <script>
2
- import { JsvTextureStoreApi } from "jsview";
3
-
4
- const FLIP_STATUS_IDLE = 0;
5
- const FLIP_STATUS_WAIT_DIV_READY = 1;
6
- const FLIP_STATUS_TAKING = 2;
7
- const FLIP_STATUS_READY = 3;
8
-
9
- function takeTexture(pageDivRef, pageIndex) {
10
- // 抓取界面
11
- let holder = {
12
- promiseRef: null,
13
- textureRef: null,
14
- };
15
-
16
- holder.promiseRef = new Promise((resolve, reject) => {
17
- holder.textureRef = JsvTextureStoreApi.capture2Texture(
18
- pageDivRef,
19
- (textureAccessName) => {
20
- if (textureAccessName != "") {
21
- resolve(textureAccessName);
22
- } else {
23
- reject();
24
- }
25
- }
26
- );
27
- });
28
- return holder;
29
- }
30
- </script>
31
-
32
- <script setup>
33
- import { computed, shallowRef, onUnmounted, onMounted, reactive } from "vue";
34
- import pageFlipShader from "./flip.glsl?raw";
35
- import { JsvFragShaderView } from "jsview";
36
-
37
- // 定义组件的 props
38
- const props = defineProps({
39
- // 页面总数
40
- pageCount: {
41
- type: Number,
42
- default: 2,
43
- },
44
-
45
- // 初始化时显示的页面索引
46
- initPageIndex: {
47
- type: Number,
48
- default: 0,
49
- },
50
-
51
- // 组件的坐标 x,y
52
- position: {
53
- type: Object,
54
- default: () => ({
55
- x: 0,
56
- y: 0,
57
- }),
58
- validator: (value) => {
59
- return !isNaN(value.x) && !isNaN(value.y);
60
- },
61
- },
62
-
63
- // page的width,height
64
- pageSize: {
65
- type: Object,
66
- required: true,
67
- validator: (value) => {
68
- return !isNaN(value.width) && !isNaN(value.height);
69
- },
70
- },
71
-
72
- // 动画持续时间
73
- duration: {
74
- type: Number,
75
- default: 600,
76
- },
77
- });
78
-
79
- const cFlipArea = {
80
- width: Math.ceil(props.pageSize.width / 1.0),
81
- height: Math.ceil(props.pageSize.height / 0.8),
82
- x: 0,
83
- y: 0,
84
- };
85
- // cFlipArea.x = Math.ceil((props.pageSize.width - cFlipArea.width) / 2); // 翻页区域对齐原div区域
86
- // cFlipArea.y = Math.ceil((props.pageSize.height - cFlipArea.height) / 2); // 翻页区域对齐原div区域
87
-
88
- // 创建rPageList数据,内容为shallowRef(null)
89
- const rPageList = Array(props.pageCount)
90
- .fill()
91
- .map((_, idx) => ({
92
- index: idx,
93
- divRef: null,
94
- pageReady: false,
95
- }));
96
-
97
- const rPageLives = reactive([props.initPageIndex, -1]);
98
-
99
- const rCurrentPageIndex = shallowRef(props.initPageIndex);
100
-
101
- const rPrevPageIndex = shallowRef(-1);
102
-
103
- // fragShaderView的Texture管理
104
- const rTextureStatus = shallowRef(FLIP_STATUS_IDLE);
105
- const rTextureNames = [shallowRef(null), shallowRef(null)];
106
- let vTextureHolder = {
107
- holder0: null,
108
- holder1: null,
109
- token: 0,
110
- };
111
- let vTexturePromiseAll = null;
112
-
113
- const rPageFlipSettings = computed(() => {
114
- return {
115
- name: "pageFlip",
116
- shader: pageFlipShader,
117
- uniforms: [],
118
- textures: [
119
- {
120
- name: "iChannel0",
121
- resource: "jsvtexturestore://" + rTextureNames[1].value,
122
- },
123
- {
124
- name: "iChannel1",
125
- resource: "jsvtexturestore://" + rTextureNames[0].value,
126
- },
127
- ],
128
- duration: props.duration,
129
- onEnd: (end_or_cancel) => {
130
- // 结束动画, 以触发prev页面的销毁
131
- if (rTextureStatus.value == FLIP_STATUS_READY) {
132
- // 非开新界面时,结束动画后,恢复到空闲状态
133
- rTextureStatus.value = FLIP_STATUS_IDLE;
134
- }
135
- },
136
- };
137
- });
138
-
139
- // 新进界面触发flush处理,第一个flush传来后才启动动画
140
- const fncTriggerFlush = (pageIndex) => {
141
- rPageList[pageIndex].pageReady = true;
142
-
143
- // prev和current的page都ready了就启动翻页动画
144
- if (
145
- rTextureStatus.value == FLIP_STATUS_WAIT_DIV_READY &&
146
- rPageList[rPrevPageIndex.value].pageReady &&
147
- rPageList[rCurrentPageIndex.value].pageReady
148
- ) {
149
- // 抓取界面
150
-
151
- // 取消上一次的抓取
152
- vTextureHolder.holder0?.textureRef.cancel();
153
- vTextureHolder.holder1?.textureRef.cancel();
154
-
155
- // 抓取当前界面
156
- rTextureStatus.value = FLIP_STATUS_TAKING;
157
-
158
- vTextureHolder = {
159
- holder0: takeTexture(
160
- rPageList[rPageLives[0]].divRef,
161
- rPageList[rPageLives[0]].index
162
- ),
163
- holder1: takeTexture(
164
- rPageList[rPageLives[1]].divRef,
165
- rPageList[rPageLives[1]].index
166
- ),
167
- };
168
-
169
- let holders = vTextureHolder;
170
-
171
- // TODO: promise.all的引用和unmount时释放, 可能可以规避组件退出时内存泄露问题
172
- vTexturePromiseAll = Promise.all([
173
- holders.holder0.promiseRef,
174
- holders.holder1.promiseRef,
175
- ])
176
- .then(([page_0_texture, page_1_texture]) => {
177
- if (rCurrentPageIndex.value > rPrevPageIndex.value) {
178
- rTextureNames[0].value = page_0_texture;
179
- rTextureNames[1].value = page_1_texture;
180
- } else {
181
- rTextureNames[0].value = page_1_texture;
182
- rTextureNames[1].value = page_0_texture;
183
- }
184
- rTextureStatus.value = FLIP_STATUS_READY;
185
- })
186
- .finally(() => {
187
- // resolve或者reject时,释放holder引用
188
- holders.holder0 = null;
189
- holders.holder1 = null;
190
- });
191
- }
192
- };
193
-
194
- // 暴露组件方法给父组件
195
- defineExpose({
196
- /**
197
- * 设置当前页码
198
- * @param {number} pageIndex - 要设置的页码索引
199
- */
200
- setCurrentPage: (pageIndex) => {
201
- if (pageIndex < 0 || pageIndex >= props.pageCount) {
202
- console.error(`页码超出范围: ${pageIndex}, 总页数: ${props.pageCount}`);
203
- return;
204
- }
205
-
206
- if (pageIndex == rCurrentPageIndex.value) {
207
- // 如果当前页码和要设置的页码相同,则不进行操作
208
- return;
209
- }
210
-
211
- // 更新页码索引
212
- // 保存旧的当前页码
213
- const oldCurrentIndex = rCurrentPageIndex.value;
214
-
215
- if (
216
- rTextureStatus.value != FLIP_STATUS_IDLE &&
217
- pageIndex == rPrevPageIndex.value &&
218
- rPageList[pageIndex].pageReady
219
- ) {
220
- // 在动画过程中,翻页反向,此时由于页面不重新mount,不会触发fncTriggerFlush
221
- // 需要手动触发fncTriggerFlush
222
- Promise.resolve().then(() => {
223
- fncTriggerFlush(pageIndex);
224
- });
225
- }
226
-
227
- // 设置当前页码
228
- rCurrentPageIndex.value = pageIndex;
229
- rPrevPageIndex.value = oldCurrentIndex;
230
-
231
- // 界面进入动画状态
232
- rTextureStatus.value = FLIP_STATUS_WAIT_DIV_READY;
233
-
234
- // 设置新页面为未准备就绪
235
- rPageList[pageIndex].pageReady = false;
236
-
237
- rPageLives[0] = pageIndex;
238
- rPageLives[1] = oldCurrentIndex; // 老页面遮挡在上面
239
- },
240
- });
241
-
242
- onMounted(() => {});
243
-
244
- onUnmounted(() => {
245
- // 取消截屏处理,并释放promise引用
246
- vTextureHolder.holder0?.textureRef.cancel();
247
- vTextureHolder.holder1?.textureRef.cancel();
248
- vTextureHolder.holder0 = null;
249
- vTextureHolder.holder1 = null;
250
-
251
- // 释放PromiseAll引用
252
- vTexturePromiseAll = null;
253
- });
254
- </script>
255
-
256
- <template>
257
- <div
258
- :style="{
259
- left: props.position.x,
260
- top: props.position.y,
261
- }"
262
- >
263
- <!-- 通过key锁定, 当 currentPageIndex 变化时,已存在页面不会重新创建 -->
264
- <div
265
- v-show="rTextureStatus != FLIP_STATUS_READY"
266
- v-for="pageIndex in rPageLives"
267
- :key="pageIndex"
268
- >
269
- <div
270
- v-if="
271
- pageIndex == rCurrentPageIndex || rTextureStatus != FLIP_STATUS_IDLE
272
- "
273
- :ref="(el) => (rPageList[pageIndex].divRef = el)"
274
- :style="{
275
- width: props.pageSize.width,
276
- height: props.pageSize.height,
277
- }"
278
- >
279
- <slot :pageIndex="pageIndex" :triggerFlush="fncTriggerFlush"></slot>
280
- </div>
281
- <!-- <div
282
- :style="{
283
- width: 300,
284
- height: 100,
285
- fontSize: 20,
286
- color: 'rgba(255,255,255,1)',
287
- lineHeight: 100,
288
- }"
289
- >
290
- 当前界面: {{ "" + pageIndex + " " + rCurrentPageIndex }}
291
- </div> -->
292
- </div>
293
-
294
- <jsv-frag-shader-view
295
- v-if="rTextureStatus == FLIP_STATUS_READY"
296
- :style="{
297
- left: cFlipArea.x,
298
- top: cFlipArea.y,
299
- width: cFlipArea.width,
300
- height: cFlipArea.height,
301
- }"
302
- :duration="rPageFlipSettings.duration"
303
- :shaderStr="rPageFlipSettings.shader"
304
- :autoplay="true"
305
- :reverseAnimate="rCurrentPageIndex < rPrevPageIndex"
306
- :textures="rPageFlipSettings.textures"
307
- :onEnd="rPageFlipSettings.onEnd"
308
- ></jsv-frag-shader-view>
309
- </div>
310
- </template>
@@ -1,135 +0,0 @@
1
- #define PI 3.14159265359
2
- #define RADIUS .05
3
- #define LIGHT_DIR vec3(5,3,1)
4
- #define SPECULAR_SHININESS 24.0
5
- #define SPECULAR_COLOR vec3(1.0,1.0,1.0)
6
- #define SPECULAR_POWER 10.0
7
- //书籍范围的百分比
8
- #define BOOK_BOUND vec4(0.00, 0.20, 1.00, 1.00)
9
-
10
- // 优化的快速反正弦函数
11
- float fastAsin(float x) {
12
- // 使用更少的项来近似计算
13
- // return x + (1.0 / 6.0) * x3 + (3.0 / 40.0) * x5 + (5.0 / 112.0) * x7;
14
- return x + x*x*x*(1.0/6.0) + x*x*x*x*x*(3.0/40.0);
15
- }
16
-
17
- // 优化的矩形检测函数
18
- bool inRect(vec2 uv, vec4 rect) {
19
- return all(greaterThanEqual(uv, rect.xy)) && all(lessThanEqual(uv, rect.zw));
20
- }
21
-
22
- vec3 fakeSpine(vec3 col, float t, float darken)
23
- {
24
- return mix(col * darken, col, min(1.0, sqrt(abs(t) * 30.0)));
25
- }
26
-
27
- vec3 fakeNormal(float t, float center)
28
- {
29
- t -= center;
30
- float interp = (1.0 - abs(t * 2.0)) * PI + PI * 0.75;
31
-
32
- vec3 normal = vec3(abs(sin(interp)) ,0. , abs(cos(interp)));
33
-
34
- return mix(normal, vec3(0.0, 0.0, 1.0), min(1.0, sqrt(abs(t) * 5.0)));
35
- }
36
-
37
- vec3 specular(vec3 viewDir, vec3 normal)
38
- {
39
- vec3 lightDir = normalize(LIGHT_DIR);
40
- float dist = length(lightDir);
41
- vec3 halfV = normalize(lightDir + normalize(viewDir));
42
-
43
- float NdotH = dot(normal, halfV);
44
- float intensity = pow(max(NdotH, 0.0), SPECULAR_SHININESS);
45
-
46
- return intensity * SPECULAR_COLOR * SPECULAR_POWER / dist;
47
- }
48
-
49
- void mainImage(out vec4 fragColor, in vec2 fragCoord) {
50
- vec2 aspect = iResolution.xy / iResolution.y;
51
- vec2 uv = fragCoord / iResolution.y;
52
- // vec2 mouse = iMouse.xy / iResolution.y;
53
-
54
- vec4 bgColor = vec4(0.0, 0.0, 0.0, 0.0);
55
-
56
- vec4 viewBounds = vec4(0., 0., aspect);
57
- vec4 bookBounds = vec4(BOOK_BOUND.xy * aspect, BOOK_BOUND.zw * aspect);
58
- vec2 bookSize = bookBounds.zw - bookBounds.xy;
59
- vec2 bookAspect = bookSize.xy / bookSize.y;
60
- vec4 bookUvBounds = vec4(0.0, 0.0, bookAspect);
61
- vec2 bookUv = (uv - bookBounds.xy) / bookSize.y;
62
- // mouse = (mouse - bookBounds.xy) / bookSize.y;
63
-
64
- // 优化鼠标轨迹计算
65
- float timeFact = 1. - iTime / iDuration;
66
- vec2 mouse = vec2(timeFact, 1.2 * timeFact * (timeFact - 1.0) + 1.0) * bookAspect;
67
- // 防止鼠标超出书本范围
68
- mouse = clamp(mouse, vec2(0.0), bookAspect - vec2(1e-2));
69
-
70
- //bookAspect为bookUv的右上角
71
- vec2 mouseDir = normalize(bookAspect - mouse);
72
- vec2 origin = mouse - mouseDir * mouse.x / abs(mouseDir.x);
73
- vec2 axisPos = (mouse + bookAspect) * 0.5; // 使用乘法代替除法
74
-
75
- float axisDist = length(axisPos - origin);
76
-
77
- float proj = dot(bookUv - origin, mouseDir);
78
- float dist = proj - axisDist;
79
- vec2 linePoint = bookUv - dist * mouseDir;
80
-
81
- float radius = clamp(2.0 * mouse.x * RADIUS, 0.0, RADIUS);
82
-
83
- // 提前计算常用值
84
- bool inBookBounds = inRect(uv, bookBounds);
85
-
86
- if(dist > radius) {
87
- if (inRect(uv, bookBounds)) {
88
- fragColor = jsvTexture2D(iChannel1, bookUv / bookAspect);
89
- } else {
90
- fragColor = bgColor;
91
- }
92
- } else if(dist >= 0.0) {
93
- //圆柱体部分
94
- if (radius > 1e-5) {
95
- float theta = fastAsin(dist / radius);
96
- vec2 p1 = linePoint + mouseDir * theta * radius;
97
- vec2 p2 = linePoint + mouseDir * (PI - theta) * radius;
98
-
99
- vec2 uv2 = p2 / bookAspect;
100
- uv2.x = 1.0 - uv2.x;
101
-
102
- vec2 uv1 = p1 / bookAspect;
103
-
104
- bool inP2 = inRect(p2, bookUvBounds);
105
- bool inP1 = inRect(p1, bookUvBounds);
106
-
107
- if(inP2) {
108
- fragColor = jsvTexture2D(iChannel1, uv2);
109
- fragColor.xyz += specular(vec3(0.0, 0.0, 1.0), fakeNormal(dist - radius * 0.5, 0.0)) * 0.2;
110
- } else if(inP1) {
111
- fragColor = jsvTexture2D(iChannel0, uv1);
112
- } else {
113
- fragColor = bgColor;
114
- }
115
- }
116
- } else {
117
- vec2 p = linePoint + mouseDir * (abs(dist) + PI * radius);
118
- bool inP = inRect(p, bookUvBounds);
119
-
120
- if (inP) {
121
- vec2 uv = p / bookAspect;
122
- uv.x = 1.0 - uv.x;
123
- fragColor = jsvTexture2D(iChannel1, uv);
124
- } else if (inRect(bookUv, bookUvBounds) ) {
125
- vec2 uv2 = bookUv / bookAspect;
126
- fragColor = jsvTexture2D(iChannel0, uv2);
127
- } else {
128
- fragColor = bgColor;
129
- }
130
- }
131
-
132
- if (inBookBounds) {
133
- fragColor.xyz = fakeSpine(fragColor.xyz, dist - radius, 0.0);
134
- }
135
- }