mirror of
https://gitee.com/guoyifanA/qiu-mo-jetbrains-help.git
synced 2026-09-21 22:30:45 +08:00
增加黑夜模式
This commit is contained in:
@@ -272,6 +272,104 @@ body {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 暗黑模式样式 */
|
||||
html.dark {
|
||||
filter: invert(1) hue-rotate(180deg);
|
||||
}
|
||||
|
||||
/* 只有在没有View Transition时才使用CSS过渡 */
|
||||
html:not(.view-transition-active) {
|
||||
transition: filter 300ms ease;
|
||||
}
|
||||
|
||||
html.dark img,
|
||||
html.dark video,
|
||||
html.dark .avatar,
|
||||
html.dark .image,
|
||||
html.dark .thumb,
|
||||
html.dark [class*="icon-"],
|
||||
html.dark .product-icon {
|
||||
filter: invert(1) hue-rotate(180deg);
|
||||
}
|
||||
|
||||
/* 主题切换按钮样式 */
|
||||
.theme-toggle {
|
||||
position: relative;
|
||||
width: 50px;
|
||||
height: 26px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 13px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.theme-toggle::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
background: white;
|
||||
border-radius: 50%;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
html.dark .theme-toggle::before {
|
||||
transform: translateX(24px);
|
||||
}
|
||||
|
||||
.theme-toggle .theme-icon {
|
||||
font-size: 12px;
|
||||
color: white;
|
||||
z-index: 1;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.theme-toggle .sun-icon {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.theme-toggle .moon-icon {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
html.dark .theme-toggle .sun-icon {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
html.dark .theme-toggle .moon-icon {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* View Transition API 动画样式 */
|
||||
::view-transition-old(root),
|
||||
::view-transition-new(root) {
|
||||
animation: none;
|
||||
mix-blend-mode: normal;
|
||||
}
|
||||
|
||||
::view-transition-old(root) {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
::view-transition-new(root) {
|
||||
z-index: 2147483646;
|
||||
}
|
||||
|
||||
html.dark::view-transition-old(root) {
|
||||
z-index: 2147483646;
|
||||
}
|
||||
|
||||
html.dark::view-transition-new(root) {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* 移动端优化 */
|
||||
@media (max-width: 768px) {
|
||||
.license-code-display {
|
||||
@@ -279,13 +377,13 @@ body {
|
||||
padding: 12px;
|
||||
max-height: 200px;
|
||||
}
|
||||
|
||||
|
||||
.notification {
|
||||
right: 10px;
|
||||
left: 10px;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
|
||||
.config-code {
|
||||
font-size: 11px;
|
||||
padding: 8px;
|
||||
@@ -293,36 +391,56 @@ body {
|
||||
word-break: break-all;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
|
||||
.config-section {
|
||||
padding: 12px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
|
||||
/* 配置步骤移动端优化 */
|
||||
.config-step-mobile {
|
||||
flex-direction: column;
|
||||
space-y: 12px;
|
||||
}
|
||||
|
||||
|
||||
.config-step-mobile .config-step-content {
|
||||
margin-left: 0;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
|
||||
/* 首页内容移动端优化 */
|
||||
.home-section {
|
||||
padding: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
|
||||
.home-title {
|
||||
font-size: 28px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
|
||||
.home-subtitle {
|
||||
font-size: 16px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* 主题切换按钮移动端优化 */
|
||||
.theme-toggle {
|
||||
width: 45px;
|
||||
height: 24px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.theme-toggle::before {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
html.dark .theme-toggle::before {
|
||||
transform: translateX(21px);
|
||||
}
|
||||
|
||||
.theme-toggle .theme-icon {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
@@ -87,9 +87,17 @@
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<button @click="showConfigModal = true" class="p-2 text-gray-600 hover:text-purple-600 transition-colors" title="配置">
|
||||
<i class="fas fa-cog"></i>
|
||||
</button>
|
||||
<div class="flex items-center space-x-3">
|
||||
<!-- 主题切换按钮 -->
|
||||
<div @click="toggleTheme($event)" class="theme-toggle" title="切换主题">
|
||||
<i class="fas fa-sun theme-icon sun-icon"></i>
|
||||
<i class="fas fa-moon theme-icon moon-icon"></i>
|
||||
</div>
|
||||
|
||||
<button @click="showConfigModal = true" class="p-2 text-gray-600 hover:text-purple-600 transition-colors" title="配置">
|
||||
<i class="fas fa-cog"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -64,16 +64,19 @@ const App = {
|
||||
this.loadProducts()
|
||||
this.loadPlugins()
|
||||
this.setDefaultExpiryDate()
|
||||
|
||||
|
||||
// 加载主题设置
|
||||
Utils.loadTheme()
|
||||
|
||||
// 监听滚动事件
|
||||
const handleScroll = () => {
|
||||
const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
|
||||
this.showBackToTop = scrollTop > 300
|
||||
}
|
||||
|
||||
|
||||
// 监听滚动事件
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
|
||||
|
||||
// 保存函数引用以便清理
|
||||
this._handleScroll = handleScroll
|
||||
},
|
||||
@@ -239,6 +242,11 @@ const App = {
|
||||
top: 0,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
},
|
||||
|
||||
// 主题切换
|
||||
toggleTheme(event) {
|
||||
Utils.toggleTheme(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +108,78 @@ const Utils = {
|
||||
const date = new Date()
|
||||
date.setFullYear(date.getFullYear() + 1)
|
||||
return date.toISOString().split('T')[0]
|
||||
},
|
||||
|
||||
// 主题切换功能
|
||||
toggleTheme(event) {
|
||||
// 检查浏览器是否支持 View Transition API
|
||||
if (!document.startViewTransition) {
|
||||
// 不支持则直接切换主题,不添加动画
|
||||
document.documentElement.classList.toggle('dark')
|
||||
this.saveTheme()
|
||||
return
|
||||
}
|
||||
|
||||
// 标记正在使用View Transition,避免CSS过渡冲突
|
||||
document.documentElement.classList.add('view-transition-active')
|
||||
|
||||
const transition = document.startViewTransition(() => {
|
||||
document.documentElement.classList.toggle('dark')
|
||||
this.saveTheme()
|
||||
})
|
||||
|
||||
transition.ready.then(() => {
|
||||
const { clientX, clientY } = event
|
||||
|
||||
const endRadius = Math.hypot(Math.max(clientX, innerWidth - clientX), Math.max(clientY, innerHeight - clientY))
|
||||
|
||||
const clipPath = [`circle(0px at ${clientX}px ${clientY}px)`, `circle(${endRadius}px at ${clientX}px ${clientY}px)`]
|
||||
|
||||
const isDark = document.documentElement.classList.contains('dark')
|
||||
|
||||
document.documentElement.animate(
|
||||
{
|
||||
clipPath: isDark ? clipPath.reverse() : clipPath
|
||||
},
|
||||
{
|
||||
duration: 450,
|
||||
easing: 'ease-in',
|
||||
pseudoElement: isDark ? '::view-transition-old(root)' : '::view-transition-new(root)'
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
// 动画完成后移除标记类
|
||||
transition.finished.finally(() => {
|
||||
document.documentElement.classList.remove('view-transition-active')
|
||||
})
|
||||
},
|
||||
|
||||
// 保存主题设置
|
||||
saveTheme() {
|
||||
const isDark = document.documentElement.classList.contains('dark')
|
||||
localStorage.setItem('theme', isDark ? 'dark' : 'light')
|
||||
},
|
||||
|
||||
// 加载主题设置
|
||||
loadTheme() {
|
||||
const savedTheme = localStorage.getItem('theme')
|
||||
if (savedTheme === 'dark') {
|
||||
document.documentElement.classList.add('dark')
|
||||
} else if (savedTheme === 'light') {
|
||||
document.documentElement.classList.remove('dark')
|
||||
} else {
|
||||
// 如果没有保存的主题,检查系统偏好
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
if (prefersDark) {
|
||||
document.documentElement.classList.add('dark')
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 获取当前主题
|
||||
getCurrentTheme() {
|
||||
return document.documentElement.classList.contains('dark') ? 'dark' : 'light'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user