mirror of
https://gitee.com/SuperManito/LinuxMirrors
synced 2026-01-07 15:25:49 +08:00
106 lines
6.1 KiB
HTML
106 lines
6.1 KiB
HTML
<form class="md-header__option" data-md-component="palette">
|
|
{% for option in config.theme.palette %} {% set scheme = option.scheme | d("default", true) %} {% set primary = option.primary | d("indigo", true) %} {% set accent = option.accent | d("indigo", true) %}
|
|
<input class="md-option" data-md-color-media="{{ option.media }}" data-md-color-scheme="{{ scheme | replace(' ', '-') }}" data-md-color-primary="{{ primary | replace(' ', '-') }}" data-md-color-accent="{{ accent | replace(' ', '-') }}" {% if option.toggle %} aria-label="{{ option.toggle.name }}" {% else %} aria-hidden="true" {% endif %} type="radio" name="__palette" id="__palette_{{ loop.index0 }}" />
|
|
{% if option.toggle %}
|
|
<label class="md-header__button md-icon" title="{{ option.toggle.name }}" for="__palette_{{ loop.index % loop.length }}" hidden> {% include ".icons/" ~ option.toggle.icon ~ ".svg" %} </label>
|
|
{% endif %} {% endfor %}
|
|
</form>
|
|
<script>
|
|
var palette = __md_get('__palette')
|
|
if (palette && palette.color) {
|
|
/* Retrieve color palette for system preference */
|
|
if (palette.color.media === '(prefers-color-scheme)') {
|
|
var media = matchMedia('(prefers-color-scheme: light)')
|
|
var input = document.querySelector(media.matches ? "[data-md-color-media='(prefers-color-scheme: light)']" : "[data-md-color-media='(prefers-color-scheme: dark)']")
|
|
/* Retrieve colors for system preference */
|
|
;(palette.color.media = input.getAttribute('data-md-color-media')), (palette.color.scheme = input.getAttribute('data-md-color-scheme')), (palette.color.primary = input.getAttribute('data-md-color-primary')), (palette.color.accent = input.getAttribute('data-md-color-accent'))
|
|
}
|
|
/* Set color palette */
|
|
for (var [key, value] of Object.entries(palette.color)) document.body.setAttribute('data-md-color-' + key, value)
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
if (typeof document.startViewTransition !== 'function') {
|
|
return // 不支持 View Transitions API 的浏览器直接返回
|
|
}
|
|
// 获取所有主题切换按钮
|
|
const themeToggles = document.querySelectorAll('.md-header__button.md-icon')
|
|
themeToggles.forEach((toggle) => {
|
|
toggle.addEventListener(
|
|
'click',
|
|
function (e) {
|
|
// 阻止默认点击事件
|
|
e.preventDefault()
|
|
e.stopPropagation()
|
|
// 获取目标输入元素
|
|
const targetId = this.getAttribute('for')
|
|
const targetInput = document.getElementById(targetId)
|
|
if (!targetInput) return
|
|
// 获取当前存储的主题信息和即将切换到的主题信息
|
|
const currentPalette = __md_get('__palette')
|
|
const currentScheme = currentPalette?.color?.scheme || ''
|
|
const currentMedia = currentPalette?.color?.media || ''
|
|
// 获取新主题信息
|
|
const newScheme = targetInput.getAttribute('data-md-color-scheme')
|
|
const newMedia = targetInput.getAttribute('data-md-color-media')
|
|
// 判断当前浏览器/系统主题
|
|
const isSystemDark = window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
// 判断是否切换到暗色主题
|
|
const isDark = newScheme != 'default'
|
|
// 确定当前主题的实际暗色状态
|
|
let isCurrentDark = currentScheme.includes('slate')
|
|
if (currentMedia === '(prefers-color-scheme)') {
|
|
isCurrentDark = isSystemDark
|
|
}
|
|
// 确定新主题的实际暗色状态
|
|
let isNewDark = newScheme.includes('slate')
|
|
if (newMedia === '(prefers-color-scheme)') {
|
|
isNewDark = isSystemDark
|
|
}
|
|
// 如果当前主题和目标主题相同,则不需要动画
|
|
if (isCurrentDark === isNewDark) {
|
|
targetInput.click()
|
|
return
|
|
}
|
|
// 动画参数
|
|
const x = e.clientX
|
|
const y = e.clientY
|
|
const endRadius = Math.hypot(Math.max(x, window.innerWidth - x), Math.max(y, window.innerHeight - y))
|
|
// 设置动画路径
|
|
const clipPath = [`circle(0px at ${x}px ${y}px)`, `circle(${endRadius}px at ${x}px ${y}px)`]
|
|
// 启动视图过渡
|
|
document
|
|
.startViewTransition(async () => {
|
|
// 切换主题
|
|
targetInput.click()
|
|
// 添加暗/亮模式类,用于动画控制
|
|
document.documentElement.classList.remove(isDark ? 'light' : 'dark')
|
|
document.documentElement.classList.add(isDark ? 'dark' : 'light')
|
|
// 等待主题变化完成
|
|
await new Promise((resolve) => setTimeout(resolve, 100))
|
|
})
|
|
.ready.then(() => {
|
|
// 视图过渡准备就绪,开始动画
|
|
document.documentElement.animate(
|
|
{
|
|
clipPath: isDark ? [...clipPath].reverse() : clipPath,
|
|
},
|
|
{
|
|
duration: 500,
|
|
easing: 'ease-in',
|
|
pseudoElement: isDark ? '::view-transition-old(root)' : '::view-transition-new(root)',
|
|
}
|
|
)
|
|
})
|
|
},
|
|
{ capture: true }
|
|
)
|
|
})
|
|
// 初始化主题状态类
|
|
const currentPalette = __md_get('__palette')
|
|
const currentScheme = currentPalette?.color?.scheme || ''
|
|
const isDark = currentScheme.includes('slate')
|
|
document.documentElement.classList.add(isDark ? 'dark' : 'light')
|
|
})
|
|
</script>
|