index.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. <template>
  2. <view class="splash-overlay">
  3. <view class="splash-overlay-bg">
  4. <view class="bg-circle bg-circle-1"></view>
  5. <view class="bg-circle bg-circle-2"></view>
  6. <view class="bg-circle bg-circle-3"></view>
  7. </view>
  8. <view class="splash-overlay-body">
  9. <view class="splash-logo-wrap">
  10. <image class="splash-logo-img" src="/static/logo.png" mode="aspectFit" />
  11. </view>
  12. <text class="splash-brand-name">浠艾福</text>
  13. <text class="splash-brand-en">Care Family</text>
  14. <text class="splash-identity">看见全家 · 了解健康 · 主动管理</text>
  15. <view class="splash-dims-row">
  16. <view class="splash-dim-item">
  17. <view class="splash-dim-circle" style="background:rgba(255,140,66,0.3);"><text class="splash-dim-icon">🌏</text></view>
  18. <text class="splash-dim-label">身</text>
  19. </view>
  20. <view class="splash-dim-item">
  21. <view class="splash-dim-circle" style="background:rgba(255,107,157,0.3);"><text class="splash-dim-icon">🔥</text></view>
  22. <text class="splash-dim-label">心</text>
  23. </view>
  24. <view class="splash-dim-item">
  25. <view class="splash-dim-circle" style="background:rgba(99,102,241,0.3);"><text class="splash-dim-icon">⚡</text></view>
  26. <text class="splash-dim-label">智</text>
  27. </view>
  28. <view class="splash-dim-item">
  29. <view class="splash-dim-circle" style="background:rgba(16,185,129,0.3);"><text class="splash-dim-icon">🌿</text></view>
  30. <text class="splash-dim-label">行</text>
  31. </view>
  32. <view class="splash-dim-item">
  33. <view class="splash-dim-circle" style="background:rgba(245,158,11,0.3);"><text class="splash-dim-icon">💧</text></view>
  34. <text class="splash-dim-label">富</text>
  35. </view>
  36. </view>
  37. <text class="splash-tagline">家里每个人的状态,你真的看见了?</text>
  38. <view class="splash-overlay-loading">
  39. <view class="splash-overlay-dot"></view>
  40. <view class="splash-overlay-dot"></view>
  41. <view class="splash-overlay-dot"></view>
  42. </view>
  43. </view>
  44. </view>
  45. </template>
  46. <script>
  47. export default {
  48. onShow() {
  49. // 只允许跳转一次。onShow 在 devtools 重渲染、前后台切换时会重复触发,
  50. // 多个 reLaunch 并发会让框架对已销毁的 webview 调用 routeDone,
  51. // 报 "routeDone with a webviewId N is not found"。
  52. if (this._hasLaunched) return
  53. this._hasLaunched = true
  54. // 显示 2 秒后自动跳转到首页
  55. this._launchTimer = setTimeout(() => {
  56. this._launchTimer = null
  57. uni.reLaunch({ url: '/pages/index-home/index' })
  58. }, 2000)
  59. },
  60. onUnload() {
  61. // 离开启动页时清掉尚未触发的定时器,避免对已销毁的页面再发起 reLaunch
  62. if (this._launchTimer) {
  63. clearTimeout(this._launchTimer)
  64. this._launchTimer = null
  65. }
  66. }
  67. }
  68. </script>
  69. <style scoped>
  70. .splash-overlay {
  71. position: fixed;
  72. top: 0; left: 0; right: 0; bottom: 0;
  73. z-index: 9999;
  74. display: flex;
  75. align-items: center;
  76. justify-content: center;
  77. background: linear-gradient(160deg, #FFF7ED 0%, #FFEDD5 50%, #FED7AA 100%);
  78. overflow: hidden;
  79. }
  80. .splash-overlay-bg {
  81. position: absolute;
  82. top: 0; left: 0; right: 0; bottom: 0;
  83. pointer-events: none;
  84. }
  85. .bg-circle {
  86. position: absolute;
  87. border-radius: 50%;
  88. opacity: 0.12;
  89. }
  90. .bg-circle-1 {
  91. width: 400rpx;
  92. height: 400rpx;
  93. background: #FF8C42;
  94. top: -100rpx;
  95. right: -80rpx;
  96. animation: splash-float-1 4s ease-in-out infinite;
  97. }
  98. .bg-circle-2 {
  99. width: 280rpx;
  100. height: 280rpx;
  101. background: #FF6B9D;
  102. bottom: 80rpx;
  103. left: -60rpx;
  104. animation: splash-float-2 5s ease-in-out infinite;
  105. }
  106. .bg-circle-3 {
  107. width: 180rpx;
  108. height: 180rpx;
  109. background: #6366F1;
  110. top: 50%;
  111. right: -40rpx;
  112. animation: splash-float-3 6s ease-in-out infinite;
  113. }
  114. @keyframes splash-float-1 {
  115. 0%, 100% { transform: translateY(0) scale(1); }
  116. 50% { transform: translateY(-30rpx) scale(1.05); }
  117. }
  118. @keyframes splash-float-2 {
  119. 0%, 100% { transform: translateY(0) scale(1); }
  120. 50% { transform: translateY(20rpx) scale(1.08); }
  121. }
  122. @keyframes splash-float-3 {
  123. 0%, 100% { transform: translateY(0) rotate(0deg); }
  124. 50% { transform: translateY(-20rpx) rotate(10deg); }
  125. }
  126. .splash-overlay-body {
  127. display: flex;
  128. flex-direction: column;
  129. align-items: center;
  130. animation: splash-body-in 0.8s cubic-bezier(0.16,1,0.3,1) forwards;
  131. }
  132. @keyframes splash-body-in {
  133. from { opacity: 0; transform: translateY(40rpx) scale(0.96); }
  134. to { opacity: 1; transform: translateY(0) scale(1); }
  135. }
  136. .splash-logo-wrap {
  137. width: 160rpx;
  138. height: 160rpx;
  139. border-radius: 40rpx;
  140. background: rgba(255,255,255,0.95);
  141. display: flex;
  142. align-items: center;
  143. justify-content: center;
  144. margin-bottom: 16rpx;
  145. box-shadow: 0 8rpx 32rpx rgba(249,115,22,0.25);
  146. animation: splash-logo-pulse 2.5s ease-in-out infinite;
  147. }
  148. @keyframes splash-logo-pulse {
  149. 0%, 100% { box-shadow: 0 8rpx 32rpx rgba(249,115,22,0.25); }
  150. 50% { box-shadow: 0 8rpx 48rpx rgba(249,115,22,0.45); }
  151. }
  152. .splash-logo-img {
  153. width: 100rpx;
  154. height: 100rpx;
  155. }
  156. .splash-brand-name {
  157. font-size: 64rpx;
  158. font-weight: 800;
  159. color: #7C2D12;
  160. letter-spacing: 10rpx;
  161. margin-bottom: 2rpx;
  162. }
  163. .splash-brand-en {
  164. font-size: 20rpx;
  165. color: rgba(124,45,18,0.5);
  166. letter-spacing: 6rpx;
  167. margin-bottom: 30rpx;
  168. }
  169. .splash-identity {
  170. font-size: 28rpx;
  171. font-weight: 600;
  172. color: rgba(124,45,18,0.85);
  173. letter-spacing: 2rpx;
  174. margin-bottom: 12rpx;
  175. text-align: center;
  176. line-height: 1.5;
  177. }
  178. .splash-dims-row {
  179. display: flex;
  180. flex-direction: row;
  181. align-items: center;
  182. justify-content: center;
  183. gap: 28rpx;
  184. }
  185. .splash-dim-item {
  186. display: flex;
  187. flex-direction: column;
  188. align-items: center;
  189. gap: 8rpx;
  190. }
  191. .splash-dim-circle {
  192. width: 80rpx;
  193. height: 80rpx;
  194. border-radius: 50%;
  195. display: flex;
  196. align-items: center;
  197. justify-content: center;
  198. }
  199. .splash-dim-icon {
  200. font-size: 36rpx;
  201. line-height: 1;
  202. }
  203. .splash-dim-label {
  204. font-size: 22rpx;
  205. font-weight: 500;
  206. color: rgba(124,45,18,0.75);
  207. line-height: 1;
  208. }
  209. .splash-dim-item:nth-child(1) { animation: splash-dim-in 0.5s ease 0.1s both; }
  210. .splash-dim-item:nth-child(2) { animation: splash-dim-in 0.5s ease 0.2s both; }
  211. .splash-dim-item:nth-child(3) { animation: splash-dim-in 0.5s ease 0.3s both; }
  212. .splash-dim-item:nth-child(4) { animation: splash-dim-in 0.5s ease 0.4s both; }
  213. .splash-dim-item:nth-child(5) { animation: splash-dim-in 0.5s ease 0.5s both; }
  214. @keyframes splash-dim-in {
  215. from { opacity: 0; transform: translateY(16rpx) scale(0.8); }
  216. to { opacity: 1; transform: translateY(0) scale(1); }
  217. }
  218. .splash-tagline {
  219. font-size: 26rpx;
  220. color: rgba(124,45,18,0.7);
  221. letter-spacing: 4rpx;
  222. margin-top: 24rpx;
  223. }
  224. .splash-overlay-loading {
  225. position: absolute;
  226. bottom: 120rpx;
  227. left: 0;
  228. right: 0;
  229. display: flex;
  230. justify-content: center;
  231. align-items: center;
  232. gap: 12rpx;
  233. }
  234. .splash-overlay-dot {
  235. width: 14rpx;
  236. height: 14rpx;
  237. border-radius: 50%;
  238. background: rgba(249,115,22,0.6);
  239. animation: splash-dot-bounce 1.4s ease-in-out infinite both;
  240. }
  241. .splash-overlay-dot:nth-child(1) { animation-delay: -0.32s; }
  242. .splash-overlay-dot:nth-child(2) { animation-delay: -0.16s; }
  243. .splash-overlay-dot:nth-child(3) { animation-delay: 0s; }
  244. @keyframes splash-dot-bounce {
  245. 0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }
  246. 40% { transform: scale(1); opacity: 1; }
  247. }
  248. </style>