Files
LinuxMirrors/docs/theme/partials/palette.html
Super Manito 984cfa4eed 更新文档
2025-04-08 02:28:46 +08:00

90 lines
5.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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 的浏览器直接返回
}
// 获取所有主题切换按钮 - 更精确的选择器
// 只选择form[data-md-component="palette"]内部的按钮而不是所有md-header__button
const themeToggles = document.querySelectorAll('form[data-md-component="palette"] .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 currentScheme = document.body.getAttribute('data-md-color-scheme')
const isCurrentDark = currentScheme.includes('slate')
// 点击后会切换到相反的主题
const isNewDark = !isCurrentDark
// 当前主题和目标主题相同则不触发动画
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(isNewDark ? 'light' : 'dark')
document.documentElement.classList.add(isNewDark ? 'dark' : 'light')
// 等待主题变化完成
await new Promise((resolve) => setTimeout(resolve, 100))
})
.ready.then(() => {
// 视图过渡准备就绪,开始动画
document.documentElement.animate(
{
clipPath: isNewDark ? [...clipPath].reverse() : clipPath,
},
{
duration: 500,
easing: 'ease-in',
pseudoElement: isNewDark ? '::view-transition-old(root)' : '::view-transition-new(root)',
}
)
})
},
{ capture: true }
)
})
// 初始化主题状态类
const currentScheme = document.body.getAttribute('data-md-color-scheme')
const isDark = currentScheme.includes('slate')
document.documentElement.classList.add(isDark ? 'dark' : 'light')
})
</script>