Skip to content

Commit

Permalink
feat: 新增主题切换功能
Browse files Browse the repository at this point in the history
  • Loading branch information
Haoyue-zhi committed May 16, 2024
1 parent 6d85faf commit 753dd42
Show file tree
Hide file tree
Showing 12 changed files with 187 additions and 14 deletions.
Binary file modified bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion components/app/experience.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { experiencesDataZn } from "~/assets/data";
const experienceRef = ref();
useSectionInView(experienceRef, "我的经历");
useSectionInView(experienceRef, "我的经历", 0.1);
</script>

<template>
Expand Down
10 changes: 8 additions & 2 deletions components/app/intro.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<script setup lang="ts">
// @ts-ignore
import { useSound } from "@vueuse/sound";
import { name, typedDes } from "~/assets/data";
import Typed from "typed.js";
import bubble from "public/sounds/bubble.wav";
const introRef = ref();
useSectionInView(introRef, "首页");
useSectionInView(introRef, "首页", 0.2);
const initTyped = () => {
new Typed("#introduce", {
Expand All @@ -17,6 +20,8 @@ const initTyped = () => {
onMounted(() => {
initTyped();
});
const { play, stop } = useSound(bubble);
</script>

<template>
Expand All @@ -38,9 +43,10 @@ onMounted(() => {
/>
</div>
<span
class="absolute text-4xl bottom-0 right-0 hover:rotate-2"
class="absolute text-4xl bottom-0 right-0 hover:rotate-2 cursor-pointer"
data-aos="zoom-in"
data-aos-delay="200"
@mouseover="play"
>
👋
</span>
Expand Down
8 changes: 2 additions & 6 deletions components/app/project.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@
import { projectsData } from "~/assets/data";
const projectsRef = ref();
useSectionInView(projectsRef, "我的项目");
useSectionInView(projectsRef, "我的项目", 0.4);
</script>

<template>
<div
ref="projectsRef"
class="scroll-mt-28 mb-28"
id="projects"
>
<div ref="projectsRef" class="scroll-mt-28 mb-28" id="projects">
<h2 class="text-3xl font-medium capitalize mb-8 text-center">我的项目</h2>
<AppProjectItem
v-for="(project, index) in projectsData"
Expand Down
51 changes: 48 additions & 3 deletions components/app/projectItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ const { title, description, tags, imageUrl, projectUrl, demoUrl, detailRoute } =

<template>
<div
class="group mb-3 sm:mb-8 last:mb-0"
class="group mb-4 sm:mb-8 last:mb-0"
data-aos="new-animation"
data-aos-mirror="true"
>
<section
class="bg-gray-100 max-w-[45rem] border border-black/5 rounded-lg overflow-hidden sm:pr-8 relative sm:h-[28rem] transition sm:group-even:pl-8 dark:text-white dark:bg-white/10"
class="bg-gray-100 max-w-[45rem] hidden sm:block border border-black/5 rounded-lg overflow-hidden sm:pr-8 relative h-96 transition sm:group-even:pl-8 dark:text-white dark:bg-white/10"
>
<div
class="group pt-4 pb-7 px-5 sm:pl-10 sm:pr-2 sm:pt-10 sm:max-w-[50%] flex flex-col items-start gap-3 h-full sm:group-even:ml-[18rem]"
Expand Down Expand Up @@ -76,9 +76,54 @@ const { title, description, tags, imageUrl, projectUrl, demoUrl, detailRoute } =
:src="imageUrl"
alt="Project I worked on"
quality="95"
class="absolute hidden sm:block top-8 -right-40 w-[28.25rem] rounded-t-lg shadow-2xl transition group-hover:scale-[1.04] group-hover:-translate-x-3 group-hover:translate-y-3 group-hover:-rotate-2 group-even:group-hover:translate-x-3 group-even:group-hover:translate-y-3 group-even:group-hover:rotate-2 group-even:right-[initial] group-even:-left-40"
class="absolute top-8 -right-40 w-[28.25rem] rounded-t-lg shadow-2xl transition group-hover:scale-[1.04] group-hover:-translate-x-3 group-hover:translate-y-3 group-hover:-rotate-2 group-even:group-hover:translate-x-3 group-even:group-hover:translate-y-3 group-even:group-hover:rotate-2 group-even:right-[initial] group-even:-left-40"
/>
</section>

<div class="card w-96 shadow-xl sm:hidden dark:text-white dark:bg-white/10">
<figure class="bg-base-100">
<NuxtImg
:src="imageUrl"
alt="Project I worked on"
quality="95"
class="h-[200px] object-cover"
/>
</figure>
<div class="card-body">
<h2 class="card-title">{{ title }}</h2>
<ul class="flex flex-wrap mt-auto gap-2">
<li
v-for="(tag, index) in tags"
class="badge badge-ghost"
:key="index"
>
{{ tag }}
</li>
</ul>
<p>{{ description }}</p>
<div class="card-actions justify-end">
<NuxtLink
v-if="projectUrl"
:to="projectUrl"
target="_blank"
class="flex items-center gap-1 hover:underline underline-offset-2"
>
<span class="break-keep">Code</span>

<Icon name="mdi:github-box" size="17" />
</NuxtLink>
<NuxtLink
v-if="demoUrl"
:to="demoUrl"
target="_blank"
class="flex items-center gap-1 hover:underline underline-offset-2"
>
<span class="break-keep min-w-[4.5rem]">Live demo</span>
<Icon name="mdi:launch" size="17" />
</NuxtLink>
</div>
</div>
</div>
</div>
</template>

Expand Down
7 changes: 7 additions & 0 deletions components/app/widgetWrapper.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<template>
<div
class="fixed bottom-5 right-3 sm:bottom-[3rem] sm:right-[3rem] flex flex-col items-center justify-between p-1 bg-opacity-80 backdrop-blur-[0.5rem] border border-white border-opacity-70 shadow-2xl rounded-lg transition-all dark:bg-gray-950 dark:bg-transparent dark:border-slate-700"
>
<slot />
</div>
</template>
104 changes: 104 additions & 0 deletions components/widget/themeSwitch.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<script setup lang="ts">
const isDark = useDark({
attribute: "data-theme",
});
const toggleDark = useToggle(isDark);
const darkMode = ref(isDark.value);
const switchTheme = (event: MouseEvent) => {
const isAppearanceTransition =
document.startViewTransition &&
!window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (!isAppearanceTransition || !event) {
return;
}
const x = event.clientX;
const y = event.clientY;
const endRadius = Math.hypot(
Math.max(x, innerWidth - x),
Math.max(y, innerHeight - y)
);
// @ts-expect-error: Transition API
const transition = document.startViewTransition(() => {
toggleDark();
console.log(darkMode.value, isDark.value);
});
transition.ready.then(() => {
const clipPath = [
`circle(0px at ${x}px ${y}px)`,
`circle(${endRadius}px at ${x}px ${y}px)`,
];
document.documentElement.animate(
{
clipPath: isDark.value ? [...clipPath].reverse() : clipPath,
},
{
duration: 400,
easing: "ease-in",
pseudoElement: isDark.value
? "::view-transition-old(root)"
: "::view-transition-new(root)",
}
);
});
};
</script>

<template>
<label class="swap swap-rotate w-[1.5rem] h-[1.5rem]">
<!-- this hidden checkbox controls the state -->
<input
type="checkbox"
class="theme-controller"
v-model="darkMode"
@click.stop="switchTheme"
/>

<!-- sun icon -->
<svg
class="swap-off fill-current w-full h-full"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path
d="M5.64,17l-.71.71a1,1,0,0,0,0,1.41,1,1,0,0,0,1.41,0l.71-.71A1,1,0,0,0,5.64,17ZM5,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H4A1,1,0,0,0,5,12Zm7-7a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4A1,1,0,0,0,12,5ZM5.64,7.05a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29,1,1,0,0,0,0-1.41l-.71-.71A1,1,0,0,0,4.93,6.34Zm12,.29a1,1,0,0,0,.7-.29l.71-.71a1,1,0,1,0-1.41-1.41L17,5.64a1,1,0,0,0,0,1.41A1,1,0,0,0,17.66,7.34ZM21,11H20a1,1,0,0,0,0,2h1a1,1,0,0,0,0-2Zm-9,8a1,1,0,0,0-1,1v1a1,1,0,0,0,2,0V20A1,1,0,0,0,12,19ZM18.36,17A1,1,0,0,0,17,18.36l.71.71a1,1,0,0,0,1.41,0,1,1,0,0,0,0-1.41ZM12,6.5A5.5,5.5,0,1,0,17.5,12,5.51,5.51,0,0,0,12,6.5Zm0,9A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z"
/>
</svg>

<!-- moon icon -->
<svg
class="swap-on fill-current w-full h-full"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path
d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z"
/>
</svg>
</label>
</template>

<style>
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
mix-blend-mode: normal;
}
::view-transition-old(root) {
z-index: 1;
}
::view-transition-new(root) {
z-index: 2147483646;
}
[data-theme="dark"]::view-transition-old(root) {
z-index: 2147483646;
}
[data-theme="dark"]::view-transition-new(root) {
z-index: 1;
}
</style>
8 changes: 6 additions & 2 deletions composables/useSectionInView.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import type { Ref } from "vue";

export const useSectionInView = (el: Ref<HTMLElement>, name: string) => {
export const useSectionInView = (
el: Ref<HTMLElement>,
name: string,
threshold: number = 0.75
) => {
const target = el;
const targetIsVisible = ref(false);

Expand All @@ -16,7 +20,7 @@ export const useSectionInView = (el: Ref<HTMLElement>, name: string) => {
}
},
{
threshold: 0.5,
threshold,
}
);

Expand Down
3 changes: 3 additions & 0 deletions layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@
<AppHeader />
<slot />
<AppFooter />
<AppWidgetWrapper>
<WidgetThemeSwitch />
</AppWidgetWrapper>
</div>
</template>
6 changes: 6 additions & 0 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export default defineNuxtConfig({
"nuxt-icon",
"nuxt-aos",
"@vueuse/motion/nuxt",
"@vueuse/sound/nuxt",
],
app: {
baseURL: "/zhi-blog",
Expand All @@ -18,4 +19,9 @@ export default defineNuxtConfig({
devServer: {
port: 3333,
},
vite: {
optimizeDeps: {
include: ["howler"],
},
},
});
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"dependencies": {
"@vueuse/motion": "^2.1.0",
"@vueuse/sound": "^2.0.1",
"nuxt": "^3.11.2",
"typed.js": "^2.1.0",
"vue": "^3.4.27",
Expand Down
1 change: 1 addition & 0 deletions tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Config } from "tailwindcss";
import daisyui from "daisyui";

export default {
darkMode: ["selector", "[data-theme='dark']"],
content: [],
theme: {
extend: {},
Expand Down

0 comments on commit 753dd42

Please sign in to comment.