Przeglądaj źródła

feat: 页面切换优化
1. 页面切换时的动画展示功能制作

kindring 10 miesięcy temu
rodzic
commit
aacd2489ed

+ 48 - 16
src/App.vue

@@ -5,58 +5,90 @@ import {onMounted, ref} from "vue";
 import MacWindow from "./components/window/macWindow.vue";
 import MagnetView from "./components/magnetView.vue";
 import AppleBar from "@/components/appleBar/appleBar.vue";
+import SettingView from "@/components/settingView.vue";
 import {NavItem} from "@/components/appleBar/appleBar.ts";
 
 onMounted(() => {
 
 });
 
+let transitionName = ref("slide-right");
+const settingPageKey = 'setting';
+const activeIndex = ref(0);
+const homePageKey = 'home';
 let navItems:NavItem[] = [
+
   {
     id: 1,
     name: '首页',
-    actionCode: 'toHome',
-    description: '返回首页',
-    icon: 'system',
-  },
-  {
-    id: 1,
-    name: '首页',
-    actionCode: 'toHome',
+    actionCode: homePageKey,
     description: '返回首页',
     icon: 'home',
   },
   {
-    id: 1,
-    name: '首页',
-    actionCode: 'toHome',
-    description: '返回首页',
+    id: 2,
+    name: '设置',
+    actionCode: settingPageKey,
+    description: '软件设置',
     icon: 'setting',
   },
 ]
 
-const title = ref("fc-ele");
 
+const title = ref("fc-ele");
+const pageKey = ref(homePageKey);
 const navAction = (actionCode:string) => {
   console.log(`action: ${actionCode}`);
+  // 寻找actionCode对应的 index
+  let index = navItems.findIndex((item) => item.actionCode === actionCode);
+  if (index === -1) {
+    return console.warn(`找不到actionCode: ${actionCode}`);
+  }
+  // 更改动画
+  if (index < activeIndex.value) {
+    transitionName.value = 'slide-left';
+  }else{
+    transitionName.value = 'slide-right';
+  }
+  activeIndex.value = index;
+  pageKey.value = navItems[index].actionCode;
+  switch (actionCode) {
+    case settingPageKey:
+      title.value = navItems[index].name;
+      break;
+    default:
+      pageKey.value = homePageKey;
+      title.value = 'fc-ele';
+      break;
+  }
+  console.log(`pageKey: ${pageKey.value}`);
 }
+
 </script>
 
 <template>
   <mac-window :title="title" :icon="'home'">
+
     <div class="image-bg">
       <img src="./assets/images/bg.jpg" alt="">
     </div>
+    <Transition :name="transitionName">
+      <div class="full" v-if="pageKey === homePageKey">
+        <div class="app-content">
+          <magnet-view/>
+        </div>
+      </div>
+      <setting-view v-else-if="pageKey === settingPageKey"></setting-view>
+    </Transition>
+
     <div class="app-bar">
       <apple-bar
           :nav-items="navItems"
+          :active="pageKey"
           :hide-time="3000"
           @action="navAction"
       ></apple-bar>
     </div>
-    <div class="app-content">
-      <magnet-view/>
-    </div>
 
   </mac-window>
 </template>

+ 7 - 3
src/assets/base.css

@@ -71,9 +71,9 @@
     position: absolute;
     display: block;
     width: 90px;
+    height: 20px;
     top: 20px;
     right: -100%;
-    height: 20px;
     padding: 0 5px;
     box-shadow: 1px 0 4px #000;
     line-height: 20px;
@@ -84,7 +84,7 @@
     border-radius: 5px;
     opacity: 0;
     transition: all 0.3s;
-    z-index: 10;
+    z-index: 1000;
 }
 .showTopTip:hover .showTip{
     top: 30px;
@@ -94,7 +94,6 @@
     top: -25px;
     right: -50%;
     opacity: 1;
-    z-index: 10;
 }
 
 .noScroll::-webkit-scrollbar {
@@ -164,3 +163,8 @@
     object-fit: cover;
     object-position: center;
 }
+
+.full{
+    width: 100%;
+    height: 100%;
+}

+ 12 - 7
src/components/appleBar/appleBar.vue

@@ -10,12 +10,12 @@ let isHidden = ref(true);
 
 
 let props = defineProps({
-//   是否全屏
+  //   是否全屏
   isFullScreen: {
     type: Boolean,
     default: false
   },
-//   导航项
+  //   导航项
   navItems:  {
     type: Array as PropType<NavItem[]>,
     default: ():NavItem[] => []
@@ -23,6 +23,10 @@ let props = defineProps({
   hideTime: {
     type: Number,
     default: 3000
+  },
+  active: {
+    type: String,
+    default: ''
   }
 });
 
@@ -71,7 +75,8 @@ function actionHandle(actionCode: string): void{
     <div class="appleBar" @mouseenter="barActiveHandle" @mouseleave="startHideTimer">
       <div class="bgMask"></div>
       <div class="appleItemGroup">
-        <div class="appleItem showCenterTip"
+        <div
+            :class="`appleItem showCenterTip ${active==item.actionCode?'active':''}`"
              v-for="item in props.navItems"
              :key="item.id"
               @click="actionHandle(item.actionCode)"
@@ -123,7 +128,6 @@ function actionHandle(actionCode: string): void{
   border-radius: 10px;
   opacity: 0.6;
   background-color: var(--color-background-soft);
-  z-index: 1;
 }
 .appleItemGroup{
   width: 100%;
@@ -131,7 +135,6 @@ function actionHandle(actionCode: string): void{
   display: flex;
   justify-content: center;
   align-items: center;
-  z-index: 2;
   position: relative;
 }
 .appleItem{
@@ -141,13 +144,15 @@ function actionHandle(actionCode: string): void{
   justify-content: center;
   align-items: center;
   margin: 0 10px;
-
   font-size: 20px;
   font-weight: bold;
   color: var(--color-text);
   cursor: pointer;
   opacity: 0.8;
 }
+.appleItemGroup .active{
+  color: var(--color-text-show);
+}
 .appleItem-content{
   width: 45px;
   height: 45px;
@@ -166,7 +171,6 @@ function actionHandle(actionCode: string): void{
   display: flex;
   flex-shrink: 0;
   position: relative;
-  z-index: 2;
 }
 
 .appleItem .icon{
@@ -192,6 +196,7 @@ function actionHandle(actionCode: string): void{
   opacity: 0.4;
   margin-bottom: 5px;
   cursor: pointer;
+  background-color: var(--color-background);
 }
 
 .hidden .appleBar .appleItem{

+ 1 - 2
src/components/magnetView.vue

@@ -14,7 +14,7 @@ interface vueMagnet extends Magnet{
 const magnetItemInfos: vueMagnet[] = [
   {
     id: `1`,
-    type: 'TimeMagnet',
+    type: timeMagnetInfo.type,
     x: 0,
     y: 0,
     width: timeMagnetInfo.sizes.medium?.width??0,
@@ -76,7 +76,6 @@ function eventHandler(magnetEmit: MagnetEmit<any>){
         @magnet="eventHandler"
     ></component>
   </div>
-
 </div>
 </template>
 

+ 18 - 0
src/components/settingView.vue

@@ -0,0 +1,18 @@
+<script setup lang="ts">
+
+</script>
+
+<template>
+  <div class="settingView">
+
+  </div>
+</template>
+
+<style scoped>
+.settingView {
+  background-color: var(--color-background-mute);
+  width: 100%;
+  height: 100%;
+  position: relative;
+}
+</style>

+ 40 - 2
src/style.css

@@ -15,7 +15,7 @@
   text-rendering: optimizeLegibility;
   --vt-c-white: #ffffff;
   --vt-c-white-soft: #f8f8f8;
-  --vt-c-white-mute: #f2f2f2;
+  --vt-c-white-mute: #d3d3d3;
 
   --vt-c-black: #181818;
   --vt-c-black-soft: #222222;
@@ -31,7 +31,6 @@
   --vt-c-text-light-1: var(--vt-c-indigo);
   --vt-c-text-light-2: rgba(60, 60, 60, 0.66);
   --vt-c-text-light-3: #56a7fb;
-  --vt-c-text-light-title: #000000;
   --vt-c-text-dark-1: var(--vt-c-white);
   --vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
   --vt-c-text-dark-3: #56a7fb;
@@ -52,6 +51,8 @@
   --color-text-title: var(--vt-c-text-light-title);
   --color-text-show: var(--vt-c-text-light-3);
   --color-text-money: var(--vt-c-text-red);
+  --color-shadow: var(--vt-c-divider-light-2);
+  --color-shadow-hover: var(--vt-c-divider-light-1);
   --section-gap: 160px;
 }
 
@@ -64,6 +65,9 @@
     --color-border: var(--vt-c-divider-dark-2);
     --color-border-hover: var(--vt-c-divider-dark-1);
 
+    --color-shadow: var(--vt-c-white-mute);
+    --color-shadow-hover: var(--vt-c-white-soft);
+
     --color-heading: var(--vt-c-text-dark-1);
     /*--color-text-title: var(--vt-c-text-dark-title);*/
     --color-text: var(--vt-c-text-dark-2);
@@ -143,3 +147,37 @@ button:focus-visible {
     background-color: #f9f9f9;
   }
 }
+
+
+.slide-left-enter-active,
+.slide-left-leave-active,
+.slide-right-enter-active,
+.slide-right-leave-active {
+  transition: transform 0.3s;
+}
+
+.slide-right-enter-from {
+  transform: translateX(0);
+}
+.slide-right-enter-to {
+  transform: translateX(-100%);
+}
+.slide-right-leave-from {
+  transform: translateX(0);
+}
+.slide-right-leave-to {
+  transform: translateX(-100%);
+}
+
+.slide-left-enter-from {
+  transform: translateX(-200%);
+}
+.slide-left-enter-to {
+  transform: translateX(-100%);
+}
+.slide-left-leave-from {
+  transform: translateX(0);
+}
+.slide-left-leave-to {
+  transform: translateX(100%);
+}