扬掉旧的掉帧动画系统 严肃使用新动画系统

This commit is contained in:
li-chx
2025-11-05 23:23:07 +08:00
parent 6c963257cf
commit 9043cf53fd
18 changed files with 138 additions and 135 deletions
+2 -2
View File
@@ -52,7 +52,7 @@ onMounted(() => {
</script>
<template>
<div class="p-5 light:bg-old-neutral-200 dark:bg-old-neutral-800 min-h-64 transition-all duration-500">
<div class="p-5 light:bg-old-neutral-200 dark:bg-old-neutral-800 min-h-64">
<div class="text-4xl">
{{ metaData?.title }}
</div>
@@ -105,7 +105,7 @@ onMounted(() => {
:tech-stack-icon-names="metaData?.tech_stack_icon_names"
:tech-stack-theme-colors="metaData?.tech_stack_theme_colors"
:tech-stack-percent="metaData?.tech_stack_percent"
class="lg:w-64 w-0 transition-all duration-500"
class="lg:w-64 w-0 transition-[width] duration-500"
/>
</div>
<div v-else class="min-w-64"/>
+8 -43
View File
@@ -2,7 +2,6 @@
import { DataAnomaly, defaultMetaData } from '~/types/PostMetaData';
import type { PostMetaData } from '~/types/PostMetaData';
import useColorModeStore from '~/stores/colorModeStore';
const props = withDefaults(defineProps<{
metaData?: PostMetaData;
@@ -54,55 +53,25 @@ const safeEditorId = computed(() => {
return `rambling_${encoded}`;
});
const showLightShadow = ref(false);
const showDarkShadow = ref(false);
const showShadow = ref(true);
function reverseCollapsed() {
if (collapsed.value) {
collapsed.value = false;
return;
}
const showLight = showLightShadow.value;
const showDark = showDarkShadow.value;
showLightShadow.value = false;
showDarkShadow.value = false;
collapsed.value = true;
showShadow.value = false;
setTimeout(() => {
showLightShadow.value = showLight;
showDarkShadow.value = showDark;
showShadow.value = true;
}, 500);
}
const colorModeStore = useColorModeStore();
let colorModeCallBackKey = '';
onMounted(() => {
if (colorModeStore.colorMode === 'light') {
showLightShadow.value = true;
} else {
showDarkShadow.value = true;
}
colorModeCallBackKey = colorModeStore.registerCallBack(() => {
if (colorModeStore.colorMode === 'light') {
setTimeout(() => {
showLightShadow.value = true;
}, 500);
showDarkShadow.value = false;
} else {
showLightShadow.value = false;
setTimeout(() => {
showDarkShadow.value = true;
}, 500);
}
});
});
onUnmounted(() => {
colorModeStore.unregisterCallBack(colorModeCallBackKey);
});
</script>
<template>
<div
class="p-5 light:bg-old-neutral-200 dark:bg-old-neutral-800 min-h-64 transition-all duration-500"
class="p-5 light:bg-old-neutral-200 dark:bg-old-neutral-800 min-h-64"
@click="reverseCollapsed">
<div class="text-4xl">
{{ (typeChinese.get(metaData?.type) || 'unknown Type') + '' }}{{ props.metaData.title }}
@@ -146,18 +115,14 @@ onUnmounted(() => {
</div>
<div
class="relative flex mt-2 justify-between overflow-hidden transition-all duration-300 ease-in-out min-h-[8.5rem]"
class="relative flex mt-2 justify-between overflow-hidden duration-300 ease-in-out min-h-[8.5rem]"
:class="{'max-h-[8.5rem]' : collapsed, 'max-h-[100vh]':!collapsed}">
<ReadonlyMdEditor
v-if="rawbody" :editor-id="safeEditorId" :markdown="rawbody!"
class="transition-all duration-500 w-full"/>
class="w-full"/>
<div
class="absolute bottom-0 left-0 right-0 h-14 bg-gradient-to-t from-old-neutral-200 to-transparent pointer-events-none transition-opacity duration-300"
:class="collapsed&&showLightShadow?'opacity-100':'opacity-0'"
/>
<div
class="absolute bottom-0 left-0 right-0 h-14 bg-gradient-to-t from-old-neutral-800 to-transparent pointer-events-none transition-opacity duration-300"
:class="collapsed&&showDarkShadow?'opacity-100':'opacity-0'"
class="absolute bottom-0 left-0 right-0 h-14 bg-gradient-to-t from-old-neutral-200 dark:from-old-neutral-800 to-transparent pointer-events-none transition-opacity duration-300"
:class="collapsed && showShadow?'opacity-100':'opacity-0'"
/>
</div>
<hr/>
+78
View File
@@ -0,0 +1,78 @@
<script setup lang="ts">
import useColorModeStore from '~/stores/colorModeStore';
const colorModeStore = useColorModeStore();
function revealToggle(e?: MouseEvent) {
if (typeof document === 'undefined' || !e || !('startViewTransition' in document)) {
// SSR 或无事件时直接切换或不支持时直接切换
colorModeStore.toggleColorMode();
return;
}
const transition = document.startViewTransition(() => {
colorModeStore.toggleColorMode();
});
transition.ready.then(() => {
// 获取鼠标的坐标
const { clientX, clientY } = e!;
// 计算最大半径
const radius = Math.hypot(
Math.max(clientX, innerWidth - clientX),
Math.max(clientY, innerHeight - clientY),
);
// 圆形动画扩散开始
document.documentElement.animate(
{
clipPath: [
`circle(0% at ${clientX}px ${clientY}px)`,
`circle(${radius}px at ${clientX}px ${clientY}px)`,
],
},
// 设置时间,已经目标伪元素
{
duration: 500,
pseudoElement: '::view-transition-new(root)',
},
);
});
}
</script>
<template>
<Transition
mode="out-in"
enter-active-class="transition-opacity duration-300 ease-in-out"
enter-from-class="opacity-0"
enter-to-class="opacity-100"
leave-active-class="transition-opacity duration-300 ease-in-out"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<Icon
v-if="colorModeStore.colorMode === 'dark'"
key="dark"
name="material-symbols:dark-mode"
class="text-2xl cursor-pointer mr-5"
@click="revealToggle($event)"
/>
<Icon
v-else
key="light"
name="material-symbols:clear-day-rounded"
class="text-2xl cursor-pointer mr-5"
@click="revealToggle($event)"
/>
</Transition>
</template>
<style>
::view-transition-new(root),
::view-transition-old(root) {
animation: none;
}
</style>