feat: md-pin
This commit is contained in:
parent
f7eb116aa3
commit
4c3d83922f
|
|
@ -13,6 +13,8 @@ customElement("md-pin", { x: 0, y: 0 }, (props, { element }) => {
|
||||||
width: "0",
|
width: "0",
|
||||||
height: "0"
|
height: "0"
|
||||||
});
|
});
|
||||||
|
const [showToast, setShowToast] = createSignal(false);
|
||||||
|
const [toastMessage, setToastMessage] = createSignal("");
|
||||||
let pinContainer: HTMLSpanElement | undefined;
|
let pinContainer: HTMLSpanElement | undefined;
|
||||||
let targetImage: HTMLImageElement | undefined;
|
let targetImage: HTMLImageElement | undefined;
|
||||||
let resizeObserver: ResizeObserver | undefined;
|
let resizeObserver: ResizeObserver | undefined;
|
||||||
|
|
@ -124,23 +126,63 @@ customElement("md-pin", { x: 0, y: 0 }, (props, { element }) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 处理点击,报告坐标并复制到剪贴板
|
||||||
|
const handleClick = (e: MouseEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
if (!targetImage) return;
|
||||||
|
|
||||||
|
const imgRect = targetImage.getBoundingClientRect();
|
||||||
|
|
||||||
|
// 计算点击位置相对于图片的百分比
|
||||||
|
const clickX = ((e.clientX - imgRect.left) / imgRect.width) * 100;
|
||||||
|
const clickY = ((e.clientY - imgRect.top) / imgRect.height) * 100;
|
||||||
|
|
||||||
|
// 四舍五入到整数
|
||||||
|
const x = Math.round(clickX);
|
||||||
|
const y = Math.round(clickY);
|
||||||
|
|
||||||
|
// 生成格式化的坐标字符串
|
||||||
|
const coordText = `:md-pin[${label || ''}]{x=${x} y=${y}}`;
|
||||||
|
|
||||||
|
// 复制到剪贴板
|
||||||
|
navigator.clipboard.writeText(coordText).then(() => {
|
||||||
|
setToastMessage(`已复制:${coordText}`);
|
||||||
|
setShowToast(true);
|
||||||
|
setTimeout(() => setShowToast(false), 2000);
|
||||||
|
}).catch(err => {
|
||||||
|
console.error('复制失败:', err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span ref={pinContainer} class="md-pin-container" style={{ display: 'inline', position: containerStyle().position, top: containerStyle().top, left: containerStyle().left, width: containerStyle().width, height: containerStyle().height }}>
|
<span
|
||||||
|
ref={pinContainer}
|
||||||
|
class="md-pin-container"
|
||||||
|
style={{ display: 'inline', position: containerStyle().position, top: containerStyle().top, left: containerStyle().left, width: containerStyle().width, height: containerStyle().height }}
|
||||||
|
onClick={handleClick}
|
||||||
|
>
|
||||||
<Show when={visible() && targetImage}>
|
<Show when={visible() && targetImage}>
|
||||||
<span
|
<span
|
||||||
class="md-pin absolute transform -translate-x-1/2 -translate-y-1/2 pointer-events-auto cursor-pointer
|
class="md-pin absolute transform -translate-x-1/2 -translate-y-1/2 pointer-events-auto cursor-pointer
|
||||||
bg-red-500 text-white text-xs font-bold rounded-full w-6 h-6
|
bg-red-500 text-white text-xs font-bold rounded-full w-6 h-6
|
||||||
flex items-center justify-center shadow-lg
|
flex items-center justify-center shadow-lg
|
||||||
hover:bg-red-600 hover:scale-110 transition-all z-10"
|
hover:bg-red-600 hover:scale-110 transition-all z-10"
|
||||||
style={{
|
style={{
|
||||||
left: position().left,
|
left: position().left,
|
||||||
top: position().top
|
top: position().top
|
||||||
}}
|
}}
|
||||||
title={label || '标记点'}
|
title={label || '点击复制坐标'}
|
||||||
>
|
>
|
||||||
{label || '📍'}
|
{label || '📍'}
|
||||||
</span>
|
</span>
|
||||||
</Show>
|
</Show>
|
||||||
|
<Show when={showToast()}>
|
||||||
|
<div class="fixed bottom-4 left-1/2 transform -translate-x-1/2 bg-gray-800 text-white px-4 py-2 rounded shadow-lg text-sm z-50">
|
||||||
|
{toastMessage()}
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue