新增活跃工具层级管理,优化调色盘和放大镜工具的激活逻辑,确保用户交互流畅性和界面友好性。
This commit is contained in:
@@ -172,6 +172,9 @@ export default function Home() {
|
||||
endCol: number;
|
||||
} | null>(null);
|
||||
|
||||
// 新增:活跃工具层级管理
|
||||
const [activeFloatingTool, setActiveFloatingTool] = useState<'palette' | 'magnifier' | null>(null);
|
||||
|
||||
// 放大镜切换处理函数
|
||||
const handleToggleMagnifier = () => {
|
||||
const newActiveState = !isMagnifierActive;
|
||||
@@ -183,6 +186,15 @@ export default function Home() {
|
||||
}
|
||||
};
|
||||
|
||||
// 激活工具处理函数
|
||||
const handleActivatePalette = () => {
|
||||
setActiveFloatingTool('palette');
|
||||
};
|
||||
|
||||
const handleActivateMagnifier = () => {
|
||||
setActiveFloatingTool('magnifier');
|
||||
};
|
||||
|
||||
// 放大镜像素编辑处理函数
|
||||
const handleMagnifierPixelEdit = (row: number, col: number, colorData: { key: string; color: string }) => {
|
||||
if (!mappedPixelData) return;
|
||||
@@ -2171,6 +2183,8 @@ export default function Home() {
|
||||
onHighlightColor={handleHighlightColor}
|
||||
isOpen={isFloatingPaletteOpen}
|
||||
onToggleOpen={() => setIsFloatingPaletteOpen(!isFloatingPaletteOpen)}
|
||||
isActive={activeFloatingTool === 'palette'}
|
||||
onActivate={handleActivatePalette}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -2188,6 +2202,8 @@ export default function Home() {
|
||||
cellSize={gridDimensions ? Math.min(6, Math.max(4, 500 / Math.max(gridDimensions.N, gridDimensions.M))) : 6}
|
||||
selectionArea={magnifierSelectionArea}
|
||||
onClearSelection={() => setMagnifierSelectionArea(null)}
|
||||
isFloatingActive={activeFloatingTool === 'magnifier'}
|
||||
onActivateFloating={handleActivateMagnifier}
|
||||
/>
|
||||
|
||||
{/* 放大镜选择覆盖层 */}
|
||||
|
||||
@@ -22,6 +22,8 @@ interface FloatingColorPaletteProps {
|
||||
onHighlightColor: (colorHex: string) => void;
|
||||
isOpen: boolean;
|
||||
onToggleOpen: () => void;
|
||||
isActive: boolean;
|
||||
onActivate: () => void;
|
||||
}
|
||||
|
||||
const FloatingColorPalette: React.FC<FloatingColorPaletteProps> = ({
|
||||
@@ -39,7 +41,9 @@ const FloatingColorPalette: React.FC<FloatingColorPaletteProps> = ({
|
||||
onColorReplace,
|
||||
onHighlightColor,
|
||||
isOpen,
|
||||
onToggleOpen
|
||||
onToggleOpen,
|
||||
isActive,
|
||||
onActivate
|
||||
}) => {
|
||||
const [position, setPosition] = useState({ x: 20, y: 100 });
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
@@ -50,6 +54,7 @@ const FloatingColorPalette: React.FC<FloatingColorPaletteProps> = ({
|
||||
const handleMouseDown = useCallback((e: React.MouseEvent) => {
|
||||
if (!paletteRef.current) return;
|
||||
|
||||
onActivate(); // 激活调色板,置于最上层
|
||||
const rect = paletteRef.current.getBoundingClientRect();
|
||||
setIsDragging(true);
|
||||
setDragOffset({
|
||||
@@ -57,12 +62,13 @@ const FloatingColorPalette: React.FC<FloatingColorPaletteProps> = ({
|
||||
y: e.clientY - rect.top
|
||||
});
|
||||
e.preventDefault();
|
||||
}, []);
|
||||
}, [onActivate]);
|
||||
|
||||
// 处理触摸开始
|
||||
const handleTouchStart = useCallback((e: React.TouchEvent) => {
|
||||
if (!paletteRef.current) return;
|
||||
|
||||
onActivate(); // 激活调色板,置于最上层
|
||||
const rect = paletteRef.current.getBoundingClientRect();
|
||||
const touch = e.touches[0];
|
||||
setIsDragging(true);
|
||||
@@ -71,7 +77,7 @@ const FloatingColorPalette: React.FC<FloatingColorPaletteProps> = ({
|
||||
y: touch.clientY - rect.top
|
||||
});
|
||||
e.preventDefault();
|
||||
}, []);
|
||||
}, [onActivate]);
|
||||
|
||||
// 处理移动
|
||||
useEffect(() => {
|
||||
@@ -160,13 +166,16 @@ const FloatingColorPalette: React.FC<FloatingColorPaletteProps> = ({
|
||||
return (
|
||||
<div
|
||||
ref={paletteRef}
|
||||
className="fixed bg-white dark:bg-gray-800 rounded-xl shadow-2xl border border-gray-200 dark:border-gray-600 z-50 select-none"
|
||||
className={`fixed bg-white dark:bg-gray-800 rounded-xl shadow-2xl border border-gray-200 dark:border-gray-600 select-none ${
|
||||
isActive ? 'z-[60]' : 'z-[50]'
|
||||
}`}
|
||||
style={{
|
||||
left: position.x,
|
||||
top: position.y,
|
||||
width: '280px',
|
||||
maxHeight: '400px'
|
||||
}}
|
||||
onClick={onActivate}
|
||||
>
|
||||
{/* 标题栏和控制按钮 */}
|
||||
<div
|
||||
|
||||
@@ -22,7 +22,7 @@ const FloatingToolbar: React.FC<FloatingToolbarProps> = ({
|
||||
if (!isManualColoringMode) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed top-4 right-4 z-40 flex flex-col gap-2">
|
||||
<div className="fixed top-4 right-4 z-[100] flex flex-col gap-2">
|
||||
{/* 调色盘开关按钮 */}
|
||||
<button
|
||||
onClick={onTogglePalette}
|
||||
|
||||
@@ -13,6 +13,8 @@ interface MagnifierToolProps {
|
||||
cellSize: number;
|
||||
selectionArea: SelectionArea | null;
|
||||
onClearSelection: () => void;
|
||||
isFloatingActive: boolean;
|
||||
onActivateFloating: () => void;
|
||||
}
|
||||
|
||||
interface SelectionArea {
|
||||
@@ -30,7 +32,9 @@ const MagnifierTool: React.FC<MagnifierToolProps> = ({
|
||||
selectedColorSystem,
|
||||
onPixelEdit,
|
||||
selectionArea,
|
||||
onClearSelection
|
||||
onClearSelection,
|
||||
isFloatingActive,
|
||||
onActivateFloating
|
||||
}) => {
|
||||
// 计算初始位置,确保在屏幕中央
|
||||
const getInitialPosition = () => ({
|
||||
@@ -160,11 +164,12 @@ const MagnifierTool: React.FC<MagnifierToolProps> = ({
|
||||
});
|
||||
}
|
||||
|
||||
onActivateFloating(); // 激活放大镜,置于最上层
|
||||
setIsDragging(true);
|
||||
// 阻止页面滚动
|
||||
document.body.style.overflow = 'hidden';
|
||||
event.preventDefault();
|
||||
}, []);
|
||||
}, [onActivateFloating]);
|
||||
|
||||
// 处理拖拽移动 - 触摸事件
|
||||
const handleTitleBarTouchStart = useCallback((event: React.TouchEvent) => {
|
||||
@@ -186,11 +191,12 @@ const MagnifierTool: React.FC<MagnifierToolProps> = ({
|
||||
});
|
||||
}
|
||||
|
||||
onActivateFloating(); // 激活放大镜,置于最上层
|
||||
setIsDragging(true);
|
||||
// 阻止页面滚动
|
||||
document.body.style.overflow = 'hidden';
|
||||
event.preventDefault();
|
||||
}, []);
|
||||
}, [onActivateFloating]);
|
||||
|
||||
const handleMouseMove = useCallback((event: MouseEvent) => {
|
||||
if (isDragging) {
|
||||
@@ -258,7 +264,7 @@ const MagnifierTool: React.FC<MagnifierToolProps> = ({
|
||||
<>
|
||||
{/* 选择区域提示 */}
|
||||
{!selectionArea && (
|
||||
<div className="fixed top-4 left-1/2 transform -translate-x-1/2 bg-blue-500 text-white px-4 py-2 rounded-lg shadow-lg z-50">
|
||||
<div className="fixed top-4 left-1/2 transform -translate-x-1/2 bg-blue-500 text-white px-4 py-2 rounded-lg shadow-lg z-[70]">
|
||||
<div className="flex items-center gap-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||
@@ -272,11 +278,14 @@ const MagnifierTool: React.FC<MagnifierToolProps> = ({
|
||||
{selectionArea && (
|
||||
<div
|
||||
ref={magnifierRef}
|
||||
className="fixed bg-white dark:bg-gray-800 rounded-xl shadow-2xl border border-gray-200 dark:border-gray-600 z-50 select-none"
|
||||
className={`fixed bg-white dark:bg-gray-800 rounded-xl shadow-2xl border border-gray-200 dark:border-gray-600 select-none ${
|
||||
isFloatingActive ? 'z-[60]' : 'z-[50]'
|
||||
}`}
|
||||
style={{
|
||||
left: magnifierPosition.x,
|
||||
top: magnifierPosition.y
|
||||
}}
|
||||
onClick={onActivateFloating}
|
||||
>
|
||||
{/* 标题栏 */}
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user