Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/components/image-editor/OptionsBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,18 @@ export function OptionsBar({
)
}

if (tool === 'hand') {
return (
<div className="pf-options">
<div className="pf-opt-group" style={{ borderRight: 0 }}>
<span className="pf-opt-label" style={{ marginRight: 0 }}>
{t('pages.imageEditor.handToolHint')}
</span>
</div>
</div>
)
}

if (tool === 'text') {
return (
<div className="pf-options">
Expand Down
1 change: 0 additions & 1 deletion src/components/image-editor/ToolsPalette.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ const GROUPS: ToolDef[][] = [
icon: <Hand className="h-4 w-4" />,
labelKey: 'pages.imageEditor.tool.hand',
shortcut: 'H',
stub: true,
},
{ id: 'zoom', icon: <Search className="h-4 w-4" />, labelKey: 'pages.imageEditor.tool.zoom', shortcut: 'Z' },
],
Expand Down
1 change: 0 additions & 1 deletion src/components/image-editor/tool-meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export const STUB_TOOLS: ReadonlySet<Tool> = new Set<Tool>([
'dodge',
'pen',
'arrowPath',
'hand',
'rotateView',
'frame',
'note',
Expand Down
1 change: 1 addition & 0 deletions src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@
"moveToolHint": "Move (V): drag layers; Cmd/Ctrl+J duplicate; Delete remove.",
"zoomToolHint": "Zoom (Z): click to zoom in 2×, Alt-click to zoom out. Cmd/Ctrl+wheel zooms at cursor.",
"eyedropperHint": "Eyedropper (I): click anywhere on the canvas to set the foreground color.",
"handToolHint": "Hand (H): drag the canvas to pan. Hold Space to pan with any other tool.",
"textToolHint": "Type (T): click on the canvas to add text.",
"toolStubHint": "{{tool}} is a placeholder — the palette button is here for parity with Photoshop, but the tool isn't implemented yet.",
"toolStubToast": "{{tool}} is not yet implemented.",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@
"moveToolHint": "移动 (V):拖动图层;Cmd/Ctrl+J 复制;Delete 删除。",
"zoomToolHint": "缩放 (Z):单击放大 2×,Alt 单击缩小。Cmd/Ctrl+滚轮在光标位置缩放。",
"eyedropperHint": "吸管 (I):在画布上单击以拾取前景色。",
"handToolHint": "抓手 (H):拖动画布以平移。任何工具下按住空格也可临时平移。",
"textToolHint": "文字 (T):在画布上单击以新增文字。",
"toolStubHint": "{{tool}} 仅作占位 —— 工具栏按钮是为了对齐 Photoshop 而保留,但功能尚未实现。",
"toolStubToast": "{{tool}} 暂未实现。",
Expand Down
10 changes: 7 additions & 3 deletions src/pages/ImageEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,14 @@ export function ImageEditorPage() {
const moveLayerRef = useRef<(d: 'forward' | 'backward' | 'front' | 'back') => void>(() => {})
const deleteLayerRef = useRef<() => void>(() => {})

// Zoom + pan + Space-held pan mode.
// Zoom + pan. Workspace enters pan mode when the user holds Space OR when
// the Hand tool is active — both treat the canvas as drag-to-pan instead
// of drag-to-draw.
const [zoom, setZoom] = useState(1)
const [pan, setPan] = useState({ x: 0, y: 0 })
const [panMode, setPanMode] = useState(false)
const [spaceHeld, setSpaceHeld] = useState(false)
const setPanMode = setSpaceHeld
const panMode = spaceHeld || tool === 'hand'

const ZOOM_MIN = 0.1
const ZOOM_MAX = 8
Expand Down Expand Up @@ -229,7 +233,7 @@ export function ImageEditorPage() {
window.removeEventListener('keydown', onKeyDown)
window.removeEventListener('keyup', onKeyUp)
}
}, [focused, zoomIn, zoomOut, zoomReset, swapColors, resetColors, selectedLayerId, trySetTool])
}, [focused, zoomIn, zoomOut, zoomReset, swapColors, resetColors, selectedLayerId, trySetTool, setPanMode])

// ── Layer state helpers ──────────────────────────────────────────────────
const setLayers = useCallback(
Expand Down
Loading