I am trying to make a draggable button using react.
The button drags over the page in a proper manner but when I drop it. Its top and left values become negative(not even reset to their original top:0,left:0) i.e. the component goes out of the page.
code sand box link : code
main draggable.js component:
import React, { Component } from 'react';
import { Button } from '@material-ui/core';
class DraggableButton extends Component {
constructor() {
super();
this.state = {
dragging: false,
diffX: 0,
diffY: 0,
style: {
top: 0,
left: 0
}
}
}
handleMouseDown = (event) => {
console.log("element caught");
this.setState({
diffX: event.clientX - event.currentTarget.getBoundingClientRect().left,
diffY: event.clientY - event.currentTarget.getBoundingClientRect().top,
dragging: true
})
}
handleMouseMove = (event) => {
if (this.state.dragging) {
console.log("dragging");
let left = event.clientX - this.state.diffX;
let top = event.clientY - this.state.diffY;
this.setState({
style: {
left,
top
}
}, console.log("style ", this.state.style))
}
}
handleMouseUp = () => {
console.log('element released');
console.log('left value ', this.state.style.left);
console.log('top value ', this.state.style.top);
this.setState({
dragging: false,
})
}
render() {
return (
<Button
variant="contained" color="primary"
style={{ position: "absolute", ...this.state.style }}
draggable={true}
onDragStart={this.handleMouseDown}
onDrag={this.handleMouseMove}
onDragEnd={this.handleMouseUp}
// onMouseDown={this.handleMouseDown}
// onMouseMove={this.handleMouseMove}
// onMouseUp={this.handleMouseUp}
>
draggable button
</Button>
);
}
}
export default DraggableButton;
console screenshot :
As is visible in the image above at the time of dragging top: 193 left : 309 and as we dropped the element it turned to left: -109 top: -13.
why is this happening how can we fix it ?
In your handleMouseMove
you need to check if event.clientX
is a positive integer and then change the state, or else it will reduce the diffX
value and it will be nevative. (On drag release this becomes 0)
let left = event.clientX - this.state.diffX;
handleMouseMove = (event) => {
if (this.state.dragging) {
let left = event.clientX - this.state.diffX;
let top = event.clientY - this.state.diffY;
if (event.clientX !== 0)
this.setState({
style: {
left,
top
}
});
}
};