mirror of
https://github.com/Ad-closeNN/blog-fuwari.git
synced 2026-05-31 01:00:04 -04:00
feat: 编译图片时可以把开头 /public 字段删除
2. feat(component): 查看照片新增打开原图更改 3. fix(component): 修复查看图片时放大图片按钮失效的问题
This commit is contained in:
+3
-1
@@ -30,4 +30,6 @@ src/content/.obsidian
|
|||||||
|
|
||||||
.playwright-mcp
|
.playwright-mcp
|
||||||
.serena
|
.serena
|
||||||
.claude
|
.claude
|
||||||
|
|
||||||
|
.obsidian
|
||||||
@@ -21,6 +21,7 @@ import { AdmonitionComponent } from "./src/plugins/rehype-component-admonition.m
|
|||||||
import { GithubCardComponent } from "./src/plugins/rehype-component-github-card.mjs";
|
import { GithubCardComponent } from "./src/plugins/rehype-component-github-card.mjs";
|
||||||
import { parseDirectiveNode } from "./src/plugins/remark-directive-rehype.js";
|
import { parseDirectiveNode } from "./src/plugins/remark-directive-rehype.js";
|
||||||
import { remarkExcerpt } from "./src/plugins/remark-excerpt.js";
|
import { remarkExcerpt } from "./src/plugins/remark-excerpt.js";
|
||||||
|
import { remarkPublicImagePaths } from "./src/plugins/remark-public-image-paths.mjs";
|
||||||
import { remarkReadingTime } from "./src/plugins/remark-reading-time.mjs";
|
import { remarkReadingTime } from "./src/plugins/remark-reading-time.mjs";
|
||||||
import { pluginCustomCopyButton } from "./src/plugins/expressive-code/custom-copy-button.js";
|
import { pluginCustomCopyButton } from "./src/plugins/expressive-code/custom-copy-button.js";
|
||||||
import rehypeExternalLinks from 'rehype-external-links';
|
import rehypeExternalLinks from 'rehype-external-links';
|
||||||
@@ -108,6 +109,7 @@ export default defineConfig({
|
|||||||
remarkMath,
|
remarkMath,
|
||||||
remarkReadingTime,
|
remarkReadingTime,
|
||||||
remarkExcerpt,
|
remarkExcerpt,
|
||||||
|
remarkPublicImagePaths,
|
||||||
remarkGithubAdmonitionsToDirectives,
|
remarkGithubAdmonitionsToDirectives,
|
||||||
remarkDirective,
|
remarkDirective,
|
||||||
remarkSectionize,
|
remarkSectionize,
|
||||||
|
|||||||
@@ -46,9 +46,12 @@ if (isLocal) {
|
|||||||
|
|
||||||
const imageClass = "w-full h-full object-cover";
|
const imageClass = "w-full h-full object-cover";
|
||||||
const imageStyle = `object-position: ${position}`;
|
const imageStyle = `object-position: ${position}`;
|
||||||
|
const originalSrc = isLocal && img ? img.src : isPublic ? url(src) : src;
|
||||||
|
const originalWidth = isLocal && img ? img.width : undefined;
|
||||||
|
const originalHeight = isLocal && img ? img.height : undefined;
|
||||||
---
|
---
|
||||||
<div id={id} class:list={[className, 'overflow-hidden relative']}>
|
<div id={id} class:list={[className, 'overflow-hidden relative']}>
|
||||||
<div class="transition absolute inset-0 dark:bg-black/10 bg-opacity-50 pointer-events-none"></div>
|
<div class="transition absolute inset-0 dark:bg-black/10 bg-opacity-50 pointer-events-none"></div>
|
||||||
{isLocal && img && <Image src={img} alt={alt || ""} class={imageClass} style={imageStyle}/>}
|
{isLocal && img && <Image src={img} alt={alt || ""} class={imageClass} style={imageStyle} data-pswp-src={originalSrc} data-pswp-width={originalWidth} data-pswp-height={originalHeight} data-original-src={originalSrc}/>}
|
||||||
{!isLocal && <img src={isPublic ? url(src) : src} alt={alt || ""} class={imageClass} style={imageStyle}/>}
|
{!isLocal && <img src={originalSrc} alt={alt || ""} class={imageClass} style={imageStyle} data-pswp-src={originalSrc} data-original-src={originalSrc}/>}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Vendored
+6
@@ -11,6 +11,12 @@ type SwupLike = {
|
|||||||
type BlogPhotoSwipeState = {
|
type BlogPhotoSwipeState = {
|
||||||
lightbox: {
|
lightbox: {
|
||||||
destroy: () => void;
|
destroy: () => void;
|
||||||
|
on: (eventName: string, handler: (...args: unknown[]) => void) => void;
|
||||||
|
pswp?: {
|
||||||
|
ui?: {
|
||||||
|
registerElement: (options: Record<string, unknown>) => void;
|
||||||
|
};
|
||||||
|
};
|
||||||
} | null;
|
} | null;
|
||||||
hookRegistered: boolean;
|
hookRegistered: boolean;
|
||||||
pageLoadRegistered: boolean;
|
pageLoadRegistered: boolean;
|
||||||
|
|||||||
@@ -634,6 +634,7 @@ window.onresize = () => {
|
|||||||
<script>
|
<script>
|
||||||
import PhotoSwipeLightbox from "photoswipe/lightbox"
|
import PhotoSwipeLightbox from "photoswipe/lightbox"
|
||||||
import "photoswipe/style.css"
|
import "photoswipe/style.css"
|
||||||
|
import "../styles/photoswipe.css"
|
||||||
|
|
||||||
const zoomTargetSelector = ".custom-md img, #post-cover img"
|
const zoomTargetSelector = ".custom-md img, #post-cover img"
|
||||||
const pswpModule = import("photoswipe")
|
const pswpModule = import("photoswipe")
|
||||||
@@ -662,6 +663,7 @@ function createPhotoSwipe() {
|
|||||||
const lightbox = new PhotoSwipeLightbox({
|
const lightbox = new PhotoSwipeLightbox({
|
||||||
gallery: "body",
|
gallery: "body",
|
||||||
children: zoomTargetSelector,
|
children: zoomTargetSelector,
|
||||||
|
initialZoomLevel: "fit",
|
||||||
pswpModule: () => pswpModule,
|
pswpModule: () => pswpModule,
|
||||||
closeSVG: '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#ffffff"><path d="M480-424 284-228q-11 11-28 11t-28-11q-11-11-11-28t11-28l196-196-196-196q-11-11-11-28t11-28q11-11 28-11t28 11l196 196 196-196q11-11 28-11t28 11q11 11 11 28t-11 28L536-480l196 196q11 11 11 28t-11 28q-11 11-28 11t-28-11L480-424Z"/></svg>',
|
closeSVG: '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#ffffff"><path d="M480-424 284-228q-11 11-28 11t-28-11q-11-11-11-28t11-28l196-196-196-196q-11-11-11-28t11-28q11-11 28-11t28 11l196 196 196-196q11-11 28-11t28 11q11 11 11 28t-11 28L536-480l196 196q11 11 11 28t-11 28q-11 11-28 11t-28-11L480-424Z"/></svg>',
|
||||||
zoomSVG: '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#ffffff"><path d="M340-540h-40q-17 0-28.5-11.5T260-580q0-17 11.5-28.5T300-620h40v-40q0-17 11.5-28.5T380-700q17 0 28.5 11.5T420-660v40h40q17 0 28.5 11.5T500-580q0 17-11.5 28.5T460-540h-40v40q0 17-11.5 28.5T380-460q-17 0-28.5-11.5T340-500v-40Zm40 220q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l224 224q11 11 11 28t-11 28q-11 11-28 11t-28-11L532-372q-30 24-69 38t-83 14Zm0-80q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z"/></svg>',
|
zoomSVG: '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#ffffff"><path d="M340-540h-40q-17 0-28.5-11.5T260-580q0-17 11.5-28.5T300-620h40v-40q0-17 11.5-28.5T380-700q17 0 28.5 11.5T420-660v40h40q17 0 28.5 11.5T500-580q0 17-11.5 28.5T460-540h-40v40q0 17-11.5 28.5T380-460q-17 0-28.5-11.5T340-500v-40Zm40 220q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l224 224q11 11 11 28t-11 28q-11 11-28 11t-28-11L532-372q-30 24-69 38t-83 14Zm0-80q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z"/></svg>',
|
||||||
@@ -669,6 +671,7 @@ function createPhotoSwipe() {
|
|||||||
showHideAnimationType: "fade",
|
showHideAnimationType: "fade",
|
||||||
showAnimationDuration: 160,
|
showAnimationDuration: 160,
|
||||||
hideAnimationDuration: 140,
|
hideAnimationDuration: 140,
|
||||||
|
secondaryZoomLevel: (zoomLevel) => Math.min(2.5, zoomLevel.max),
|
||||||
wheelToZoom: true,
|
wheelToZoom: true,
|
||||||
arrowPrev: false,
|
arrowPrev: false,
|
||||||
arrowNext: false,
|
arrowNext: false,
|
||||||
@@ -679,19 +682,69 @@ function createPhotoSwipe() {
|
|||||||
|
|
||||||
lightbox.addFilter("domItemData", (itemData, element) => {
|
lightbox.addFilter("domItemData", (itemData, element) => {
|
||||||
if (element instanceof HTMLImageElement) {
|
if (element instanceof HTMLImageElement) {
|
||||||
const width = element.naturalWidth || element.width || window.innerWidth
|
const fullSrc = element.dataset.pswpSrc || element.currentSrc || element.src
|
||||||
const height = element.naturalHeight || element.height || window.innerHeight
|
const width = Number(element.dataset.pswpWidth) || element.naturalWidth || element.width || window.innerWidth
|
||||||
const src = element.currentSrc || element.src
|
const height = Number(element.dataset.pswpHeight) || element.naturalHeight || element.height || window.innerHeight
|
||||||
|
const thumbSrc = element.currentSrc || element.src
|
||||||
|
const sourceElement = element.closest(zoomTargetSelector)
|
||||||
|
const allImages = getZoomTargets()
|
||||||
|
const index = sourceElement instanceof HTMLImageElement ? allImages.indexOf(sourceElement) : -1
|
||||||
|
|
||||||
itemData.src = src
|
itemData.src = fullSrc
|
||||||
itemData.w = Number(width)
|
itemData.w = Number(width)
|
||||||
itemData.h = Number(height)
|
itemData.h = Number(height)
|
||||||
itemData.msrc = src
|
itemData.msrc = thumbSrc
|
||||||
|
if (index >= 0) {
|
||||||
|
itemData.element = sourceElement
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return itemData
|
return itemData
|
||||||
})
|
})
|
||||||
|
|
||||||
|
lightbox.addFilter("clickedIndex", (clickedIndex, event) => {
|
||||||
|
const target = event.target instanceof Element ? event.target.closest(zoomTargetSelector) : null
|
||||||
|
if (!(target instanceof HTMLImageElement)) {
|
||||||
|
return clickedIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
const allImages = getZoomTargets()
|
||||||
|
const index = allImages.indexOf(target)
|
||||||
|
return index >= 0 ? index : clickedIndex
|
||||||
|
})
|
||||||
|
|
||||||
|
lightbox.on("uiRegister", () => {
|
||||||
|
lightbox.pswp?.ui?.registerElement({
|
||||||
|
name: "open-link",
|
||||||
|
order: 8,
|
||||||
|
isButton: true,
|
||||||
|
tagName: "a",
|
||||||
|
className: "pswp__button pswp__button--open-link",
|
||||||
|
title: "打开原图",
|
||||||
|
html: '<svg class="pswp__icn" viewBox="0 0 24 24" aria-hidden="true"><path d="M14 3h7v7h-2V6.41l-9.29 9.3-1.42-1.42 9.3-9.29H14V3Zm5 16V11h2v10H3V3h10v2H5v14h14Z"/></svg>',
|
||||||
|
onInit: (el, pswp) => {
|
||||||
|
if (!(el instanceof HTMLAnchorElement)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
el.target = "_blank"
|
||||||
|
el.rel = "noreferrer noopener"
|
||||||
|
|
||||||
|
const syncHref = () => {
|
||||||
|
const currSlide = pswp.currSlide
|
||||||
|
const link = typeof currSlide?.data?.src === "string" ? currSlide.data.src : ""
|
||||||
|
el.href = link
|
||||||
|
el.classList.toggle("pswp__button--disabled", !link)
|
||||||
|
el.setAttribute("aria-disabled", link ? "false" : "true")
|
||||||
|
el.tabIndex = link ? 0 : -1
|
||||||
|
}
|
||||||
|
|
||||||
|
pswp.on("change", syncHref)
|
||||||
|
syncHref()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
lightbox.init()
|
lightbox.init()
|
||||||
photoSwipeState.lightbox = lightbox
|
photoSwipeState.lightbox = lightbox
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { visit } from "unist-util-visit";
|
||||||
|
|
||||||
|
function rewritePublicPath(url) {
|
||||||
|
if (typeof url !== "string") {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url === "/public") {
|
||||||
|
return "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url.startsWith("/public/")) {
|
||||||
|
return url.slice("/public".length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function remarkPublicImagePaths() {
|
||||||
|
return (tree) => {
|
||||||
|
visit(tree, "image", (node) => {
|
||||||
|
node.url = rewritePublicPath(node.url);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,12 +1,37 @@
|
|||||||
.pswp__button {
|
.pswp__button {
|
||||||
@apply transition bg-black/40 hover:bg-black/50 active:bg-black/60 flex items-center justify-center mr-0 w-12 h-12 !important;
|
@apply transition bg-black/40 hover:bg-black/50 active:bg-black/60 flex items-center justify-center mr-0 w-12 h-12 !important;
|
||||||
}
|
}
|
||||||
.pswp__button--zoom, .pswp__button--close {
|
.pswp__button--zoom, .pswp__button--open-link, .pswp__button--close {
|
||||||
@apply mt-4 rounded-xl active:scale-90 !important;
|
@apply mt-4 rounded-xl active:scale-90 !important;
|
||||||
}
|
}
|
||||||
.pswp__button--zoom {
|
.pswp__button--zoom, .pswp__button--open-link {
|
||||||
@apply mr-2.5 !important;
|
@apply mr-2.5 !important;
|
||||||
}
|
}
|
||||||
|
.pswp__button--open-link {
|
||||||
|
@apply no-underline !important;
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
.pswp__button--close {
|
.pswp__button--close {
|
||||||
@apply mr-4 !important;
|
@apply mr-4 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pswp__button--disabled {
|
||||||
|
@apply opacity-40 pointer-events-none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pswp__icn {
|
||||||
|
@apply fill-white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pswp__icn-shadow {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pswp__button--open-link .pswp__icn {
|
||||||
|
width: 24px !important;
|
||||||
|
height: 24px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pswp__button--open-link .pswp__icn path {
|
||||||
|
fill: currentColor !important;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user