diff --git a/bun.lock b/bun.lock index 5ad74a9..753e96f 100644 --- a/bun.lock +++ b/bun.lock @@ -12,6 +12,7 @@ "daisyui": "^5.0.50", "echarts": "^6.0.0", "element-plus": "^2.13.2", + "gsap": "^3.14.2", "lenis": "^1.3.17", "lucide-vue-next": "^0.563.0", "motion-v": "^1.6.1", @@ -20,6 +21,7 @@ "radash": "^12.1.1", "reka-ui": "^2.8.0", "tailwind-merge": "^3.4.0", + "three": "^0.183.1", "vue": "^3.5.17", "vue-echarts": "^8.0.1", "vue-i18n": "11", @@ -719,6 +721,8 @@ "graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="], + "gsap": ["gsap@3.14.2", "", {}, "sha512-P8/mMxVLU7o4+55+1TCnQrPmgjPKnwkzkXOK1asnR9Jg2lna4tEY5qBJjMmAaOBDDZWtlRjBXjLa0w53G/uBLA=="], + "has-bigints": ["has-bigints@1.1.0", "", {}, "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg=="], "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], @@ -1123,6 +1127,8 @@ "tar": ["tar@7.4.3", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="], + "three": ["three@0.183.1", "", {}, "sha512-Psv6bbd3d/M/01MT2zZ+VmD0Vj2dbWTNhfe4CuSg7w5TuW96M3NOyCVuh9SZQ05CpGmD7NEcJhZw4GVjhCYxfQ=="], + "tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="], "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], diff --git a/components.d.ts b/components.d.ts index 718bd3b..900e793 100644 --- a/components.d.ts +++ b/components.d.ts @@ -15,6 +15,7 @@ declare module 'vue' { AnimatePresence: typeof import('motion-v')['AnimatePresence'] AnimText: typeof import('./src/components/special/AnimText.vue')['default'] AuthDialog: typeof import('./src/components/dialog/AuthDialog.vue')['default'] + BasicIntroCard: typeof import('./src/components/card/BasicIntroCard.vue')['default'] BiliBiliIcon: typeof import('./src/components/icon/BiliBiliIcon.vue')['default'] Button: typeof import('./src/components/ui/button/Button.vue')['default'] Calendar: typeof import('./src/components/ui/calendar/Calendar.vue')['default'] @@ -43,6 +44,8 @@ declare module 'vue' { FooterBarV2Placeholder: typeof import('./src/components/layout/FooterBarV2Placeholder.vue')['default'] FooterBarV2Space: typeof import('./src/components/layout/FooterBarV2Space.vue')['default'] LogoIcon: typeof import('./src/components/icon/LogoIcon.vue')['default'] + LogoModel: typeof import('./src/components/three/LogoModel.vue')['default'] + ModelViewer: typeof import('./src/components/three/ModelViewer.vue')['default'] NativeSelect: typeof import('./src/components/ui/native-select/NativeSelect.vue')['default'] NativeSelectOptGroup: typeof import('./src/components/ui/native-select/NativeSelectOptGroup.vue')['default'] NativeSelectOption: typeof import('./src/components/ui/native-select/NativeSelectOption.vue')['default'] @@ -63,6 +66,7 @@ declare global { const AnimatePresence: typeof import('motion-v')['AnimatePresence'] const AnimText: typeof import('./src/components/special/AnimText.vue')['default'] const AuthDialog: typeof import('./src/components/dialog/AuthDialog.vue')['default'] + const BasicIntroCard: typeof import('./src/components/card/BasicIntroCard.vue')['default'] const BiliBiliIcon: typeof import('./src/components/icon/BiliBiliIcon.vue')['default'] const Button: typeof import('./src/components/ui/button/Button.vue')['default'] const Calendar: typeof import('./src/components/ui/calendar/Calendar.vue')['default'] @@ -91,6 +95,8 @@ declare global { const FooterBarV2Placeholder: typeof import('./src/components/layout/FooterBarV2Placeholder.vue')['default'] const FooterBarV2Space: typeof import('./src/components/layout/FooterBarV2Space.vue')['default'] const LogoIcon: typeof import('./src/components/icon/LogoIcon.vue')['default'] + const LogoModel: typeof import('./src/components/three/LogoModel.vue')['default'] + const ModelViewer: typeof import('./src/components/three/ModelViewer.vue')['default'] const NativeSelect: typeof import('./src/components/ui/native-select/NativeSelect.vue')['default'] const NativeSelectOptGroup: typeof import('./src/components/ui/native-select/NativeSelectOptGroup.vue')['default'] const NativeSelectOption: typeof import('./src/components/ui/native-select/NativeSelectOption.vue')['default'] diff --git a/docs/cli-feature/motion.md b/docs/cli-feature/motion.md index 53d13a5..aaacfee 100644 --- a/docs/cli-feature/motion.md +++ b/docs/cli-feature/motion.md @@ -31,3 +31,7 @@ Hucky 安装了 [motion-v](https://motion.net.cn/docs/vue) 库,您可以在组 :::tip 提示 exit 会自动为元素的进入也添加动画效果。 ::: + +## 3D 动画 + +Hucky 选用 [GSAP](https://gsap.com/docs/v3/) 作为 3D 动画库,您可以学习相关知识 diff --git a/docs/cli-feature/three.md b/docs/cli-feature/three.md new file mode 100644 index 0000000..17be57a --- /dev/null +++ b/docs/cli-feature/three.md @@ -0,0 +1,19 @@ +# 3D + +## Three.js + +Hucky 选用 [three.js](https://threejs.org/manual/#zh) 作为 3D 框架,您可以学习相关知识 + +## 首页 + +Hucky 的首页层叠关系非常复杂,在这里做解释 + +- z-10 导航栏 fixed 位于所有元素的最上方 +- z-8 悬浮文字 仅次于导航栏,要求用户最先看到 +- z-7 Three.js Canvas 位于悬浮文字下方,要求用户在看到悬浮文字后立即看到 3D 模型,同时将 canvas 背景透明,让用户可以看到 canvas 下方的主内容 +- z-5 主内容区域 位于 Three.js Canvas 下方,主要提供了背景颜色 +- z-1 页脚 位于所有元素的最下方且 fixed,完成了类似幕布拉开的效果 + +## 3D 动画 + +Hucky 选用 [GSAP](https://gsap.com/docs/v3/) 作为 3D 动画库,您可以学习相关知识 diff --git a/package.json b/package.json index 7d85fe8..5cd598c 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "daisyui": "^5.0.50", "echarts": "^6.0.0", "element-plus": "^2.13.2", + "gsap": "^3.14.2", "lenis": "^1.3.17", "lucide-vue-next": "^0.563.0", "motion-v": "^1.6.1", @@ -31,6 +32,7 @@ "radash": "^12.1.1", "reka-ui": "^2.8.0", "tailwind-merge": "^3.4.0", + "three": "^0.183.1", "vue": "^3.5.17", "vue-echarts": "^8.0.1", "vue-i18n": "11", diff --git a/public/model/christmas_ball.glb b/public/model/christmas_ball.glb new file mode 100644 index 0000000..007c675 Binary files /dev/null and b/public/model/christmas_ball.glb differ diff --git a/src/components/card/BasicIntroCard.vue b/src/components/card/BasicIntroCard.vue new file mode 100644 index 0000000..f26145b --- /dev/null +++ b/src/components/card/BasicIntroCard.vue @@ -0,0 +1,29 @@ + + + + + diff --git a/src/components/layout/FooterBarV2.vue b/src/components/layout/FooterBarV2.vue index e90869e..1ddbe06 100644 --- a/src/components/layout/FooterBarV2.vue +++ b/src/components/layout/FooterBarV2.vue @@ -7,7 +7,7 @@ import RedBookIcon from "../icon/RedBookIcon.vue";