Sfoglia il codice sorgente

feat: 添加loading过渡动画

jiaxing.liao 3 settimane fa
parent
commit
21b5494a62

+ 3 - 1
electron.vite.config.ts

@@ -7,6 +7,7 @@ import Components from 'unplugin-vue-components/vite'
 import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
 import UnoCSS from 'unocss/vite'
 import vueJsx from '@vitejs/plugin-vue-jsx'
+import AppLoading from 'vite-plugin-app-loading'
 
 export default defineConfig({
   main: {
@@ -38,7 +39,8 @@ export default defineConfig({
         resolvers: [ElementPlusResolver()]
       }),
       UnoCSS(),
-      vueJsx()
+      vueJsx(),
+      AppLoading('src/renderer/loading.html')
     ]
   }
 })

+ 1 - 0
package.json

@@ -67,6 +67,7 @@
     "unplugin-auto-import": "^20.2.0",
     "unplugin-vue-components": "^30.0.0",
     "vite": "^7.1.6",
+    "vite-plugin-app-loading": "^0.4.0",
     "vite-plugin-monaco-editor": "^1.1.0",
     "vue": "^3.5.21",
     "vue-eslint-parser": "^10.2.0",

+ 8 - 0
pnpm-lock.yaml

@@ -141,6 +141,9 @@ importers:
       vite:
         specifier: ^7.1.6
         version: 7.1.9(@types/node@22.18.9)(jiti@2.6.1)(less@4.4.2)
+      vite-plugin-app-loading:
+        specifier: ^0.4.0
+        version: 0.4.0
       vite-plugin-monaco-editor:
         specifier: ^1.1.0
         version: 1.1.0(monaco-editor@0.54.0)
@@ -3479,6 +3482,9 @@ packages:
     resolution: {integrity: sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==}
     engines: {node: '>=0.6.0'}
 
+  vite-plugin-app-loading@0.4.0:
+    resolution: {integrity: sha512-ifcqZk2x4fFrUvBJ8Llcw0gZpK8y7zwAZqSOQLER7VIJXd+w8nn+X9vzAFOxzYKqNVjFCyEZVkMs5NDyN9iNdg==}
+
   vite-plugin-monaco-editor@1.1.0:
     resolution: {integrity: sha512-IvtUqZotrRoVqwT0PBBDIZPNraya3BxN/bfcNfnxZ5rkJiGcNtO5eAOWWSgT7zullIAEqQwxMU83yL9J5k7gww==}
     peerDependencies:
@@ -7610,6 +7616,8 @@ snapshots:
       extsprintf: 1.4.1
     optional: true
 
+  vite-plugin-app-loading@0.4.0: {}
+
   vite-plugin-monaco-editor@1.1.0(monaco-editor@0.54.0):
     dependencies:
       monaco-editor: 0.54.0

+ 113 - 0
src/renderer/loading.html

@@ -0,0 +1,113 @@
+<style data-app-loading="inject-css">
+  html {
+    /* same as antdv-next/dist/reset.css setting, avoid the title line-height changed */
+    line-height: 1.15;
+  }
+
+  .loading {
+    position: fixed;
+    top: 0;
+    left: 0;
+    z-index: 9999;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    width: 100%;
+    height: 100%;
+    overflow: hidden;
+    background-color: #f4f7f9;
+
+    /* transition: all 0.8s ease-out; */
+  }
+
+  .loading.hidden {
+    pointer-events: none;
+    visibility: hidden;
+    opacity: 0;
+    transition: all 0.8s ease-out;
+  }
+
+  .dark .loading {
+    background: #0d0d10;
+  }
+
+  .title {
+    margin-top: 66px;
+    font-size: 28px;
+    font-weight: 600;
+    color: rgb(0 0 0 / 85%);
+  }
+
+  .dark .title {
+    color: #fff;
+  }
+
+  .loader {
+    position: relative;
+    width: 48px;
+    height: 48px;
+  }
+
+  .loader::before {
+    position: absolute;
+    top: 60px;
+    left: 0;
+    width: 48px;
+    height: 5px;
+    content: '';
+    background: hsl(var(--primary, 210 100% 50%) / 50%);
+    border-radius: 50%;
+    animation: shadow-ani 0.5s linear infinite;
+  }
+
+  .loader::after {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    content: '';
+    background: hsl(var(--primary, 210 100% 50%));
+    border-radius: 4px;
+    animation: jump-ani 0.5s linear infinite;
+  }
+
+  @keyframes jump-ani {
+    15% {
+      border-bottom-right-radius: 3px;
+    }
+
+    25% {
+      transform: translateY(9px) rotate(22.5deg);
+    }
+
+    50% {
+      border-bottom-right-radius: 40px;
+      transform: translateY(18px) scale(1, 0.9) rotate(45deg);
+    }
+
+    75% {
+      transform: translateY(9px) rotate(67.5deg);
+    }
+
+    100% {
+      transform: translateY(0) rotate(90deg);
+    }
+  }
+
+  @keyframes shadow-ani {
+    0%,
+    100% {
+      transform: scale(1, 1);
+    }
+
+    50% {
+      transform: scale(1.2, 1);
+    }
+  }
+</style>
+<div class="loading" id="__app-loading__">
+  <div class="loader"></div>
+  <div class="title">Loading...</div>
+</div>

+ 4 - 0
src/renderer/src/main.ts

@@ -5,12 +5,16 @@ import 'element-plus/dist/index.css'
 import 'element-plus/theme-chalk/dark/css-vars.css'
 import './theme/vars.css'
 import './style.less'
+import { loadingFadeOut } from 'virtual:app-loading'
 
 import 'normalize.css'
 import router from './router'
 import { setupStore } from './store'
 import i18n from './locales'
 
+// 关闭加载动画
+loadingFadeOut()
+
 const app = createApp(App)
 setupStore(app)
 app.use(router)

+ 1 - 1
src/renderer/src/views/designer/sidebar/Resource.vue

@@ -58,7 +58,7 @@
         </el-scrollbar>
       </div>
     </SplitterCollapseItem>
-    <SplitterCollapseItem title="其他数据">
+    <SplitterCollapseItem title="其他资源">
       <template #header-right>
         <el-tooltip content="添加">
           <el-button type="text" class="mr-12px" @click.capture.stop="handleAddOther"

+ 1 - 1
tsconfig.web.json

@@ -7,7 +7,7 @@
     "src/preload/*.d.ts"
   ],
   "compilerOptions": {
-    "types": ["element-plus/global"],
+    "types": ["element-plus/global", "vite-plugin-app-loading/client"],
     "composite": true,
     "jsxImportSource": "vue",
     "jsx": "preserve",