index.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. <template>
  2. <view class="paper-body">
  3. <view class="paper-wrapper">
  4. <view class="paper-onboarding">
  5. <view class="paper-onboarding-fills" :style="[fillsStyle]">
  6. <view v-for="(item,index) in list" :key="index" class="paper-onboarding-fill"
  7. :style="[{backgroundColor:item.bgColor},fillStyleList[index].fillStyle]">
  8. </view>
  9. </view>
  10. <z-swiper ref="zSwiper" v-model="list" :options="options" @beforeInit="init">
  11. <z-swiper-item v-for="(item,index) in list" :key="index">
  12. <view class="slide-inner">
  13. <image class="slide-image" :src="item.url" />
  14. <view class="slide-title">{{item.title}}</view>
  15. <view class="slide-text">{{item.text}}</view>
  16. </view>
  17. </z-swiper-item>
  18. </z-swiper>
  19. </view>
  20. </view>
  21. </view>
  22. </template>
  23. <script>
  24. export default {
  25. data() {
  26. return {
  27. list: [{
  28. bgColor: "#6002EE",
  29. fillStyle: {},
  30. url: require("../../../static/images/banks.svg"),
  31. title: "Banks",
  32. text: "Banks are financial institutions that provide a wide range of financial services, including savings accounts, loans, investment opportunities, and more."
  33. }, {
  34. bgColor: "#008386",
  35. fillStyle: {},
  36. url: require("../../../static/images/hotels.svg"),
  37. title: "Hotels",
  38. text: "Hotels are establishments that offer accommodation, amenities, and services to travelers and guests, providing a comfortable and convenient stay away from home."
  39. }, {
  40. bgColor: "#a41fa8",
  41. fillStyle: {},
  42. url: require("../../../static/images/business.svg"),
  43. title: "Business",
  44. text: "Business involves activities aimed at creating products or services, generating profits, and contributing to the economy."
  45. }, {
  46. bgColor: "#007700",
  47. fillStyle: {},
  48. url: require("../../../static/images/checkmark.svg"),
  49. title: "Done",
  50. text: "Now you can continue using it."
  51. }],
  52. options: {
  53. effect: 'creative',
  54. direction: 'vertical',
  55. speed: 500,
  56. resistanceRatio: 0,
  57. grabCursor: true,
  58. pagination: {
  59. el: true,
  60. clickable: true,
  61. dynamicBullets: true,
  62. },
  63. creativeEffect: {
  64. progressMultiplier: 2,
  65. prev: {
  66. opacity: 0,
  67. // translate: direction === 'vertical' ? [0, -128, 0] : [-128, 0, 0],
  68. translate: [0, -128, 0],
  69. },
  70. next: {
  71. opacity: 0,
  72. // translate: direction === 'vertical' ? [0, 128, 0] : [128, 0, 0],
  73. translate: [0, 128, 0],
  74. },
  75. },
  76. },
  77. fillsStyle: {},
  78. fillStyleList: [{
  79. fillStyle: {}
  80. },
  81. {
  82. fillStyle: {}
  83. },
  84. {
  85. fillStyle: {}
  86. },
  87. {
  88. fillStyle: {}
  89. },
  90. ],
  91. }
  92. },
  93. mounted() {
  94. this.calcFillSize('vertical');
  95. },
  96. methods: {
  97. init() {
  98. this.$refs.zSwiper.swiper.on("setTranslate", (swiper) => {
  99. this.onTranslate(swiper)
  100. });
  101. this.$refs.zSwiper.swiper.on("setTransition", (swiper, duration) => {
  102. this.onTransition(swiper, duration)
  103. });
  104. },
  105. onTranslate(swiper) {
  106. const {
  107. slides
  108. } = swiper;
  109. for (let i = 0; i < slides.length; i += 1) {
  110. const slideEl = slides[i];
  111. const slideProgress = slideEl.progress;
  112. const progress = 1 - Math.max(Math.min(Math.abs(slideProgress), 1), 0);
  113. if (slideProgress < 0) {
  114. this.$set(this.fillStyleList[i].fillStyle, 'transform', `scale(${progress})`);
  115. } else {
  116. this.$set(this.fillStyleList[i].fillStyle, 'transform', `scale(1)`);
  117. }
  118. }
  119. },
  120. onTransition(swiper, duration) {
  121. this.fillStyleList.forEach((fillEl) => {
  122. this.$set(fillEl.fillStyle, 'transitionDuration', `${duration}ms`);
  123. });
  124. },
  125. calcFillSize(direction) {
  126. const res = uni.getSystemInfoSync();
  127. let offsetWidth = res.screenWidth;
  128. let offsetHeight = res.screenHeight;
  129. const radius = ((offsetWidth / 2) ** 2 + (offsetHeight / 2) ** 2) ** 0.5;
  130. this.fillsStyle = {
  131. width: `${radius * 4}px`,
  132. height: `${radius * 4}px`,
  133. marginLeft: direction === 'vertical' ? `-${radius * 2}px` : `-${radius}px`,
  134. marginTop: direction === 'vertical' ? `-${radius}px` : `-${radius * 2}px`
  135. };
  136. }
  137. }
  138. }
  139. </script>
  140. <style lang="scss" scoped>
  141. .paper-body {
  142. position: relative;
  143. height: 100%;
  144. margin: 0;
  145. padding: 0;
  146. background: #000;
  147. color: #fff;
  148. line-height: 1.5;
  149. font-family: -apple-system, system-ui, 'Helvetica Neue', Helvetica, Arial,
  150. 'Segoe UI', Roboto, sans-serif;
  151. -webkit-font-smoothing: antialiased;
  152. -moz-osx-font-smoothing: grayscale;
  153. .paper-wrapper {
  154. height: 100vh;
  155. .slide-inner {
  156. padding: 16px;
  157. }
  158. .slide-image {
  159. width: 128px;
  160. height: 128px;
  161. }
  162. .slide-title {
  163. font-size: 28px;
  164. font-weight: bold;
  165. margin: 24px 0;
  166. }
  167. .slide-text {
  168. font-size: 18px;
  169. }
  170. .paper-onboarding {
  171. width: 100%;
  172. height: 100%;
  173. position: relative;
  174. overflow: hidden;
  175. --swiper-theme-color: #fff;
  176. .swiper-pagination-bullet {
  177. background: #fff;
  178. }
  179. ::v-deep .swiper {
  180. width: 100%;
  181. height: 100%;
  182. z-index: 1;
  183. }
  184. .slide-inner {
  185. display: flex;
  186. flex-direction: column;
  187. align-items: center;
  188. justify-content: center;
  189. width: 100%;
  190. height: 100%;
  191. box-sizing: border-box;
  192. padding: 16px;
  193. text-align: center;
  194. }
  195. .paper-onboarding-fills {
  196. left: 50%;
  197. top: 50%;
  198. z-index: 0;
  199. }
  200. .paper-onboarding-fills,
  201. .paper-onboarding-fill {
  202. position: absolute;
  203. pointer-events: none;
  204. width: 100%;
  205. height: 100%;
  206. }
  207. .paper-onboarding-fill {
  208. left: 0;
  209. top: 0;
  210. transform-origin: center center;
  211. border-radius: 50%;
  212. }
  213. }
  214. }
  215. }
  216. </style>