Enhance BlogPost layout with image modal functionality; add astro-link-preview integration and update dependencies

This commit is contained in:
KazooTTT
2025-01-19 21:39:04 +08:00
parent b9307d4a41
commit 8c1fbba215
4 changed files with 5843 additions and 4213 deletions

View File

@ -10,6 +10,7 @@ import { expressiveCodeOptions } from './src/site.config'
import icon from 'astro-icon' import icon from 'astro-icon'
import react from '@astrojs/react' import react from '@astrojs/react'
import cloudflare from '@astrojs/cloudflare' import cloudflare from '@astrojs/cloudflare'
import linkPreview from 'astro-link-preview'
// https://astro.build/config // https://astro.build/config
export default defineConfig({ export default defineConfig({
@ -60,7 +61,8 @@ export default defineConfig({
local: './src/icons/*.svg' local: './src/icons/*.svg'
} }
}), }),
react() react(),
linkPreview()
], ],
markdown: { markdown: {
remarkPlugins: [remarkUnwrapImages, remarkReadingTime], remarkPlugins: [remarkUnwrapImages, remarkReadingTime],

View File

@ -32,6 +32,7 @@
"astro": "^4.4.15", "astro": "^4.4.15",
"astro-expressive-code": "^0.33.5", "astro-expressive-code": "^0.33.5",
"astro-icon": "^1.1.0", "astro-icon": "^1.1.0",
"astro-link-preview": "^0.3.4",
"axios": "^1.7.7", "axios": "^1.7.7",
"clsx": "^2.1.0", "clsx": "^2.1.0",
"fast-xml-parser": "^4.5.0", "fast-xml-parser": "^4.5.0",

9962
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -96,6 +96,24 @@ const { headings } = await post.render()
<path d='M4.5 15.75l7.5-7.5 7.5 7.5' stroke-linecap='round' stroke-linejoin='round'></path> <path d='M4.5 15.75l7.5-7.5 7.5 7.5' stroke-linecap='round' stroke-linejoin='round'></path>
</svg> </svg>
</button> </button>
<div id='image-modal' class='modal'>
<span class='close'>
<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>
</span>
<img class='modal-content' id='modal-image' />
</div>
</div> </div>
</PageLayout> </PageLayout>
@ -116,32 +134,67 @@ const { headings } = await post.render()
const observer = new IntersectionObserver(callback) const observer = new IntersectionObserver(callback)
observer.observe(targetHeader) observer.observe(targetHeader)
const modal = document.getElementById('image-modal')
const modalImg = document.getElementById('modal-image') as HTMLImageElement
const images = document.querySelectorAll('#blog-gallery img') as NodeListOf<HTMLImageElement>
images.forEach(function (img) {
img.style.cursor = 'pointer'
img.addEventListener('click', () => {
if (modal && modalImg) {
modal.style.display = 'flex'
document.body.style.overflow = 'hidden'
modalImg.src = img.src
}
})
})
const span = document.getElementsByClassName('close')[0]
span?.addEventListener('click', () => {
if (modal) {
modal.style.display = 'none'
document.body.style.overflow = 'auto'
}
})
</script> </script>
<style> <style>
#image-modal { .modal {
transition: opacity 300ms ease-in-out; display: none;
position: fixed;
z-index: 100;
margin: auto;
padding: 50px;
inset: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.9);
align-items: center;
justify-content: center;
} }
#modal-image { .modal-content {
transition: transform 300ms ease-in-out; margin: auto;
cursor: zoom-in; display: block;
width: 80%;
} }
#modal-image.zoomed { .close {
cursor: zoom-out; position: fixed;
top: 15px;
right: 35px;
color: #f1f1f1;
font-size: 40px;
font-weight: bold;
transition: 0.3s;
} }
#close-modal { .close:hover,
opacity: 0.7; .close:focus {
transition: opacity 300ms ease-in-out; color: #bbb;
} text-decoration: none;
cursor: pointer;
#close-modal:hover {
opacity: 1;
}
body.modal-open {
overflow: hidden;
} }
</style> </style>