diff --git a/app/page.js b/app/page.js
index decc51c..c33e239 100644
--- a/app/page.js
+++ b/app/page.js
@@ -295,78 +295,67 @@ export default function Home() {
)}
- {/* 可拖动浮动按钮组 */}
- {(() => {
- const STORAGE_KEY = 'author-fab-pos';
- const saved = typeof window !== 'undefined' ? JSON.parse(localStorage.getItem(STORAGE_KEY) || 'null') : null;
- const defaultPos = { right: 24, bottom: 24 };
- return (
-
{
- if (e.target.closest('a') || (e.target.tagName === 'BUTTON' && !e.target.classList.contains('fab-drag-handle'))) return;
- const el = e.currentTarget;
- const rect = el.getBoundingClientRect();
- const parentRect = el.parentElement.getBoundingClientRect();
- const offsetX = e.clientX - rect.left;
- const offsetY = e.clientY - rect.top;
- el.style.cursor = 'grabbing';
- let moved = false;
- const onMove = (ev) => {
- moved = true;
- const newRight = parentRect.right - ev.clientX - (rect.width - offsetX);
- const newBottom = parentRect.bottom - ev.clientY - (rect.height - offsetY);
- const clampedRight = Math.max(0, Math.min(parentRect.width - rect.width, newRight));
- const clampedBottom = Math.max(0, Math.min(parentRect.height - rect.height, newBottom));
- el.style.right = `${clampedRight}px`;
- el.style.bottom = `${clampedBottom}px`;
- };
- const onUp = () => {
- el.style.cursor = 'grab';
- document.removeEventListener('pointermove', onMove);
- document.removeEventListener('pointerup', onUp);
- if (moved) {
- localStorage.setItem(STORAGE_KEY, JSON.stringify({
- right: parseInt(el.style.right),
- bottom: parseInt(el.style.bottom),
- }));
- }
- };
- document.addEventListener('pointermove', onMove);
- document.addEventListener('pointerup', onUp);
- }}
- >
+ {/* 独立可拖动浮动按钮 */}
+ {['github', 'help'].map(btnKey => {
+ const storageKey = `author-fab-${btnKey}`;
+ const saved = typeof window !== 'undefined' ? JSON.parse(localStorage.getItem(storageKey) || 'null') : null;
+ const defaults = { github: { right: 24, bottom: 76 }, help: { right: 24, bottom: 24 } };
+ const pos = saved || defaults[btnKey];
+ const makeDraggable = (e) => {
+ const el = e.currentTarget;
+ const parentRect = el.parentElement.getBoundingClientRect();
+ const rect = el.getBoundingClientRect();
+ const startX = e.clientX, startY = e.clientY;
+ const offsetX = e.clientX - rect.left;
+ const offsetY = e.clientY - rect.top;
+ let dragging = false;
+ const onMove = (ev) => {
+ if (!dragging && Math.abs(ev.clientX - startX) + Math.abs(ev.clientY - startY) < 5) return;
+ dragging = true;
+ ev.preventDefault();
+ const r = Math.max(0, Math.min(parentRect.width - rect.width, parentRect.right - ev.clientX - (rect.width - offsetX)));
+ const b = Math.max(0, Math.min(parentRect.height - rect.height, parentRect.bottom - ev.clientY - (rect.height - offsetY)));
+ el.style.right = `${r}px`;
+ el.style.bottom = `${b}px`;
+ };
+ const onUp = (ev) => {
+ document.removeEventListener('pointermove', onMove);
+ document.removeEventListener('pointerup', onUp);
+ if (dragging) {
+ ev.preventDefault();
+ localStorage.setItem(storageKey, JSON.stringify({ right: parseInt(el.style.right), bottom: parseInt(el.style.bottom) }));
+ }
+ };
+ document.addEventListener('pointermove', onMove);
+ document.addEventListener('pointerup', onUp);
+ };
+ const commonStyle = {
+ position: 'absolute',
+ right: `${pos.right}px`,
+ bottom: `${pos.bottom}px`,
+ zIndex: 40,
+ borderRadius: '50%',
+ width: '44px',
+ height: '44px',
+ boxShadow: 'var(--shadow-md)',
+ fontSize: '18px',
+ opacity: 0.8,
+ cursor: 'grab',
+ userSelect: 'none',
+ touchAction: 'none',
+ };
+ if (btnKey === 'github') {
+ return (
{ if (e.defaultPrevented) return; }}
onMouseEnter={(e) => e.currentTarget.style.opacity = '1'}
onMouseLeave={(e) => e.currentTarget.style.opacity = '0.8'}
title="GitHub"
@@ -375,28 +364,24 @@ export default function Home() {
-
-
+ );
+ }
+ return (
+