Files
LinuxMirrors/docs/theme/partials/palette.html
Super Manito 421e0a42aa 更新文档
2025-04-04 13:15:39 +08:00

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>