Skip to content

Commit

Permalink
Merge pull request #93 from stefan-ysh/main
Browse files Browse the repository at this point in the history
Add view transition animation to the theme toggle functionality
  • Loading branch information
babaohuang authored Dec 25, 2023
2 parents a72c829 + ba35bb9 commit 62215d1
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 6 deletions.
54 changes: 48 additions & 6 deletions src/components/Themetoggle.astro
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,54 @@ const listenColorSchema = () => {
listenColorSchema()
toogleThemeCircle()

const handleToggleClick = () => {
const element = document.documentElement
element.classList.toggle('dark')
const isDark = element.classList.contains('dark')
localStorage.setItem('theme', isDark ? 'dark' : 'light')
toogleThemeCircle()
const handleToggleClick = ({ x, y }) => {
const root = document.documentElement
const isDark = root.classList.contains('dark')
localStorage.setItem('theme', isDark ? 'light' : 'dark')

// check if the current browser supports viewtransition API
const isAppearanceTransition
// @ts-expect-error: Transition API
= document.startViewTransition
&& !window.matchMedia('(prefers-reduced-motion: reduce)').matches

// if it is not supported, just toggle the class directly
if (!isAppearanceTransition) {
toogleThemeCircle()
root.classList.toggle('dark')
} else {
// if it is supported, use the transition API to animate the theme change
const endRadius = Math.hypot(
Math.max(x, innerWidth - x),
Math.max(y, innerHeight - y),
)

// @ts-expect-error: Transition API
const transition = document.startViewTransition(() => {
root.classList.toggle('dark')
toogleThemeCircle()
})
transition.ready.then(() => {
const clipPath = [
`circle(0px at ${x}px ${y}px)`,
`circle(${endRadius}px at ${x}px ${y}px)`,
]
const _c = !isDark ? clipPath : [...clipPath].reverse()
const pseudoElement = !isDark
? '::view-transition-new(root)'
: '::view-transition-old(root)'
document.documentElement.animate(
{
clipPath: _c,
},
{
duration: 500,
easing: 'ease-in',
pseudoElement,
},
)
})
}
}
themeToggle.addEventListener('click', handleToggleClick)
</script>
20 changes: 20 additions & 0 deletions src/layouts/Layout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,27 @@ const { title } = Astro.props;
min-height: calc(100vh - 4.5rem);
}
}
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
mix-blend-mode: normal;
}

.dark::view-transition-old(root) {
z-index: 1;
}

.dark::view-transition-new(root) {
z-index: 999;
}

::view-transition-old(root) {
z-index: 999;
}

::view-transition-new(root) {
z-index: 1;
}
</style>

<script>
Expand Down

1 comment on commit 62215d1

@vercel
Copy link

@vercel vercel bot commented on 62215d1 Dec 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.