index.vue 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. <template>
  2. <div class="schedule" @touchmove="touchmove">
  3. <!-- 上划图标 -->
  4. <div class="up_icon">
  5. <div class="center0">
  6. <div class="up_left"></div>
  7. <div class="up_right"></div>
  8. </div>
  9. </div>
  10. <div ref="main" class="page" @touchstart="touchstart" @touchend="touchend">
  11. <pageFirst
  12. :class="{
  13. animate__animated: page === 0,
  14. animate__fadeInUp: isUp && page === 0,
  15. animate__fadeInDown: !isUp && page === 0,
  16. }"
  17. v-if="page === 0"
  18. />
  19. <pageThird
  20. :class="{
  21. animate__animated: page === 1,
  22. animate__fadeInUp: isUp && page === 1,
  23. animate__fadeInDown: !isUp && page === 1,
  24. }"
  25. v-if="page === 1"
  26. />
  27. <pageFifth
  28. :class="{
  29. animate__animated: page === 2,
  30. animate__fadeInUp: isUp && page === 2,
  31. animate__fadeInDown: !isUp && page === 2,
  32. }"
  33. v-if="page === 2"
  34. />
  35. <page4
  36. :class="{
  37. animate__animated: page === 3,
  38. animate__fadeInUp: isUp && page === 3,
  39. animate__fadeInDown: !isUp && page === 3,
  40. }"
  41. v-if="page === 3"
  42. />
  43. <page7
  44. :class="{
  45. animate__animated: page === 4,
  46. animate__fadeInUp: isUp && page === 4,
  47. animate__fadeInDown: !isUp && page === 4,
  48. }"
  49. v-if="page === 4"
  50. />
  51. <pageSexth
  52. :class="{
  53. animate__animated: page === 5,
  54. animate__fadeInUp: isUp && page === 5,
  55. animate__fadeInDown: !isUp && page === 5,
  56. }"
  57. v-if="page === 5"
  58. />
  59. <page12
  60. :class="{
  61. animate__animated: page === 6,
  62. animate__fadeInUp: isUp && page === 6,
  63. animate__fadeInDown: !isUp && page === 6,
  64. }"
  65. v-if="page === 6"
  66. />
  67. <page8
  68. :class="{
  69. animate__animated: page === 7,
  70. animate__fadeInUp: isUp && page === 7,
  71. animate__fadeInDown: !isUp && page === 7,
  72. }"
  73. v-if="page === 7"
  74. />
  75. <page9
  76. :class="{
  77. animate__animated: page === 8,
  78. animate__fadeInUp: isUp && page === 8,
  79. animate__fadeInDown: !isUp && page === 8,
  80. }"
  81. v-if="page === 8"
  82. />
  83. <page10
  84. :class="{
  85. animate__animated: page === 9,
  86. animate__fadeInUp: isUp && page === 9,
  87. animate__fadeInDown: !isUp && page === 9,
  88. }"
  89. v-if="page === 9"
  90. />
  91. <page11
  92. :class="{
  93. animate__animated: page === 10,
  94. animate__fadeInUp: isUp && page === 10,
  95. animate__fadeInDown: !isUp && page === 10,
  96. }"
  97. v-if="page === 10"
  98. />
  99. <page13
  100. :class="{
  101. animate__animated: page === 11,
  102. animate__fadeInUp: isUp && page === 11,
  103. animate__fadeInDown: !isUp && page === 11,
  104. }"
  105. v-if="page === 11"
  106. />
  107. </div>
  108. </div>
  109. </template>
  110. <script setup>
  111. import { ref } from 'vue';
  112. import pageFirst from './page1.vue';
  113. import pageThird from './page3.vue';
  114. import page4 from './page4.vue';
  115. import pageFifth from './page5.vue';
  116. import pageSexth from './page6.vue';
  117. import page7 from './page7.vue';
  118. import page8 from './page8.vue';
  119. import page9 from './page9.vue';
  120. import page10 from './page10.vue';
  121. import page11 from './page11.vue';
  122. import page12 from './page12.vue';
  123. import page13 from './page13.vue';
  124. // import { onMounted, reactive } from "vue";
  125. // import { isIpad, isIpod, isIphone } from "../../utils/isTerminal";
  126. /**
  127. * window.$originData.orginParames.title 页面标题
  128. * window.$originData.orginParames.parameters 固定参数值
  129. * window.$originData.urlParames url参数
  130. */
  131. // console.log(window.$originData);
  132. // const play_stats = ref(false);
  133. const main = ref(null);
  134. const page = ref(0);
  135. const isUp = ref(true);
  136. let startStats = 0;
  137. let time = Date.now();
  138. let startY = 0;
  139. const isChangePage = cha => {
  140. let out = false; // false 不能翻页 true 能翻页
  141. let sondiv = getinnerele();
  142. // 视口高度 main.value.offsetHeight
  143. // 内容高度 sondiv.offsetHeight
  144. // 视口基本大于内容 则可以翻页
  145. /**
  146. * 初始化y值或结束y值不在翻页区间,则不能翻页
  147. * 翻页区间是scrolltop 10 以内 和 底部剩余空间10 以内
  148. */
  149. let h = main.value.offsetHeight + main.value.scrollTop;
  150. // if (Math.pow(cha, 2) < 6400) out = true;
  151. let timeRange = Date.now() - time > 50;
  152. if (cha < -80 && startStats < 10 && timeRange) {
  153. // 下滑
  154. /**
  155. * 下滑初始滚动小于10 -翻页
  156. */
  157. out = true;
  158. } else {
  159. // 上滑
  160. /**
  161. * 下滑剩余小于10 -翻页
  162. */
  163. if (sondiv.offsetHeight - h < 10 && cha > 80 && timeRange) out = true;
  164. }
  165. return out;
  166. };
  167. const touchstart = e => {
  168. time = Date.now();
  169. startStats = main.value.scrollTop;
  170. startY = e.changedTouches[0].clientY;
  171. };
  172. const touchend = e => {
  173. const cha = startY - e.changedTouches[0].clientY;
  174. if (!isChangePage(cha)) return;
  175. // cha > 0 向上滑动手指
  176. // cha < 0 向下滑动手指
  177. // 初始位置滚动为0的,则判断距离25即可
  178. // 距离足够则滑动到下一页;
  179. let n = cha > 0 ? 1 : -1;
  180. let dn = n + page.value;
  181. let len = 11;
  182. // if (dn < 0) dn = len;
  183. // if (dn > len) dn = 0;
  184. if (dn < 0) return;
  185. if (dn > len) return;
  186. isUp.value = n === 1;
  187. page.value = dn;
  188. main.value.scrollTop = 0;
  189. };
  190. const touchmove = e => {
  191. const cha = startY - e.changedTouches[0].clientY;
  192. if (main.value.scrollTop <= 1 && cha < 0) e.preventDefault();
  193. const ele = getinnerele()
  194. if (cha > 0 && main.value.offsetHeight + main.value.scrollTop >= ele.offsetHeight ) e.preventDefault();
  195. };
  196. const getinnerele = () => {
  197. let nodes = main.value.childNodes || [];
  198. return nodes[page.value];
  199. };
  200. </script>
  201. <style lang="scss">
  202. // 动画库
  203. @import url(./sass/animation.scss);
  204. // 字体库
  205. @import url(./sass/base.scss);
  206. // @import url(https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css);
  207. .schedule {
  208. width: 100vw;
  209. height: 100vh;
  210. overflow: hidden;
  211. background-image: url(./img/background.jpg);
  212. background-size: 100% 100%;
  213. max-width: 750px;
  214. min-width: 330px;
  215. margin: 0 auto;
  216. display: block;
  217. .imgbtn {
  218. position: absolute;
  219. top: 16px;
  220. right: 16px;
  221. z-index: 10;
  222. }
  223. .rotating {
  224. -webkit-animation: rotating 1.2s linear infinite;
  225. -moz-animation: rotating 1.2s linear infinite;
  226. -o-animation: rotating 1.2s linear infinite;
  227. animation: rotating 1.2s linear infinite;
  228. }
  229. .up_icon {
  230. width: 24px;
  231. height: 14px;
  232. position: absolute;
  233. z-index: 10;
  234. bottom: 30px;
  235. left: 50%;
  236. transform: translateX(-50%);
  237. font-size: 0;
  238. .center0 {
  239. position: relative;
  240. display: flex;
  241. -webkit-animation: start 1.5s ease-in-out infinite;
  242. -moz-animation: start 1.5s infinite ease-in-out;
  243. animation: start 1.5s ease-in-out infinite;
  244. .up_left,
  245. .up_right {
  246. overflow: hidden;
  247. height: 14px;
  248. width: 12px;
  249. flex: 1;
  250. padding-top: 5px;
  251. }
  252. .up_left::after,
  253. .up_right::after {
  254. background-color: #fff;
  255. width: 14px;
  256. height: 5px;
  257. border-radius: 2px;
  258. position: absolute;
  259. display: block;
  260. content: ' ';
  261. }
  262. .up_left::after {
  263. transform: rotate(-40deg);
  264. box-shadow: 1px 1px 1px #646464;
  265. -webkit-transform: rotate(-40deg);
  266. }
  267. .up_right::after {
  268. -webkit-transform: rotate(40deg);
  269. transform: rotate(40deg);
  270. box-shadow: 1px -1px 1px #646464;
  271. margin-left: -5px;
  272. }
  273. }
  274. }
  275. .page {
  276. width: 100%;
  277. height: 100vh;
  278. margin: 0 auto;
  279. overflow-y: auto;
  280. & > div {
  281. width: 100%;
  282. }
  283. }
  284. .excess-enter-active,
  285. .excess-leave-active {
  286. transition: opacity 0.1s ease;
  287. }
  288. .excess-enter-from,
  289. .excess-leave-to {
  290. opacity: 0;
  291. }
  292. }
  293. </style>