index.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <template>
  2. <div class="AEROSPACE2023" @touchmove="touchmove">
  3. <div ref="main" class="page" @touchstart="touchstart" @touchend="touchend">
  4. <page0
  5. :class="{
  6. animate__animated: page === 0,
  7. animate__fadeInUp: isUp && page === 0,
  8. animate__fadeInDown: !isUp && page === 0,
  9. }"
  10. v-if="page === 0"
  11. />
  12. <page1
  13. :class="{
  14. animate__animated: page === 1,
  15. animate__fadeInUp: isUp && page === 1,
  16. animate__fadeInDown: !isUp && page === 1,
  17. }"
  18. v-if="page === 1"
  19. />
  20. <page2
  21. :class="{
  22. animate__animated: page === 2,
  23. animate__fadeInUp: isUp && page === 2,
  24. animate__fadeInDown: !isUp && page === 2,
  25. }"
  26. v-if="page === 2"
  27. />
  28. <page3
  29. :class="{
  30. animate__animated: page === 3,
  31. animate__fadeInUp: isUp && page === 3,
  32. animate__fadeInDown: !isUp && page === 3,
  33. }"
  34. v-if="page === 3"
  35. />
  36. <page4
  37. :class="{
  38. animate__animated: page === 4,
  39. animate__fadeInUp: isUp && page === 4,
  40. animate__fadeInDown: !isUp && page === 4,
  41. }"
  42. v-if="page === 4"
  43. />
  44. <page5
  45. :class="{
  46. animate__animated: page === 5,
  47. animate__fadeInUp: isUp && page === 5,
  48. animate__fadeInDown: !isUp && page === 5,
  49. }"
  50. v-if="page === 5"
  51. />
  52. <page6
  53. :class="{
  54. animate__animated: page === 6,
  55. animate__fadeInUp: isUp && page === 6,
  56. animate__fadeInDown: !isUp && page === 6,
  57. }"
  58. v-if="page === 6"
  59. />
  60. </div>
  61. </div>
  62. </template>
  63. <script setup>
  64. import { ref } from 'vue';
  65. import page0 from './page0.vue';
  66. import page1 from './page1.vue';
  67. import page2 from './page2.vue';
  68. import page3 from './page3.vue';
  69. import page4 from './page4.vue';
  70. import page5 from './page5.vue';
  71. import page6 from './page6.vue';
  72. // import { onMounted, reactive } from "vue";
  73. // import { isIpad, isIpod, isIphone } from "../../utils/isTerminal";
  74. /**
  75. * window.$originData.orginParames.title 页面标题
  76. * window.$originData.orginParames.parameters 固定参数值
  77. * window.$originData.urlParames url参数
  78. */
  79. // console.log(window.$originData);
  80. // const play_stats = ref(false);
  81. const main = ref(null);
  82. const page = ref(3);
  83. const isUp = ref(true);
  84. let startStats = 0;
  85. let time = Date.now();
  86. let startY = 0;
  87. const isChangePage = cha => {
  88. let out = false; // false 不能翻页 true 能翻页
  89. let sondiv = getinnerele();
  90. // 视口高度 main.value.offsetHeight
  91. // 内容高度 sondiv.offsetHeight
  92. // 视口基本大于内容 则可以翻页
  93. /**
  94. * 初始化y值或结束y值不在翻页区间,则不能翻页
  95. * 翻页区间是scrolltop 10 以内 和 底部剩余空间10 以内
  96. */
  97. let h = main.value.offsetHeight + main.value.scrollTop;
  98. // if (Math.pow(cha, 2) < 6400) out = true;
  99. let timeRange = Date.now() - time > 50;
  100. if (cha < -80 && startStats < 10 && timeRange) {
  101. // 下滑
  102. /**
  103. * 下滑初始滚动小于10 -翻页
  104. */
  105. out = true;
  106. } else {
  107. // 上滑
  108. /**
  109. * 下滑剩余小于10 -翻页
  110. */
  111. if (sondiv.offsetHeight - h < 10 && cha > 80 && timeRange) out = true;
  112. }
  113. return out;
  114. };
  115. const touchstart = e => {
  116. time = Date.now();
  117. startStats = main.value.scrollTop;
  118. startY = e.changedTouches[0].clientY;
  119. };
  120. const touchend = e => {
  121. const cha = startY - e.changedTouches[0].clientY;
  122. if (!isChangePage(cha)) return;
  123. // cha > 0 向上滑动手指
  124. // cha < 0 向下滑动手指
  125. // 初始位置滚动为0的,则判断距离25即可
  126. // 距离足够则滑动到下一页;
  127. let n = cha > 0 ? 1 : -1;
  128. let dn = n + page.value;
  129. let len = 6;
  130. // if (dn < 0) dn = len;
  131. // if (dn > len) dn = 0;
  132. if (dn < 0) return;
  133. if (dn > len) return;
  134. isUp.value = n === 1;
  135. page.value = dn;
  136. main.value.scrollTop = 0;
  137. };
  138. const touchmove = e => {
  139. const cha = startY - e.changedTouches[0].clientY;
  140. if (main.value.scrollTop <= 1 && cha < 0) e.preventDefault();
  141. const ele = getinnerele()
  142. if (cha > 0 && main.value.offsetHeight + main.value.scrollTop >= ele.offsetHeight ) e.preventDefault();
  143. };
  144. const getinnerele = () => {
  145. let nodes = main.value.childNodes || [];
  146. return nodes[page.value];
  147. };
  148. </script>
  149. <style lang="scss">
  150. // 动画库
  151. @import url(./sass/animation.scss);
  152. // 字体库
  153. @import url(./sass/base.scss);
  154. // @import url(https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css);
  155. .AEROSPACE2023 {
  156. width: 100vw;
  157. height: 100vh;
  158. overflow: hidden;
  159. background-image: url(./img/background.jpg);
  160. background-size: 100% 100%;
  161. max-width: 750px;
  162. min-width: 330px;
  163. margin: 0 auto;
  164. display: block;
  165. .imgbtn {
  166. position: absolute;
  167. top: 16px;
  168. right: 16px;
  169. z-index: 10;
  170. }
  171. .page {
  172. width: 100%;
  173. height: 100vh;
  174. margin: 0 auto;
  175. overflow-y: auto;
  176. & > div {
  177. width: 100%;
  178. }
  179. }
  180. .excess-enter-active,
  181. .excess-leave-active {
  182. transition: opacity 0.1s ease;
  183. }
  184. .excess-enter-from,
  185. .excess-leave-to {
  186. opacity: 0;
  187. }
  188. }
  189. </style>