mirror of
https://github.com/IliesAllali/parenthese.git
synced 2026-11-15 00:30:50 +00:00
fix(galaxy): un deuxième doigt annule le glisser d'une personne
Au passage à deux doigts (ou en cas d'interruption tactile), le glisser en cours est annulé et la personne revient à sa place : plus d'enregistrement pendant un pincement. Un doigt qui reste après un pincement ne saisit plus de personne, il ne fait que déplacer l'arbre. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b27b5e9737
commit
8fa2808b5d
2 files changed
+30
-7
No files matched your search
@@ -119,7 +119,7 @@ const Galaxy = ({ onPersonSelect, onMediaSelect, onPersonPositionChange, editMod
|
||||
|
||||
const {
|
||||
isDragging, isZooming, zoomTimeoutRef, hasDragged,
|
||||
handleMouseDown, handleMouseMove, handleMouseUp,
|
||||
handleMouseDown, handleMouseMove, handleMouseUp, cancelPersonDrag,
|
||||
handleMouseLeave, handleWheel, handleClick,
|
||||
} = useGalaxyInteractions({
|
||||
canvasRef, transformRef, targetTransformRef,
|
||||
@@ -706,7 +706,8 @@ const Galaxy = ({ onPersonSelect, onMediaSelect, onPersonPositionChange, editMod
|
||||
handleMouseDown({ clientX: t.clientX, clientY: t.clientY, preventDefault: () => e.preventDefault() })
|
||||
} else if (e.touches.length === 2) {
|
||||
e.preventDefault()
|
||||
// Stop any ongoing single-finger pan before starting pinch
|
||||
// Un second doigt annule le glisser d'une personne (rien n'est enregistré) puis arrête le pan
|
||||
cancelPersonDrag()
|
||||
handleMouseUp()
|
||||
const [a, b] = e.touches
|
||||
const dx = a.clientX - b.clientX
|
||||
@@ -744,15 +745,16 @@ const Galaxy = ({ onPersonSelect, onMediaSelect, onPersonPositionChange, editMod
|
||||
// and mark hasDragged=true so the lift doesn't fire an accidental click
|
||||
const t = e.touches[0]
|
||||
handleMouseUp()
|
||||
handleMouseDown({ clientX: t.clientX, clientY: t.clientY, preventDefault: () => e.preventDefault() })
|
||||
handleMouseDown({ clientX: t.clientX, clientY: t.clientY, preventDefault: () => e.preventDefault() }, { panOnly: true })
|
||||
hasDragged.current = true
|
||||
} else {
|
||||
handleMouseUp()
|
||||
}
|
||||
}}
|
||||
onTouchCancel={() => {
|
||||
// System interruption (notification, keyboard, etc.) — reset all touch state
|
||||
// System interruption (notification, keyboard, etc.) — reset all touch state, sans enregistrer de position
|
||||
pinchRef.current = null
|
||||
cancelPersonDrag()
|
||||
handleMouseUp()
|
||||
}}
|
||||
onClick={handleClick}
|
||||
|
||||
@@ -50,7 +50,8 @@ export function useGalaxyInteractions({
|
||||
}
|
||||
}, [canvasRef, transformRef])
|
||||
|
||||
const handleMouseDown = useCallback((e) => {
|
||||
// panOnly : un doigt qui reste après un pincement ne saisit pas de personne, il ne fait que déplacer l'arbre
|
||||
const handleMouseDown = useCallback((e, { panOnly = false } = {}) => {
|
||||
const ah = annotationHandlers
|
||||
const worldPos = getWorldPos(e)
|
||||
|
||||
@@ -72,7 +73,7 @@ export function useGalaxyInteractions({
|
||||
}
|
||||
}
|
||||
|
||||
if (editModeActive && (!ah || ah.activeTool === 'pointer') && worldPos && layoutDataRef.current) {
|
||||
if (editModeActive && !panOnly && (!ah || ah.activeTool === 'pointer') && worldPos && layoutDataRef.current) {
|
||||
const now = performance.now()
|
||||
for (let index = layoutDataRef.current.children.length - 1; index >= 0; index -= 1) {
|
||||
const node = layoutDataRef.current.children[index]
|
||||
@@ -86,6 +87,10 @@ export function useGalaxyInteractions({
|
||||
offsetY: worldPos.y - pos.cy,
|
||||
startClientX: e.clientX,
|
||||
startClientY: e.clientY,
|
||||
// Place d'origine, pour un glisser annulé (second doigt, interruption)
|
||||
originX: node.x,
|
||||
originY: node.y,
|
||||
originManual: node._manualPosition,
|
||||
}
|
||||
hoveredNodeIdRef.current = node.id
|
||||
hasDragged.current = false
|
||||
@@ -257,6 +262,22 @@ export function useGalaxyInteractions({
|
||||
}
|
||||
}, [handleGlobalMouseUp])
|
||||
|
||||
// Annule le glisser d'une personne sans rien enregistrer : la personne revient à sa place d'avant
|
||||
const cancelPersonDrag = useCallback(() => {
|
||||
const drag = draggedPersonRef.current
|
||||
if (!drag) return
|
||||
draggedPersonRef.current = null
|
||||
const { node, originX, originY, originManual } = drag
|
||||
node.x = originX
|
||||
node.y = originY
|
||||
node._manualPosition = originManual
|
||||
if (typeof window !== 'undefined') {
|
||||
window.removeEventListener('mouseup', handleGlobalMouseUp)
|
||||
}
|
||||
hoveredNodeIdRef.current = node.id
|
||||
setCanvasCursor(canvasRef, editModeActive ? CURSOR_NODE_GRAB : CURSOR_POINTER)
|
||||
}, [canvasRef, hoveredNodeIdRef, editModeActive, handleGlobalMouseUp])
|
||||
|
||||
const handleMouseLeave = useCallback(() => {
|
||||
isDragging.current = false
|
||||
annotationDragging.current = false
|
||||
@@ -366,6 +387,6 @@ export function useGalaxyInteractions({
|
||||
return {
|
||||
isDragging, isZooming, zoomTimeoutRef, hasDragged,
|
||||
handleMouseDown, handleMouseMove, handleMouseUp,
|
||||
handleMouseLeave, handleWheel, handleClick,
|
||||
handleMouseLeave, handleWheel, handleClick, cancelPersonDrag,
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user