From ca1801e1a7468c2e3a87913e3cd97b4a0ddca86f Mon Sep 17 00:00:00 2001 From: hypercross Date: Fri, 27 Feb 2026 00:27:04 +0800 Subject: [PATCH] refactor: md-pins --- src/components/index.ts | 3 +- src/components/md-pin.tsx | 125 ------------------ .../{md-pin-editor.tsx => md-pins.tsx} | 4 +- 3 files changed, 3 insertions(+), 129 deletions(-) delete mode 100644 src/components/md-pin.tsx rename src/components/{md-pin-editor.tsx => md-pins.tsx} (97%) diff --git a/src/components/index.ts b/src/components/index.ts index bfe2764..053c55b 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -2,8 +2,7 @@ import './dice'; import './table'; import './md-link'; -import './md-pin'; -import './md-pin-editor'; +import './md-pins'; // 导出组件 export { Article } from './Article'; diff --git a/src/components/md-pin.tsx b/src/components/md-pin.tsx deleted file mode 100644 index 4000018..0000000 --- a/src/components/md-pin.tsx +++ /dev/null @@ -1,125 +0,0 @@ -import { customElement, noShadowDOM } from "solid-element"; -import { createSignal, onMount, onCleanup, Show } from "solid-js"; - -customElement("md-pin", { x: 0, y: 0 }, (props, { element }) => { - noShadowDOM(); - - const [position, setPosition] = createSignal<{ top: string; left: string }>({ top: "0", left: "0" }); - const [visible, setVisible] = createSignal(false); - const [transformStyle, setTransformStyle] = createSignal(""); - let pinContainer: HTMLSpanElement | undefined; - let targetImage: HTMLImageElement | undefined; - let resizeObserver: ResizeObserver | undefined; - - // 从 element 的 textContent 获取 pin 标签内容 - const label = element?.textContent?.trim() || ""; - - // 隐藏原始文本内容 - if (element) { - element.textContent = ""; - } - - // 查找上方最近的图片 - const findNearestImage = (): HTMLImageElement | null => { - if (!element) return null; - - // 从当前元素向上查找 - let current: Element | null = element; - while (current) { - // 在当前元素的之前兄弟节点中查找图片 - let sibling: Element | null = current.previousElementSibling; - while (sibling) { - // 检查是否是图片元素 - const img = sibling.querySelector('img'); - if (img) return img; - - // 检查元素本身是否有图片相关的类或标签 - if (sibling.tagName === 'IMG') return sibling as HTMLImageElement; - - sibling = sibling.previousElementSibling; - } - current = current.parentElement; - } - - return null; - }; - - // 更新 pin 位置和容器样式 - const updatePosition = () => { - if (!targetImage || !pinContainer) return; - - const imgRect = targetImage.getBoundingClientRect(); - const containerRect = pinContainer.parentElement.getBoundingClientRect(); - - // 计算图片左上角相对于容器原始位置的偏移 - const offsetX = imgRect.left - containerRect.left; - const offsetY = imgRect.top - containerRect.top; - - // 使用 transform 将容器移动到图片位置 - setTransformStyle(`translate(${offsetX}px, ${offsetY}px)`); - - // 计算 pin 在图片内的相对位置(x/y 是百分比) - const x = typeof props.x === 'number' ? props.x : parseFloat(props.x) || 0; - const y = typeof props.y === 'number' ? props.y : parseFloat(props.y) || 0; - - const left = (x / 100) * imgRect.width; - const top = (y / 100) * imgRect.height; - - setPosition({ - left: `${left}px`, - top: `${top}px` - }); - }; - - onMount(() => { - // 查找目标图片 - targetImage = findNearestImage(); - - if (targetImage) { - // 初始定位 - updatePosition(); - - // 使用 ResizeObserver 监听图片大小变化 - resizeObserver = new ResizeObserver(() => { - updatePosition(); - }); - resizeObserver.observe(targetImage); - - // 延迟显示以等待位置计算完成 - requestAnimationFrame(() => { - setVisible(true); - }); - } else { - console.warn('md-pin: 未找到目标图片'); - } - }); - - onCleanup(() => { - if (resizeObserver && targetImage) { - resizeObserver.unobserve(targetImage); - } - }); - - return ( -
- - - {label || '📍'} - - -
- ); -}); diff --git a/src/components/md-pin-editor.tsx b/src/components/md-pins.tsx similarity index 97% rename from src/components/md-pin-editor.tsx rename to src/components/md-pins.tsx index 512ad59..0dfeba8 100644 --- a/src/components/md-pin-editor.tsx +++ b/src/components/md-pins.tsx @@ -63,7 +63,7 @@ function findNextUnusedLabel(pins: Pin[]): string { return generateLabel(pins.length); } -customElement("md-pin-editor", { pins: "", fixed: false }, (props, { element }) => { +customElement("md-pins", { pins: "", fixed: false }, (props, { element }) => { noShadowDOM(); const [pins, setPins] = createSignal([]); @@ -139,7 +139,7 @@ customElement("md-pin-editor", { pins: "", fixed: false }, (props, { element }) // 复制所有 pin 为 :md-editor-pin 格式 const copyPins = () => { const pinsStr = formatPins(pins()); - const text = `:md-pin-editor[${rawSrc}]{pins="${pinsStr}" fixed}`; + const text = `:md-pins[${rawSrc}]{pins="${pinsStr}" fixed}`; navigator.clipboard.writeText(text).then(() => { setShowToast(true);