feat: use Swug for transition animations instead of ViewTransitions
This commit is contained in:
parent
e64bd923da
commit
a80d69d843
|
@ -9,6 +9,7 @@ import rehypeSlug from "rehype-slug"
|
||||||
import remarkMath from "remark-math"
|
import remarkMath from "remark-math"
|
||||||
import { remarkReadingTime } from "./src/plugins/remark-reading-time.mjs"
|
import { remarkReadingTime } from "./src/plugins/remark-reading-time.mjs"
|
||||||
import svelte from "@astrojs/svelte"
|
import svelte from "@astrojs/svelte"
|
||||||
|
import swup from '@swup/astro';
|
||||||
|
|
||||||
const oklchToHex = (str) => {
|
const oklchToHex = (str) => {
|
||||||
const DEFAULT_HUE = 250
|
const DEFAULT_HUE = 250
|
||||||
|
@ -26,6 +27,16 @@ export default defineConfig({
|
||||||
base: "/",
|
base: "/",
|
||||||
integrations: [
|
integrations: [
|
||||||
tailwind(),
|
tailwind(),
|
||||||
|
swup({
|
||||||
|
theme: false,
|
||||||
|
animationClass: 'transition-',
|
||||||
|
containers: ['main'],
|
||||||
|
smoothScrolling: true,
|
||||||
|
cache: true,
|
||||||
|
preload: true,
|
||||||
|
accessibility: true,
|
||||||
|
globalInstance: true,
|
||||||
|
}),
|
||||||
icon({
|
icon({
|
||||||
include: {
|
include: {
|
||||||
"material-symbols": ["*"],
|
"material-symbols": ["*"],
|
||||||
|
|
|
@ -18,8 +18,9 @@
|
||||||
"@astrojs/tailwind": "^5.1.0",
|
"@astrojs/tailwind": "^5.1.0",
|
||||||
"@fontsource-variable/jetbrains-mono": "^5.0.19",
|
"@fontsource-variable/jetbrains-mono": "^5.0.19",
|
||||||
"@fontsource/roboto": "^5.0.8",
|
"@fontsource/roboto": "^5.0.8",
|
||||||
"astro": "^4.4.0",
|
"@swup/astro": "^1.4.0",
|
||||||
"astro-icon": "1.0.2",
|
"astro": "^4.5.1",
|
||||||
|
"astro-icon": "1.1.0",
|
||||||
"colorjs.io": "^0.4.5",
|
"colorjs.io": "^0.4.5",
|
||||||
"mdast-util-to-string": "^4.0.0",
|
"mdast-util-to-string": "^4.0.0",
|
||||||
"overlayscrollbars": "^2.4.6",
|
"overlayscrollbars": "^2.4.6",
|
||||||
|
|
3785
pnpm-lock.yaml
3785
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -5,9 +5,9 @@ import {profileConfig} from "../config";
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="card-base max-w-[var(--page-width)] min-h-[4.5rem] rounded-b-none mx-auto flex items-center px-6">
|
<div class="card-base max-w-[var(--page-width)] min-h-[4.5rem] rounded-b-none mx-auto flex items-center px-6">
|
||||||
<div class="text-50 text-sm">
|
<div class="transition text-50 text-sm">
|
||||||
© 2023 {profileConfig.name}. All Rights Reserved.
|
© 2023 {profileConfig.name}. All Rights Reserved.
|
||||||
<br>
|
<br>
|
||||||
Powered by <a class="link text-[var(--primary)]" target="_blank" href="https://github.com/saicaca/fuwari">Fuwari</a>
|
Powered by <a class="link text-[var(--primary)] font-medium" target="_blank" href="https://github.com/saicaca/fuwari">Fuwari</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -236,5 +236,13 @@ color_set({
|
||||||
.text-25 {
|
.text-25 {
|
||||||
@apply text-black/25 dark:text-white/25
|
@apply text-black/25 dark:text-white/25
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html.is-changing .transition-fade {
|
||||||
|
@apply transition-all duration-200
|
||||||
|
}
|
||||||
|
html.is-animating .transition-fade {
|
||||||
|
@apply opacity-0 translate-y-4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
|
@ -16,7 +16,7 @@ let links: NavBarLink[] = navBarConfig.links.map((item: NavBarLink | LinkPreset)
|
||||||
});
|
});
|
||||||
|
|
||||||
---
|
---
|
||||||
<div transition:animate="none" class:list={[
|
<div class:list={[
|
||||||
className,
|
className,
|
||||||
"card-base sticky top-0 overflow-visible max-w-[var(--page-width)] h-[4.5rem] rounded-t-none mx-auto flex items-center justify-between px-4"]}>
|
"card-base sticky top-0 overflow-visible max-w-[var(--page-width)] h-[4.5rem] rounded-t-none mx-auto flex items-center justify-between px-4"]}>
|
||||||
<a href="/" class="btn-plain h-[3.25rem] px-5 font-bold rounded-lg active:scale-95">
|
<a href="/" class="btn-plain h-[3.25rem] px-5 font-bold rounded-lg active:scale-95">
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Icon } from 'astro-icon/components';
|
||||||
---
|
---
|
||||||
|
|
||||||
<!-- There can't be a filter on parent element, or it will break `fixed` -->
|
<!-- There can't be a filter on parent element, or it will break `fixed` -->
|
||||||
<div class="back-to-top-wrapper hidden lg:block" transition:persist>
|
<div class="back-to-top-wrapper hidden lg:block">
|
||||||
<div id="back-to-top-btn" class="back-to-top-btn hide flex items-center rounded-2xl overflow-hidden transition" onclick="backToTop()">
|
<div id="back-to-top-btn" class="back-to-top-btn hide flex items-center rounded-2xl overflow-hidden transition" onclick="backToTop()">
|
||||||
<button aria-label="Back to Top" class="btn-card h-[3.75rem] w-[3.75rem]">
|
<button aria-label="Back to Top" class="btn-card h-[3.75rem] w-[3.75rem]">
|
||||||
<Icon name="material-symbols:keyboard-arrow-up-rounded" class="mx-auto"></Icon>
|
<Icon name="material-symbols:keyboard-arrow-up-rounded" class="mx-auto"></Icon>
|
||||||
|
|
|
@ -5,11 +5,11 @@ import Categories from "./Categories.astro";
|
||||||
|
|
||||||
const className = Astro.props.class;
|
const className = Astro.props.class;
|
||||||
---
|
---
|
||||||
<div id="sidebar" class:list={[className, "w-full"]} transition:persist>
|
<div id="sidebar" class:list={[className, "w-full"]}>
|
||||||
<div class="flex flex-col w-full gap-4 mb-4" transition:animate="none">
|
<div class="flex flex-col w-full gap-4 mb-4">
|
||||||
<Profile></Profile>
|
<Profile></Profile>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col w-full gap-4 top-4 sticky top-4" transition:animate="none">
|
<div class="flex flex-col w-full gap-4 top-4 sticky top-4">
|
||||||
<Categories></Categories>
|
<Categories></Categories>
|
||||||
<Tag></Tag>
|
<Tag></Tag>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,10 +3,8 @@ import GlobalStyles from "@components/GlobalStyles.astro";
|
||||||
import '@fontsource/roboto/400.css';
|
import '@fontsource/roboto/400.css';
|
||||||
import '@fontsource/roboto/500.css';
|
import '@fontsource/roboto/500.css';
|
||||||
import '@fontsource/roboto/700.css';
|
import '@fontsource/roboto/700.css';
|
||||||
import { ViewTransitions } from 'astro:transitions';
|
|
||||||
import ImageWrapper from "@components/misc/ImageWrapper.astro";
|
import ImageWrapper from "@components/misc/ImageWrapper.astro";
|
||||||
|
|
||||||
import { fade } from 'astro:transitions';
|
|
||||||
import {pathsEqual} from "@utils/url-utils";
|
import {pathsEqual} from "@utils/url-utils";
|
||||||
import ConfigCarrier from "@components/ConfigCarrier.astro";
|
import ConfigCarrier from "@components/ConfigCarrier.astro";
|
||||||
import {siteConfig} from "@/config";
|
import {siteConfig} from "@/config";
|
||||||
|
@ -54,6 +52,8 @@ if (!banner || typeof banner !== 'string' || banner.trim() === '') {
|
||||||
// TODO don't use post cover as banner for now
|
// TODO don't use post cover as banner for now
|
||||||
banner = siteConfig.banner.src;
|
banner = siteConfig.banner.src;
|
||||||
|
|
||||||
|
const enableBanner = siteConfig.banner.enable;
|
||||||
|
|
||||||
let pageTitle;
|
let pageTitle;
|
||||||
if (title) {
|
if (title) {
|
||||||
pageTitle = `${title} - ${siteConfig.title}`;
|
pageTitle = `${title} - ${siteConfig.title}`;
|
||||||
|
@ -66,7 +66,6 @@ if (title) {
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" isHome={isHomePage} pathname={testPathName} class="bg-[var(--page-bg)] transition text-[14px] md:text-[16px]">
|
<html lang="en" isHome={isHomePage} pathname={testPathName} class="bg-[var(--page-bg)] transition text-[14px] md:text-[16px]">
|
||||||
<head>
|
<head>
|
||||||
<ViewTransitions />
|
|
||||||
|
|
||||||
<title>{pageTitle}</title>
|
<title>{pageTitle}</title>
|
||||||
|
|
||||||
|
@ -88,15 +87,12 @@ if (title) {
|
||||||
<style define:vars={{ configHue }}></style> <!-- defines global css variables. This will be applied to <html> <body> and some other elements idk why -->
|
<style define:vars={{ configHue }}></style> <!-- defines global css variables. This will be applied to <html> <body> and some other elements idk why -->
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body class=" min-h-screen transition ">
|
<body class=" min-h-screen transition " class:list={[{"is-home": isHomePage, "enable-banner": enableBanner}]}>
|
||||||
<ConfigCarrier></ConfigCarrier>
|
<ConfigCarrier></ConfigCarrier>
|
||||||
<GlobalStyles>
|
<GlobalStyles>
|
||||||
<div id="banner-wrapper" class="absolute w-full transition-all"
|
<div id="banner-wrapper" class="absolute w-full">
|
||||||
class:list={{'banner-home': isHomePage, 'banner-else': !isHomePage}}
|
|
||||||
|
|
||||||
>
|
|
||||||
<ImageWrapper id="boxtest" alt="Banner image of the blog" class:list={["object-center object-cover h-full", {"hidden": !siteConfig.banner.enable}]}
|
<ImageWrapper id="boxtest" alt="Banner image of the blog" class:list={["object-center object-cover h-full", {"hidden": !siteConfig.banner.enable}]}
|
||||||
src={siteConfig.banner.src} transition:animate="fade"
|
src={siteConfig.banner.src}
|
||||||
>
|
>
|
||||||
</ImageWrapper>
|
</ImageWrapper>
|
||||||
</div>
|
</div>
|
||||||
|
@ -110,36 +106,32 @@ if (title) {
|
||||||
--page-width: 75rem;
|
--page-width: 75rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<style>
|
<style is:global>
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
@layer components {
|
@layer components {
|
||||||
.banner-home {
|
/* TODO: temporarily make banner height same for all pages since I cannot make the transition feel good
|
||||||
|
I want to make the height transition parallel with the content transition instead of blocking it
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
.enable-banner.is-home #banner-wrapper {
|
||||||
@apply h-[var(--banner-height)] md:h-[var(--banner-height-home)]
|
@apply h-[var(--banner-height)] md:h-[var(--banner-height-home)]
|
||||||
}
|
}
|
||||||
.banner-else {
|
*/
|
||||||
|
.enable-banner #banner-wrapper {
|
||||||
@apply h-[var(--banner-height)]
|
@apply h-[var(--banner-height)]
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#banner-wrapper {
|
/*
|
||||||
view-transition-name: banner-ani;
|
.enable-banner.is-home #top-row {
|
||||||
}
|
@apply h-[calc(var(--banner-height)_-_4.5rem)] md:h-[calc(var(--banner-height-home)_-_4.5rem)]
|
||||||
/* i don't know how this work*/
|
}
|
||||||
html::view-transition-old(banner-ani) {
|
*/
|
||||||
mix-blend-mode: normal;
|
.enable-banner #top-row {
|
||||||
animation: none;
|
@apply h-[calc(var(--banner-height)_-_4.5rem)]
|
||||||
height: 100%;
|
}
|
||||||
overflow: clip;
|
|
||||||
object-fit: none;
|
|
||||||
}
|
|
||||||
html::view-transition-new(banner-ani) {
|
|
||||||
mix-blend-mode: normal;
|
|
||||||
animation: none;
|
|
||||||
height: 100%;
|
|
||||||
overflow: clip;
|
|
||||||
object-fit: none;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
|
@ -281,6 +273,27 @@ init();
|
||||||
/* Load settings before swapping */
|
/* Load settings before swapping */
|
||||||
/* astro:after-swap event happened before swap animation */
|
/* astro:after-swap event happened before swap animation */
|
||||||
document.addEventListener('astro:after-swap', init);
|
document.addEventListener('astro:after-swap', init);
|
||||||
|
|
||||||
|
const setup = () => {
|
||||||
|
// TODO: temp solution to change the height of the banner
|
||||||
|
/*
|
||||||
|
window.swup.hooks.on('animation:out:start', () => {
|
||||||
|
const path = window.location.pathname
|
||||||
|
const body = document.querySelector('body')
|
||||||
|
if (path[path.length - 1] === '/' && !body.classList.contains('is-home')) {
|
||||||
|
body.classList.add('is-home')
|
||||||
|
} else if (path[path.length - 1] !== '/' && body.classList.contains('is-home')) {
|
||||||
|
body.classList.remove('is-home')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
if (window.swup.hooks) {
|
||||||
|
setup()
|
||||||
|
} else {
|
||||||
|
document.addEventListener('swup:enable', setup)
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style is:global lang="stylus">
|
<style is:global lang="stylus">
|
||||||
|
@ -291,5 +304,4 @@ document.addEventListener('astro:after-swap', init);
|
||||||
#banner-wrapper
|
#banner-wrapper
|
||||||
top: -120px
|
top: -120px
|
||||||
opacity: 0
|
opacity: 0
|
||||||
|
|
||||||
</style>
|
</style>
|
|
@ -21,51 +21,23 @@ const enableBanner = siteConfig.banner.enable
|
||||||
<Layout title={title} banner={banner}>
|
<Layout title={title} banner={banner}>
|
||||||
<div class="max-w-[var(--page-width)] min-h-screen grid grid-cols-[17.5rem_auto] grid-rows-[auto_auto_1fr_auto] lg:grid-rows-[auto_1fr_auto]
|
<div class="max-w-[var(--page-width)] min-h-screen grid grid-cols-[17.5rem_auto] grid-rows-[auto_auto_1fr_auto] lg:grid-rows-[auto_1fr_auto]
|
||||||
mx-auto gap-4 relative px-0 md:px-4"
|
mx-auto gap-4 relative px-0 md:px-4"
|
||||||
transition:animate="none"
|
|
||||||
>
|
>
|
||||||
<div id="top-row" class="col-span-2 grid-rows-1 z-50" class:list={["transition-all", {
|
<div id="top-row" class="col-span-2 grid-rows-1 z-50" class:list={[""]}>
|
||||||
'h-[calc(var(--banner-height)_-_4.5rem)] md:h-[calc(var(--banner-height-home)_-_4.5rem)]': enableBanner && isHomePage,
|
<Navbar></Navbar>
|
||||||
'h-[calc(var(--banner-height)_-_4.5rem)]': enableBanner && !isHomePage,}]}
|
|
||||||
>
|
|
||||||
<Navbar transition:animate="fade" transition:persist></Navbar>
|
|
||||||
</div>
|
</div>
|
||||||
<SideBar class="row-start-3 row-end-4 col-span-2 lg:row-start-2 lg:row-end-3 lg:col-span-1 lg:max-w-[17.5rem]" transition:persist></SideBar>
|
<SideBar class="row-start-3 row-end-4 col-span-2 lg:row-start-2 lg:row-end-3 lg:col-span-1 lg:max-w-[17.5rem]"></SideBar>
|
||||||
|
|
||||||
<div class="row-start-2 row-end-3 col-span-2 lg:col-span-1 overflow-hidden" transition:animate="slide">
|
<div class="row-start-2 row-end-3 col-span-2 lg:col-span-1 overflow-hidden">
|
||||||
<!-- the overflow-hidden here prevent long text break the layout-->
|
<!-- the overflow-hidden here prevent long text break the layout-->
|
||||||
<slot></slot>
|
<main id="swup" class="transition-fade">
|
||||||
|
<slot></slot>
|
||||||
|
</main>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid-rows-3 col-span-2 mt-4" transition:persist transition:animate="fade">
|
<div class="grid-rows-3 col-span-2 mt-4">
|
||||||
<Footer transition:persist></Footer>
|
<Footer></Footer>
|
||||||
</div>
|
</div>
|
||||||
<BackToTop></BackToTop>
|
<BackToTop></BackToTop>
|
||||||
</div>
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
<style>
|
|
||||||
#top-row {
|
|
||||||
view-transition-name: rrrr;
|
|
||||||
}
|
|
||||||
/* i don't know how this work*/
|
|
||||||
html::view-transition-old(rrrr) {
|
|
||||||
mix-blend-mode: normal;
|
|
||||||
animation: none;
|
|
||||||
height: auto;
|
|
||||||
overflow: clip;
|
|
||||||
object-fit: none;
|
|
||||||
}
|
|
||||||
html::view-transition-new(rrrr) {
|
|
||||||
mix-blend-mode: normal;
|
|
||||||
animation: none;
|
|
||||||
height: auto;
|
|
||||||
overflow: clip;
|
|
||||||
object-fit: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style lang="stylus" is:global>
|
|
||||||
.banner-closed
|
|
||||||
#top-row
|
|
||||||
height: 4.5rem;
|
|
||||||
</style>
|
|
||||||
|
|
Loading…
Reference in New Issue