Я пытаюсь реализовать перетаскивание в React и использовать элементы SVG. Проблема в том, что mouseMove
не срабатывает, если пользователь слишком быстро перемещает мышь. Это в основном теряет перетаскивание довольно часто. Чтобы решить эту проблему, я думаю, что мне нужно обработать mouseMove
в родительском элементе, но не уверен, как это сделать с помощью React. Я пробовал несколько разных подходов безрезультатно.
Я пытался addEventListener('mousemove', ...)
на родительском элементе, используя ссылку, но проблема в том, что clientX
- это система координат, отличная от текущего компонента. Кроме того, обработчик событий не имеет доступа ни к какому состоянию из компонента (событие с функциями стрелки). Он сохраняет устаревшую ссылку на любое состояние.
Я попытался установить clientX
и clientY
в context
на родительском элементе, а затем вытянуть его из компонента DragMe
, но это всегда undefined
в первый раз по какой-то странной причине, хотя Я даю ему значение по умолчанию.
Вот код, с которым я работаю:
const DragMe = ({ x = 50, y = 50, r = 10 }) => {
const [dragging, setDragging] = useState(false)
const [coord, setCoord] = useState({ x, y })
const [offset, setOffset] = useState({ x: 0, y: 0 })
const [origin, setOrigin] = useState({ x: 0, y: 0 })
const xPos = coord.x + offset.x
const yPos = coord.y + offset.y
const transform = `translate(${xPos}, ${yPos})`
const fill = dragging ? 'red' : 'green'
const stroke = 'black'
const handleMouseDown = e => {
setDragging(true)
setOrigin({ x: e.clientX, y: e.clientY })
}
const handleMouseMove = e => {
if (!dragging) { return }
setOffset({
x: e.clientX - origin.x,
y: e.clientY - origin.y,
})
}
const handleMouseUp = e => {
setDragging(false)
setCoord({ x: xPos, y: yPos })
setOrigin({ x: 0, y: 0 })
setOffset({ x: 0, y: 0 })
}
return (
<svg style={{ userSelect: 'none' }}
onMouseDown={handleMouseDown}
onMouseUp={handleMouseUp}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseUp}
>
<circle transform={transform} cx="0" cy="0" r={r} fill={fill} stroke={stroke} />
</svg>
)
}