Я пытался реализовать перетаскиваемый div в реакции, в основном я использовал бы мышь, чтобы щелкнуть и перетащить элемент вокруг или даже палец, если я нахожусь на мобильном телефоне.
Проблема в том, что когда я слишком быстро перемещаю мышь и курсор покидает область div, элемент останавливается. Как будто я не обновляю позицию div достаточно быстро, чтобы идти в ногу со скоростью курсора.
Любая идея, как я могу это исправить?
Кроме того, я использовал верхнюю и левую позиции для обновления позиции div, есть ли какие-то преимущества в использовании css translatex / y?
Чем бы это отличалось?
import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
class App extends Component {
constructor() {
super();
this.state = {
pos: {
x:0,
y:0,
},
rel: {
x:0,
y:0
},
dragging : false
};
this.draggable = React.createRef()
}
onTouchStart = e => {
const touch = e.touches[0]
const posTop = this.draggable.current.offsetTop
const posLeft = this.draggable.current.offsetLeft
this.setState({
dragging: true,
rel: {
x: touch.clientX - posLeft,
y: touch.clientY - posLeft
}
})
e.stopPropagation()
}
onTouchMove = e => {
if (!this.state.dragging) return
const touch = e.touches[0]
this.setState({
pos: {
x: touch.clientX - this.state.rel.x,
y: touch.clientY - this.state.rel.y
}
})
e.stopPropagation()
e.preventDefault()
}
onTouchEnd = e => {
this.setState({dragging: false})
}
onMouseDown = (e) => {
// only left mouse button
if (e.button !== 0) return
const posTop = this.draggable.current.offsetTop
const posLeft = this.draggable.current.offsetLeft
console.log(e.pageX,': pagex ', e.pageY, ' : and pagey')
console.log(posTop, ': posTop', posLeft, ' : posY')
console.log('resultLeft :', e.pageX - posLeft, 'resultTop :', e.pageY - posTop)
this.setState({
dragging: true,
rel: {
x: e.pageX - posLeft,
y: e.pageY - posTop
}
})
e.stopPropagation()
e.preventDefault()
}
onMouseUp = (e) => {
this.setState({dragging: false})
e.stopPropagation()
e.preventDefault()
}
onMouseMove = (e) => {
if (!this.state.dragging) return
this.setState({
pos: {
x: e.pageX - this.state.rel.x,
y: e.pageY - this.state.rel.y
}
})
e.stopPropagation()
e.preventDefault()
}
render() {
return (
<div style={{position:'relative', backgroundColor:'green', height:'100%', width:'100%'}}>
<div style={{position:'absolute',backgroundColor:'red',
height: '100px', width:'100px',
left: this.state.pos.x + 'px', top: this.state.pos.y + 'px'}}
onTouchStart={this.onTouchStart}
onTouchMove={this.onMouseMove}
onTouchEnd={this.onTouchEnd}
onMouseDown={this.onMouseDown}
onTouchMove={this.onTouchMove}
onMouseMove={this.onMouseMove}
onMouseUp={this.onMouseUp}
ref={this.draggable}
> draggable div
</div>
</div>
);
}
}
render(<App />, document.getElementById('root'));
Вы можете поместить код на stackblitz, и он будет работать, чтобы вы могли попробовать.
Любой совет приветствуется!
Ссылка на стек: https://stackblitz.com/edit/react-draggable-test-oezlsk