From 0a7f84ce8cd75914bc8cfdcaa942f950dc6b846a Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Mon, 13 May 2024 22:25:24 +0800 Subject: [PATCH] doc(Theme): add switch theme transition (#3496) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 更新搜索弹窗 z-index * feat: 修复手机模式切换明亮暗黑模式按钮 * refactor: 增加点击事件释放逻辑 * feat: 增加主题切换特效 * chore: 更新变量名称 --- .../Components/GlobalSearch.razor.css | 2 +- .../Components/Components/Header.razor.js | 39 ++++++++++++++++--- .../Components/Components/ThemeMode.razor | 6 +-- .../Components/Components/ThemeMode.razor.cs | 37 ++++++++++++++++++ .../Components/Layout/BaseLayout.razor.css | 1 + .../wwwroot/css/site.css | 29 ++++++++++---- .../ThemeProvider/ThemeProvider.razor.js | 9 +++-- 7 files changed, 104 insertions(+), 19 deletions(-) create mode 100644 src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor.cs diff --git a/src/BootstrapBlazor.Server/Components/Components/GlobalSearch.razor.css b/src/BootstrapBlazor.Server/Components/Components/GlobalSearch.razor.css index 58cca4899..3512f9569 100644 --- a/src/BootstrapBlazor.Server/Components/Components/GlobalSearch.razor.css +++ b/src/BootstrapBlazor.Server/Components/Components/GlobalSearch.razor.css @@ -57,7 +57,7 @@ top: var(--bb-global-search-top); left: var(--bb-global-search-left); right: var(--bb-global-search-right); - z-index: 45; + z-index: 50; height: calc(100vh - 160px); color: var(--bs-body-color); background-color: var(--bs-body-bg); diff --git a/src/BootstrapBlazor.Server/Components/Components/Header.razor.js b/src/BootstrapBlazor.Server/Components/Components/Header.razor.js index 7ff62f2fd..07c1ba2e1 100644 --- a/src/BootstrapBlazor.Server/Components/Components/Header.razor.js +++ b/src/BootstrapBlazor.Server/Components/Components/Header.razor.js @@ -1,6 +1,8 @@ -import EventHandler from "../../_content/BootstrapBlazor/modules/event-handler.js" +import { getTheme, setTheme } from "../../_content/BootstrapBlazor/modules/utility.js" +import Data from "../../_content/BootstrapBlazor/modules/data.js" +import EventHandler from "../../_content/BootstrapBlazor/modules/event-handler.js" -export function init() { +export function init(id) { const scrollTop = () => (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop let prevScrollTop = 0; EventHandler.on(document, 'scroll', () => { @@ -13,9 +15,36 @@ export function init() { items.forEach(item => item.classList.remove('hide')) } prevScrollTop = currentScrollTop - }) + }); + + const themeElement = document.querySelector('.icon-theme'); + if (themeElement) { + EventHandler.on(themeElement, 'click', e => { + let theme = getTheme(); + if (theme === 'dark') { + theme = 'light'; + } + else { + theme = 'dark'; + } + document.documentElement.style.setProperty('--bb-theme-x', `${window.innerWidth}px`); + document.documentElement.style.setProperty('--bb-theme-y', `${window.innerHeight}px`); + document.startViewTransition(() => { + setTheme(theme, true); + }); + }); + } + + Data.set(id, themeElement); } -export function dispose() { - EventHandler.off(document, 'scroll') +export function dispose(id) { + EventHandler.off(document, 'scroll'); + + const themeElement = Data.get(id); + Data.remove(id); + + if (themeElement) { + EventHandler.off(themeElement, 'click'); + } } diff --git a/src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor b/src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor index a5e82dd9d..800a8f1c5 100644 --- a/src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor +++ b/src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor @@ -1,6 +1,6 @@ @inherits ComponentBase -
- - +
+ +
diff --git a/src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor.cs b/src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor.cs new file mode 100644 index 000000000..dbe737d2d --- /dev/null +++ b/src/BootstrapBlazor.Server/Components/Components/ThemeMode.razor.cs @@ -0,0 +1,37 @@ +// Copyright (c) Argo Zhang (argo@163.com). All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +// Website: https://www.blazor.zone or https://argozhang.github.io/ + +namespace BootstrapBlazor.Server.Components.Components; + +/// +/// ThemeMode 页面 +/// +public partial class ThemeMode +{ + [Inject, NotNull] + private IIconTheme? IconTheme { get; set; } + + private string? GetLightIconClassString => CssBuilder.Default("icon-light") + .AddClass(_lightModeIcon) + .Build(); + + private string? GetDarkIconClassString => CssBuilder.Default("icon-dark") + .AddClass(_darkModeIcon) + .Build(); + + private string? _darkModeIcon; + + private string? _lightModeIcon; + + /// + /// + /// + protected override void OnInitialized() + { + base.OnInitialized(); + + _darkModeIcon ??= IconTheme.GetIconByKey(ComponentIcons.ThemeProviderDarkModeIcon); + _lightModeIcon ??= IconTheme.GetIconByKey(ComponentIcons.ThemeProviderLightModeIcon); + } +} diff --git a/src/BootstrapBlazor.Server/Components/Layout/BaseLayout.razor.css b/src/BootstrapBlazor.Server/Components/Layout/BaseLayout.razor.css index 6526776cc..224bb329d 100644 --- a/src/BootstrapBlazor.Server/Components/Layout/BaseLayout.razor.css +++ b/src/BootstrapBlazor.Server/Components/Layout/BaseLayout.razor.css @@ -53,6 +53,7 @@ display: flex; justify-content: center; align-items: center; + color: var(--bb-button-chat-color); } ::deep pre { diff --git a/src/BootstrapBlazor.Server/wwwroot/css/site.css b/src/BootstrapBlazor.Server/wwwroot/css/site.css index 075a1d504..a711e4428 100644 --- a/src/BootstrapBlazor.Server/wwwroot/css/site.css +++ b/src/BootstrapBlazor.Server/wwwroot/css/site.css @@ -266,20 +266,16 @@ code { background-color: rgba(var(--bs-emphasis-color-rgb),.1); } -.icon-theme img { - cursor: pointer; -} - -.icon-theme .icon-light { +.icon-theme .icon-dark { display: none; } [data-bs-theme='dark'] .icon-dark { - display: none; + display: block; } [data-bs-theme='dark'] .icon-light { - display: block; + display: none; } .layout-demo { @@ -313,6 +309,25 @@ code { width: 320px; } +::view-transition-old(root) { + animation: none; +} + +::view-transition-new(root) { + mix-blend-mode: normal; + animation: clip .3s ease-in; +} + +@keyframes clip { + from { + clip-path: circle(0% at var(--bb-theme-x) var(--bb-theme-y)); + } + + to { + clip-path: circle(100% at var(--bb-theme-x) var(--bb-theme-y)); + } +} + @media (min-width: 768px) { :root { --bs-header-height: 50px; diff --git a/src/BootstrapBlazor/Components/ThemeProvider/ThemeProvider.razor.js b/src/BootstrapBlazor/Components/ThemeProvider/ThemeProvider.razor.js index 090107e49..fc4cf1450 100644 --- a/src/BootstrapBlazor/Components/ThemeProvider/ThemeProvider.razor.js +++ b/src/BootstrapBlazor/Components/ThemeProvider/ThemeProvider.razor.js @@ -1,4 +1,4 @@ -import { getAutoThemeValue, getPreferredTheme, setActiveTheme, setTheme, saveTheme } from "../../modules/utility.js" +import { getAutoThemeValue, getPreferredTheme, setActiveTheme, setTheme } from "../../modules/utility.js" import EventHandler from "../../modules/event-handler.js" export function init(id) { @@ -19,8 +19,11 @@ export function init(id) { if (theme === 'auto') { theme = getAutoThemeValue(); } - setTheme(theme, false); - saveTheme(theme); + document.documentElement.style.setProperty('--bb-theme-x', `${window.innerWidth}px`); + document.documentElement.style.setProperty('--bb-theme-y', '0px'); + document.startViewTransition(() => { + setTheme(theme, true); + }); }); }); }