Refactor Calendar component

This commit is contained in:
KazooTTT
2025-01-08 00:28:16 +08:00
parent 11c193786d
commit 96686f37e3
5 changed files with 210 additions and 276 deletions

View File

@ -5,6 +5,7 @@ import BlogHero from '@/components/blog/Hero.astro'
import TOC from '@/components/blog/TOC.astro'
import Button from '@/components/Button.astro'
import PageLayout from './BaseLayout.astro'
import GiscusComment from '@/components/GiscusComment'
interface Props {
post: CollectionEntry<'post'>
@ -55,10 +56,11 @@ const { headings } = await post.render()
</div>
<div
id='blog-gallery'
class='prose prose-base prose-zinc mt-12 text-muted-foreground dark:prose-invert prose-headings:font-medium prose-headings:text-foreground prose-headings:before:absolute prose-headings:before:-ms-4 prose-th:before:content-none prose-img:shadow'
class='prose-base prose-zinc mt-12 w-full text-muted-foreground dark:prose-invert prose-headings:font-medium prose-headings:text-foreground prose-headings:before:absolute prose-headings:before:-ms-4 prose-th:before:content-none prose-img:shadow'
>
<slot />
</div>
<GiscusComment client:load />
</article>
</div>
<button
@ -80,38 +82,6 @@ const { headings } = await post.render()
</svg>
</button>
</div>
<!-- Image Preview Modal -->
<div
id='image-modal'
class='pointer-events-none fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50 opacity-0 backdrop-blur-md transition-opacity duration-300 ease-in-out'
>
<div class='relative flex h-full w-full items-center justify-center p-4' id='modal-container'>
<img
id='modal-image'
alt='modal-image'
class='h-auto max-h-full w-auto max-w-full object-contain transition-transform duration-300 ease-in-out'
/>
<button
id='close-modal'
class='absolute right-4 top-4 text-white transition-colors duration-300 hover:text-gray-300'
>
<svg
xmlns='http://www.w3.org/2000/svg'
class='h-6 w-6'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
>
<path
stroke-linecap='round'
stroke-linejoin='round'
stroke-width='2'
d='M6 18L18 6M6 6l12 12'></path>
</svg>
</button>
</div>
</div>
</PageLayout>
<script>
@ -131,79 +101,6 @@ const { headings } = await post.render()
const observer = new IntersectionObserver(callback)
observer.observe(targetHeader)
// Image preview functionality
const imageModal = document.getElementById('image-modal')
const modalImage = document.getElementById('modal-image') as HTMLImageElement
const modalContainer = document.getElementById('modal-container')
function openModal() {
if (imageModal) {
imageModal.classList.remove('opacity-0', 'pointer-events-none')
modalImage.style.transform = 'scale(1)'
isZoomed = false
document.body.style.overflow = 'hidden'
}
}
function closeModal() {
if (imageModal) {
imageModal.classList.add('opacity-0', 'pointer-events-none')
modalImage.src = ''
modalImage.alt = ''
modalImage.style.transform = 'scale(1)'
isZoomed = false
document.body.style.overflow = ''
}
}
document.addEventListener('click', (e) => {
const target = e.target as HTMLElement
if (target.tagName === 'IMG' && target.closest('.prose')) {
const img = target as HTMLImageElement
modalImage.src = img.src
modalImage.alt = img.alt
openModal()
}
})
// 处理点击事件
if (imageModal) {
imageModal.addEventListener('click', (e) => {
const clickedElement = e.target as HTMLElement
// 如果点击的是 modal 背景或 modal-container不是图片和关闭按钮
if (clickedElement === imageModal || clickedElement === modalContainer) {
closeModal()
}
})
}
// 关闭按钮事件
const closeButton = document.getElementById('close-modal')
if (closeButton) {
closeButton.addEventListener('click', closeModal)
}
// ESC 键关闭
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && imageModal && !imageModal.classList.contains('opacity-0')) {
closeModal()
}
})
// 图片缩放功能
let isZoomed = false
modalImage.addEventListener('click', (e) => {
e.stopPropagation() // 阻止事件冒泡到 modal
if (isZoomed) {
modalImage.style.transform = 'scale(1)'
modalImage.classList.remove('zoomed')
} else {
modalImage.style.transform = 'scale(1.5)'
modalImage.classList.add('zoomed')
}
isZoomed = !isZoomed
})
</script>
<style>