49a92f466a
Improve sidebar navigation spacing and line heights to enhance visual hierarchy and readability. Move CSS from external file to inline style in config for better maintainability.
129 lines
3.8 KiB
JavaScript
129 lines
3.8 KiB
JavaScript
import DefaultTheme from 'vitepress/theme'
|
||
import Viewer from 'viewerjs'
|
||
import 'viewerjs/dist/viewer.css'
|
||
import TypeIt from 'typeit'
|
||
import { onMounted, watch, nextTick } from 'vue'
|
||
import { useRoute, useData } from 'vitepress'
|
||
import './style.css'
|
||
|
||
export default {
|
||
extends: DefaultTheme,
|
||
setup() {
|
||
const route = useRoute()
|
||
const { frontmatter } = useData()
|
||
let viewer = null
|
||
|
||
const initViewer = () => {
|
||
// 销毁旧实例
|
||
if (viewer) {
|
||
viewer.destroy()
|
||
viewer = null
|
||
}
|
||
|
||
// 找到文章内容容器
|
||
const doc = document.querySelector('.vp-doc')
|
||
if (doc) {
|
||
// 初始化 Viewer,配置一些常用选项
|
||
viewer = new Viewer(doc, {
|
||
button: true, // 显示右上角关闭按钮
|
||
navbar: true, // 显示底部缩略图导航
|
||
title: true, // 显示图片标题(alt 属性)
|
||
toolbar: true, // 显示工具栏(缩放、旋转等)
|
||
tooltip: true, // 显示缩放百分比
|
||
movable: true, // 允许拖拽
|
||
zoomable: true, // 允许缩放
|
||
rotatable: true, // 允许旋转
|
||
scalable: true, // 允许翻转
|
||
transition: false, // 禁用自带动画,确保打开瞬间无飞入
|
||
fullscreen: true, // 允许全屏播放
|
||
shown() {
|
||
// 打开完成后,标记为 ready,CSS 此时才会介入 transition
|
||
document.body.classList.add('viewer-ready')
|
||
},
|
||
hide() {
|
||
// 关闭前移除标记,确保关闭瞬间无动画
|
||
document.body.classList.remove('viewer-ready')
|
||
},
|
||
keyboard: true, // 允许键盘控制
|
||
url: 'src', // 图片源
|
||
// 过滤掉不想查看的图片(比如表情包等小图标,如果需要的话)
|
||
filter(image) {
|
||
return !image.classList.contains('no-viewer')
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
const initTypewriter = () => {
|
||
const taglineData = frontmatter.value.hero?.tagline
|
||
if (Array.isArray(taglineData) && taglineData.length > 0) {
|
||
const taglineEl = document.querySelector('.VPHomeHero .tagline')
|
||
if (taglineEl) {
|
||
taglineEl.innerHTML = ''
|
||
|
||
const typeIt = new TypeIt(taglineEl, {
|
||
speed: 50,
|
||
startDelay: 500,
|
||
loop: true
|
||
})
|
||
|
||
taglineData.forEach((text) => {
|
||
typeIt.type(text).pause(2000).delete().pause(500)
|
||
})
|
||
|
||
typeIt.go()
|
||
}
|
||
}
|
||
}
|
||
|
||
const optimizeImages = () => {
|
||
const images = document.querySelectorAll('.vp-doc img')
|
||
images.forEach(img => {
|
||
if (img.complete) {
|
||
applyImageStyle(img)
|
||
} else {
|
||
img.onload = () => applyImageStyle(img)
|
||
}
|
||
})
|
||
}
|
||
|
||
const applyImageStyle = (img) => {
|
||
const { naturalWidth, naturalHeight } = img
|
||
if (!naturalWidth || !naturalHeight) return
|
||
|
||
const ratio = naturalHeight / naturalWidth
|
||
img.classList.remove('img-tall', 'img-very-tall', 'img-ultra-tall')
|
||
img.style.width = 'auto' // 确保宽度自动,防止拉伸
|
||
|
||
if (ratio > 3) {
|
||
img.classList.add('img-ultra-tall')
|
||
img.style.maxHeight = '250px'
|
||
} else if (ratio > 2) {
|
||
img.classList.add('img-very-tall')
|
||
img.style.maxHeight = '350px'
|
||
} else if (ratio > 1.2) {
|
||
img.classList.add('img-tall')
|
||
img.style.maxHeight = '450px'
|
||
} else {
|
||
// 普通图片重置,避免复用 dom 时残留样式
|
||
img.style.maxHeight = ''
|
||
}
|
||
}
|
||
|
||
onMounted(() => {
|
||
initViewer()
|
||
initTypewriter()
|
||
optimizeImages()
|
||
})
|
||
|
||
watch(
|
||
() => route.path,
|
||
() => nextTick(() => {
|
||
initViewer()
|
||
initTypewriter()
|
||
optimizeImages()
|
||
})
|
||
)
|
||
}
|
||
}
|