From 46bcb981403cebbe97e0f8e31d467e314521ab12 Mon Sep 17 00:00:00 2001 From: RayJason Date: Sun, 7 Apr 2024 10:56:02 +0800 Subject: [PATCH] add TransitionAPI in theme toggle (#466) * feat: add TransitionAPI in theme toggle * feat: update transition animation * feat: update transition 8deg animation --- .../src/components/td-theme-tabs/index.js | 27 ++++++-- .../src/components/td-theme-tabs/style.less | 65 ++++++++++++++++++- 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/packages/components/src/components/td-theme-tabs/index.js b/packages/components/src/components/td-theme-tabs/index.js index 789304e0..bbf93368 100755 --- a/packages/components/src/components/td-theme-tabs/index.js +++ b/packages/components/src/components/td-theme-tabs/index.js @@ -7,12 +7,21 @@ import { watchHtmlMode } from '@utils'; // const isDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; const storageChangeEvent = new CustomEvent('storageChange'); -function handleTabClick(host, currentTheme) { +function toggleTheme(host, currentTheme) { document.documentElement.removeAttribute('theme-mode'); Object.assign(host, { theme: currentTheme }); document.documentElement.setAttribute('theme-mode', currentTheme); } +function handleTabClick(host, event, currentTheme) { + const root = document.documentElement; + const prevTheme = root.getAttribute('theme-mode'); + if (prevTheme === currentTheme) return; + + if (!document.startViewTransition) return toggleTheme(host, currentTheme); + document.startViewTransition(() => toggleTheme(host, currentTheme)); +} + function initBlockStyleMap(host) { requestAnimationFrame(() => { const { shadowRoot } = host; @@ -50,7 +59,7 @@ export default define({ if (lastTheme) { document.documentElement.removeAttribute('theme-mode'); - + Object.assign(host, { [key]: lastTheme }); document.documentElement.setAttribute('theme-mode', lastTheme); invalidate(); @@ -74,8 +83,18 @@ export default define({ return html`
-
handleTabClick(host, 'light')} data-theme="light" class="item sun ${theme === 'light' ? 'active' : ''}" innerHTML=${sunIcon}>
-
handleTabClick(host, 'dark')} data-theme="dark" class="item moon ${theme === 'dark' ? 'active' : ''}" innerHTML=${moonIcon}>
+
handleTabClick(host, e, 'light')} + data-theme="light" + class="item sun ${theme === 'light' ? 'active' : ''}" + innerHTML=${sunIcon} + >
+
handleTabClick(host, e, 'dark')} + data-theme="dark" + class="item moon ${theme === 'dark' ? 'active' : ''}" + innerHTML=${moonIcon} + >
`.css`${style}`; }, diff --git a/packages/components/src/components/td-theme-tabs/style.less b/packages/components/src/components/td-theme-tabs/style.less index 420577d7..be6532f7 100755 --- a/packages/components/src/components/td-theme-tabs/style.less +++ b/packages/components/src/components/td-theme-tabs/style.less @@ -15,9 +15,8 @@ justify-content: space-between; &__block { - position: absolute; background-color: var(--bg-color-tab-select); - box-shadow: 0px 2px 4px rgba(0, 0, 0, .15); + box-shadow: 0 2px 4px rgba(0, 0, 0, .15); position: absolute; height: calc(100% - 4px); transition: all var(--anim-time-fn-easing) var(--anim-duration-moderate); @@ -55,4 +54,66 @@ color: #fff; } } +} + +:root::view-transition-group(root) { + animation-duration: 1s; +} + +:root::view-transition-new(root), +:root::view-transition-old(root) { + mix-blend-mode: normal; +} + +:root::view-transition-old(root), +:root[theme-mode='dark']::view-transition-old(root) { + animation: none; +} + +:root::view-transition-new(root) { + animation-name: dark-to-light; +} + +:root[theme-mode='dark']::view-transition-new(root) { + animation-name: light-to-dark; +} + +@keyframes light-to-dark { + from { + clip-path: polygon( + 0 0, + 0 0, + calc(tan(8deg) * -100vh) 100%, + calc(tan(8deg) * -100vh) 100% + ); + } + + to { + clip-path: polygon( + 0 0, + calc((tan(8deg) * 100vh) + 100%) 0, + 100% 100%, + calc(tan(8deg) * -100vh) 100% + ); + } +} + +@keyframes dark-to-light { + from { + clip-path: polygon( + calc((tan(8deg) * 100vh) + 100%) 0, + calc((tan(8deg) * 100vh) + 100%) 0, + 100% 100%, + 100% 100% + ); + } + + to { + clip-path: polygon( + 0 0, + calc((tan(8deg) * 100vh) + 100%) 0, + 100% 100%, + calc(tan(8deg) * -100vh) 100% + ); + } } \ No newline at end of file