From 94471c4c895d5661d2c094335f49cead73ce5b06 Mon Sep 17 00:00:00 2001 From: zqlit Date: Sun, 24 May 2026 13:37:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=BB=E9=A2=98=E5=8A=A8?= =?UTF-8?q?=E7=94=BB=E6=8E=89=E5=B8=A7=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../index.md | 8 +-- themes/Ying/assets/css/main.css | 56 +++++++++++++++++-- themes/Ying/layouts/shortcodes/grid.html | 4 ++ write/src/components/ShortcutPanel.tsx | 26 ++++++++- 4 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 themes/Ying/layouts/shortcodes/grid.html diff --git a/content/post/2021/2021-12-22-放假之前最后一次的照片合集,再见啦!理工/index.md b/content/post/2021/2021-12-22-放假之前最后一次的照片合集,再见啦!理工/index.md index 1fd51ba1..26769fb1 100644 --- a/content/post/2021/2021-12-22-放假之前最后一次的照片合集,再见啦!理工/index.md +++ b/content/post/2021/2021-12-22-放假之前最后一次的照片合集,再见啦!理工/index.md @@ -24,17 +24,17 @@ ai_comment: >- --- +{{< grid cols="3" >}} ![74854-tf6ncx2nrr.png](2764401068.png) - ![62240-spcby0sdo7.png](4275984327.png) - ![62909-pacjkrxfi99.png](1156075190.png) +{{< /grid >}} +{{< grid cols="3" >}} ![65458-7jlq1z1b5yc.png](2184315093.png) - ![49621-vx4ekvnrb2.png](2457603522.png) - ![34327-y2zcf7dsot.png](1690557256.png) +{{< /grid >}} ![93598-t0ytoep9l8c.png](1113265311.png) diff --git a/themes/Ying/assets/css/main.css b/themes/Ying/assets/css/main.css index 62b99259..a4734212 100644 --- a/themes/Ying/assets/css/main.css +++ b/themes/Ying/assets/css/main.css @@ -2990,8 +2990,6 @@ input[type=submit] { display: block; max-width: 100%; height: auto; - content-visibility: auto; - contain-intrinsic-size: 700px auto; } .post-content .sen-image-frame, @@ -3006,6 +3004,8 @@ input[type=submit] { transform: translateY(14px); transition: opacity 0.6s cubic-bezier(0.22, 0.61, 0.36, 1), transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1); + content-visibility: auto; + contain-intrinsic-size: auto 400px; } .post-content .sen-image-frame.is-visible, @@ -3046,15 +3046,16 @@ input[type=submit] { text-overflow: ellipsis; pointer-events: none; opacity: 0; - transform: translateY(4px); + transform: translateY(4px) translateZ(0); transition: opacity 0.4s 0.2s cubic-bezier(0.22, 0.61, 0.36, 1), transform 0.4s 0.2s cubic-bezier(0.22, 0.61, 0.36, 1); + will-change: transform, opacity; } .post-content .sen-image-frame.is-visible[data-title]::after, .entry-content .sen-image-frame.is-visible[data-title]::after { opacity: 1; - transform: translateY(0); + transform: translateY(0) translateZ(0); } [data-theme="dark"] .post-content .sen-image-frame[data-title]::after, @@ -3688,6 +3689,53 @@ input[type=submit] { } } +/* ── Image Grid ── */ +.img-grid { + display: grid; + gap: 4px; + margin: 0.6rem 0; +} + +.img-grid.cols-2 { grid-template-columns: repeat(2, 1fr); } +.img-grid.cols-3 { grid-template-columns: repeat(3, 1fr); } +.img-grid.cols-4 { grid-template-columns: repeat(4, 1fr); } + +/* Penetrate Markdown

wrappers so images become grid items */ +.img-grid > p { + display: contents; +} + +.img-grid .sen-image-frame { + margin: 0; + aspect-ratio: 1 / 1; + width: 100%; + max-width: 100%; + height: 100%; + overflow: hidden; + border-radius: 4px; +} + +.img-grid .sen-image-frame > img { + width: 100%; + height: 100%; + max-width: 100%; + object-fit: cover; + border-radius: 4px; +} + +/* Suppress title overlay inside grids */ +.img-grid .sen-image-frame[data-title]::after { + display: none; +} + +/* Mobile: reduce to 2 columns */ +@media screen and (max-width: 480px) { + .img-grid.cols-3, + .img-grid.cols-4 { + grid-template-columns: repeat(2, 1fr); + } +} + .floating-tools a { width: 40px; height: 40px; diff --git a/themes/Ying/layouts/shortcodes/grid.html b/themes/Ying/layouts/shortcodes/grid.html new file mode 100644 index 00000000..c509d46c --- /dev/null +++ b/themes/Ying/layouts/shortcodes/grid.html @@ -0,0 +1,4 @@ +{{ $cols := .Get "cols" | default "3" }} +

+ {{ .Inner | $.Page.RenderString (dict "display" "block") }} +
diff --git a/write/src/components/ShortcutPanel.tsx b/write/src/components/ShortcutPanel.tsx index 33f3d2b7..ef0fa65c 100644 --- a/write/src/components/ShortcutPanel.tsx +++ b/write/src/components/ShortcutPanel.tsx @@ -1,7 +1,7 @@ "use client"; import { RefObject } from "react"; -import { Heading2, Heading3, Code, Quote, Image, Link, Minus, Bold, FileCode } from "lucide-react"; +import { Heading2, Heading3, Code, Quote, Image, Link, Minus, Bold, FileCode, Grid3X3 } from "lucide-react"; interface ShortcutPanelProps { textareaRef: RefObject; @@ -28,6 +28,29 @@ export default function ShortcutPanel({ textareaRef, value, onChange }: Shortcut }, 0); }; + const insertBlock = (template: string) => { + const el = textareaRef.current; + if (!el) { + onChange(value + template); + return; + } + const start = el.selectionStart; + const newVal = value.slice(0, start) + template + value.slice(start); + onChange(newVal); + setTimeout(() => { + el.selectionStart = start + template.length; + el.selectionEnd = start + template.length; + el.focus(); + }, 0); + }; + + const gridTemplate = `{{< grid cols="3" >}} +![描述]() +![描述]() +![描述]() +{{< /grid >}} +`; + const shortcuts = [ { label: "H2", icon: Heading2, action: () => insert("## ", "\n", "二级标题") }, { label: "H3", icon: Heading3, action: () => insert("### ", "\n", "三级标题") }, @@ -36,6 +59,7 @@ export default function ShortcutPanel({ textareaRef, value, onChange }: Shortcut { label: "行内代码", icon: Code, action: () => insert("`", "`", "code") }, { label: "引用", icon: Quote, action: () => insert("> ", "\n", "引用内容") }, { label: "图片", icon: Image, action: () => insert("![", "]()", "描述") }, + { label: "图片网格", icon: Grid3X3, action: () => insertBlock(gridTemplate) }, { label: "链接", icon: Link, action: () => insert("[", "]()", "链接文本") }, { label: "分割线", icon: Minus, action: () => insert("\n---\n", "", "") }, ];