From a1b8cbd7382901ee4ffe83efa67358e2c2eb527f Mon Sep 17 00:00:00 2001 From: butubb <1422726308@qq.com> Date: Thu, 7 May 2026 15:26:46 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=9B=BE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/css/extended/gallery.css | 303 ++++++++++++++++++++++++++++++ assets/js/gallery.js | 102 ++++++++++ content/gallery/2024-01.md | 6 + content/gallery/_index.md | 4 + hugo.toml | 10 +- layouts/gallery/list.html | 75 ++++++++ layouts/partials/extend_head.html | 9 + 7 files changed, 506 insertions(+), 3 deletions(-) create mode 100644 assets/css/extended/gallery.css create mode 100644 assets/js/gallery.js create mode 100644 content/gallery/2024-01.md create mode 100644 content/gallery/_index.md create mode 100644 layouts/gallery/list.html create mode 100644 layouts/partials/extend_head.html diff --git a/assets/css/extended/gallery.css b/assets/css/extended/gallery.css new file mode 100644 index 0000000..2b55170 --- /dev/null +++ b/assets/css/extended/gallery.css @@ -0,0 +1,303 @@ +/* ======================================== + Gallery — PaperMod Design Language + ======================================== */ + +/* ---------- Page Layout ---------- */ +/* Widen the main container for gallery pages */ +.main:has(.gallery-page-content) { + max-width: calc(var(--nav-width) + var(--gap) * 2); +} + +.gallery-page-content { + max-width: 100%; +} + +/* ---------- Album Section ---------- */ +.gallery-album { + background: var(--entry); + border: 1px solid var(--border); + border-radius: var(--radius); + padding: var(--gap); + margin-bottom: var(--gap); + transition: transform 0.1s; +} + +.gallery-album:active { + transform: scale(0.99); +} + +.gallery-album-header { + display: flex; + align-items: baseline; + gap: 8px; + margin-bottom: 4px; +} + +.gallery-album-title { + font-size: 24px; + font-weight: 600; + color: var(--primary); + line-height: 1.3; +} + +.gallery-album-count { + font-size: 13px; + color: var(--secondary); + flex-shrink: 0; +} + +.gallery-album-desc { + color: var(--secondary); + font-size: 14px; + line-height: 1.6; + margin-bottom: var(--content-gap); +} + +/* ---------- Image Grid ---------- */ +.gallery-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + gap: calc(var(--content-gap) * 0.5); +} + +.gallery-card { + position: relative; + border-radius: var(--radius); + overflow: hidden; + cursor: pointer; + background: var(--code-bg); + border: 1px solid var(--border); + transition: transform 0.1s; +} + +[data-theme="dark"] .gallery-card { + background: var(--tertiary); +} + +.gallery-card:active { + transform: scale(0.96); +} + +.gallery-card-img { + aspect-ratio: 1; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; +} + +.gallery-card-img img { + width: 100%; + height: 100%; + object-fit: cover; + transition: transform 0.3s ease; +} + +.gallery-card:hover .gallery-card-img img { + transform: scale(1.05); +} + +.gallery-card::after { + content: ''; + position: absolute; + inset: 0; + background: rgba(0, 0, 0, 0); + transition: background 0.2s ease; + pointer-events: none; + border-radius: inherit; +} + +.gallery-card:hover::after { + background: rgba(0, 0, 0, 0.08); +} + +[data-theme="dark"] .gallery-card:hover::after { + background: rgba(0, 0, 0, 0.2); +} + +/* ---------- Empty State ---------- */ +.gallery-empty { + text-align: center; + padding: calc(var(--gap) * 3) 0; + color: var(--secondary); +} + +.gallery-empty svg { + margin: 0 auto var(--gap); + opacity: 0.4; +} + +.gallery-empty p { + font-size: 16px; +} + +/* ---------- Lightbox ---------- */ +.lightbox { + position: fixed; + inset: 0; + z-index: 9999; + display: flex; + align-items: center; + justify-content: center; + opacity: 0; + visibility: hidden; + transition: opacity 0.25s ease, visibility 0.25s ease; +} + +.lightbox.active { + opacity: 1; + visibility: visible; +} + +.lightbox-backdrop { + position: absolute; + inset: 0; + background: rgba(0, 0, 0, 0.85); + -webkit-backdrop-filter: blur(8px); + backdrop-filter: blur(8px); +} + +[data-theme="dark"] .lightbox-backdrop { + background: rgba(0, 0, 0, 0.92); +} + +.lightbox-body { + position: relative; + max-width: 92vw; + max-height: 88vh; + z-index: 1; +} + +.lightbox-body img { + max-width: 92vw; + max-height: 88vh; + object-fit: contain; + border-radius: var(--radius); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); +} + +/* Lightbox Buttons */ +.lightbox-btn { + position: absolute; + z-index: 2; + background: rgba(255, 255, 255, 0.12); + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 50%; + width: 44px; + height: 44px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + color: white; + transition: background 0.2s, transform 0.1s; + -webkit-backdrop-filter: blur(4px); + backdrop-filter: blur(4px); + padding: 0; +} + +.lightbox-btn:hover { + background: rgba(255, 255, 255, 0.22); +} + +.lightbox-btn:active { + transform: scale(0.92); +} + +.lightbox-btn svg { + width: 20px; + height: 20px; +} + +.lightbox-close-btn { + top: 20px; + right: 20px; +} + +.lightbox-prev-btn { + left: 20px; + top: 50%; + transform: translateY(-50%); +} + +.lightbox-prev-btn:active { + transform: translateY(-50%) scale(0.92); +} + +.lightbox-next-btn { + right: 20px; + top: 50%; + transform: translateY(-50%); +} + +.lightbox-next-btn:active { + transform: translateY(-50%) scale(0.92); +} + +.lightbox-counter { + position: absolute; + bottom: 20px; + left: 50%; + transform: translateX(-50%); + z-index: 2; + color: rgba(255, 255, 255, 0.7); + font-size: 13px; + background: rgba(0, 0, 0, 0.4); + padding: 4px 12px; + border-radius: 20px; + -webkit-backdrop-filter: blur(4px); + backdrop-filter: blur(4px); +} + +/* ---------- Responsive ---------- */ +@media (max-width: 768px) { + :root { + --gap: 14px; + } + + .gallery-grid { + grid-template-columns: repeat(3, 1fr); + gap: 8px; + } + + .gallery-album { + padding: 14px; + } + + .gallery-album-title { + font-size: 20px; + } + + .lightbox-btn { + width: 38px; + height: 38px; + } + + .lightbox-btn svg { + width: 16px; + height: 16px; + } + + .lightbox-prev-btn { + left: 10px; + } + + .lightbox-next-btn { + right: 10px; + } + + .lightbox-close-btn { + top: 10px; + right: 10px; + } +} + +@media (max-width: 480px) { + .gallery-grid { + grid-template-columns: repeat(2, 1fr); + } + + .gallery-album-title { + font-size: 18px; + } +} diff --git a/assets/js/gallery.js b/assets/js/gallery.js new file mode 100644 index 0000000..7084c58 --- /dev/null +++ b/assets/js/gallery.js @@ -0,0 +1,102 @@ +document.addEventListener('DOMContentLoaded', function () { + const lightbox = document.getElementById('lightbox'); + const lightboxImg = document.getElementById('lightbox-img'); + const lightboxClose = document.getElementById('lightbox-close'); + const lightboxPrev = document.getElementById('lightbox-prev'); + const lightboxNext = document.getElementById('lightbox-next'); + const lightboxCounter = document.getElementById('lightbox-counter'); + const lightboxBackdrop = document.getElementById('lightbox-backdrop'); + + const cards = Array.from(document.querySelectorAll('.gallery-card')); + let currentIndex = -1; + + function openLightbox(index) { + if (index < 0 || index >= cards.length) return; + currentIndex = index; + const src = cards[index].dataset.src; + if (!src) return; + lightboxImg.src = src; + lightbox.classList.add('active'); + document.body.style.overflow = 'hidden'; + updateCounter(); + } + + function closeLightbox() { + lightbox.classList.remove('active'); + document.body.style.overflow = ''; + currentIndex = -1; + } + + function showPrev() { + if (currentIndex > 0) { + openLightbox(currentIndex - 1); + } + } + + function showNext() { + if (currentIndex < cards.length - 1) { + openLightbox(currentIndex + 1); + } + } + + function updateCounter() { + if (lightboxCounter) { + lightboxCounter.textContent = (currentIndex + 1) + ' / ' + cards.length; + } + } + + // Click on gallery cards + cards.forEach(function (card, index) { + card.addEventListener('click', function () { + openLightbox(index); + }); + }); + + // Lightbox controls + lightboxClose.addEventListener('click', closeLightbox); + lightboxBackdrop.addEventListener('click', closeLightbox); + lightboxPrev.addEventListener('click', function (e) { + e.stopPropagation(); + showPrev(); + }); + lightboxNext.addEventListener('click', function (e) { + e.stopPropagation(); + showNext(); + }); + + // Keyboard navigation + document.addEventListener('keydown', function (e) { + if (!lightbox.classList.contains('active')) return; + switch (e.key) { + case 'Escape': + closeLightbox(); + break; + case 'ArrowLeft': + showPrev(); + break; + case 'ArrowRight': + showNext(); + break; + } + }); + + // Touch swipe support + var touchStartX = 0; + var touchEndX = 0; + + lightbox.addEventListener('touchstart', function (e) { + touchStartX = e.changedTouches[0].screenX; + }, { passive: true }); + + lightbox.addEventListener('touchend', function (e) { + touchEndX = e.changedTouches[0].screenX; + var diff = touchStartX - touchEndX; + if (Math.abs(diff) > 50) { + if (diff > 0) { + showNext(); + } else { + showPrev(); + } + } + }, { passive: true }); +}); diff --git a/content/gallery/2024-01.md b/content/gallery/2024-01.md new file mode 100644 index 0000000..fbdf9e2 --- /dev/null +++ b/content/gallery/2024-01.md @@ -0,0 +1,6 @@ +--- +title: "跑步记录" +date: 2026-03-09 +--- + +![123](https://cdn.jsdelivr.net/gh/8butubb/image/img/20260309120246636.png) diff --git a/content/gallery/_index.md b/content/gallery/_index.md new file mode 100644 index 0000000..a8cc467 --- /dev/null +++ b/content/gallery/_index.md @@ -0,0 +1,4 @@ +--- +title: "画廊" +description: "记录生活中的美好瞬间" +--- \ No newline at end of file diff --git a/hugo.toml b/hugo.toml index 8ca4e37..91cf913 100644 --- a/hugo.toml +++ b/hugo.toml @@ -7,11 +7,10 @@ defaultContentLanguage = 'zh-cn' [outputs] home = ["HTML", "RSS", "JSON"] -# ===== 新增区域:告诉 Hugo 允许渲染安全的 HTML ===== [markup] [markup.goldmark] [markup.goldmark.renderer] - unsafe = true # 允许在 Markdown 中渲染原始 HTML + unsafe = true [params] [params.homeInfoParams] @@ -47,7 +46,12 @@ defaultContentLanguage = 'zh-cn' url = "/search" weight = 4 +[[menu.main]] + name = "画廊" + url = "/gallery" + weight = 5 + [[menu.main]] name = "Run" url = "https://run.butubb.cn" - weight = 5 \ No newline at end of file + weight = 6 \ No newline at end of file diff --git a/layouts/gallery/list.html b/layouts/gallery/list.html new file mode 100644 index 0000000..3c491f4 --- /dev/null +++ b/layouts/gallery/list.html @@ -0,0 +1,75 @@ +{{- define "main" -}} + +{{- if .Title }} + +{{- end }} + + + + + +{{- end -}} diff --git a/layouts/partials/extend_head.html b/layouts/partials/extend_head.html new file mode 100644 index 0000000..6eaa818 --- /dev/null +++ b/layouts/partials/extend_head.html @@ -0,0 +1,9 @@ +{{- if eq .Type "gallery" }} +{{- $galleryJS := resources.Get "js/gallery.js" | minify }} +{{- if not site.Params.assets.disableFingerprinting }} +{{- $galleryJS = $galleryJS | fingerprint }} + +{{- else }} + +{{- end }} +{{- end }}