feat: add View Transitions API hero animation for favicon between pages
The favicon animates from its large position in the WelcomeWorld title to the smaller header position in PublicNoteListView and PublicNoteListByDidView.
This commit is contained in:
10
src/App.vue
10
src/App.vue
@@ -21,4 +21,14 @@ const { isATProtoReady } = useATProtoLogin()
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::view-transition-old(root),
|
||||||
|
::view-transition-new(root) {
|
||||||
|
animation-duration: 0.25s;
|
||||||
|
}
|
||||||
|
|
||||||
|
::view-transition-group(remanso-logo) {
|
||||||
|
animation-duration: 0.4s;
|
||||||
|
animation-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ const { userInput, repoInput, submit } = useForm()
|
|||||||
<template>
|
<template>
|
||||||
<div class="welcome-world">
|
<div class="welcome-world">
|
||||||
<h1 class="title is-1">
|
<h1 class="title is-1">
|
||||||
<img src="/favicon.png" alt="Remanso icon" />
|
<img src="/favicon.png" alt="Remanso icon" class="remanso-logo" />
|
||||||
Remanso
|
Remanso
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
@@ -93,6 +93,10 @@ h1 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.remanso-logo {
|
||||||
|
view-transition-name: remanso-logo;
|
||||||
|
}
|
||||||
|
|
||||||
.welcome-world {
|
.welcome-world {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { nextTick } from "vue"
|
||||||
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router"
|
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router"
|
||||||
|
|
||||||
import Home from "@/views/HomeApp.vue"
|
import Home from "@/views/HomeApp.vue"
|
||||||
@@ -93,3 +94,13 @@ export const router = createRouter({
|
|||||||
history: createWebHistory(import.meta.env.BASE_URL),
|
history: createWebHistory(import.meta.env.BASE_URL),
|
||||||
routes,
|
routes,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
router.beforeEach(() => {
|
||||||
|
if (!("startViewTransition" in document)) return
|
||||||
|
return new Promise<void>((resolve) => {
|
||||||
|
;(document as Document & { startViewTransition: (cb: () => Promise<void>) => void }).startViewTransition(async () => {
|
||||||
|
resolve()
|
||||||
|
await nextTick()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const author = computedAsync(async () => getAuthor(did.value))
|
|||||||
<main class="public-note-list-view">
|
<main class="public-note-list-view">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<home-button class="back-button" />
|
<home-button class="back-button" />
|
||||||
|
<img src="/favicon.png" alt="Remanso" class="remanso-logo" />
|
||||||
<h1 v-if="author">{{ author.handle }}</h1>
|
<h1 v-if="author">{{ author.handle }}</h1>
|
||||||
<div v-else class="skeleton h-8 w-40"></div>
|
<div v-else class="skeleton h-8 w-40"></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -65,6 +66,13 @@ const author = computedAsync(async () => getAuthor(did.value))
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.remanso-logo {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
box-shadow: none;
|
||||||
|
view-transition-name: remanso-logo;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 769px) {
|
@media screen and (min-width: 769px) {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ const following = useFollowingNoteList(follows, followingEnabled)
|
|||||||
<main class="public-note-list-view">
|
<main class="public-note-list-view">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<home-button class="back-button" />
|
<home-button class="back-button" />
|
||||||
|
<img src="/favicon.png" alt="Remanso" class="remanso-logo" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="isLoggedIn" role="tablist" class="tabs tabs-border">
|
<div v-if="isLoggedIn" role="tablist" class="tabs tabs-border">
|
||||||
@@ -135,6 +136,14 @@ const following = useFollowingNoteList(follows, followingEnabled)
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remanso-logo {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
box-shadow: none;
|
||||||
|
view-transition-name: remanso-logo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 769px) {
|
@media screen and (min-width: 769px) {
|
||||||
|
|||||||
Reference in New Issue
Block a user