Anurag92
Anurag92

Reputation: 124

Not able to move div using mousemove in react

I am trying to move a div with the help of mousemove event.

Here is the code for the same. https://codepen.io/anurag92/pen/VEoQOZ

class ImageMarker extends React.Component {

    constructor(props) {
        super(props);

        this.mouseDown = this.mouseDown.bind(this);
        this.mouseUp = this.mouseUp.bind(this);
        this.mouseMove = this.mouseMove.bind(this);
        this.paint = this.paint.bind(this);
    }

    mouseDown(e) {
        const position = {
            left: this.marker.offsetLeft,
            top: this.marker.offsetTop
        };

        this.hitOffset = {
            x: e.pageX - position.left,
            y: e.pageY - position.top,
            diameter: this.diameter(),
            markerRadius: 10
        };
        this.marker.addEventListener('mousemove', this.mouseMove);
        this.marker.addEventListener('mouseup', this.mouseUp);
        this.marker.addEventListener('mouseleave', this.mouseUp);
        e.preventDefault();
    }

    mouseMove(e) {
        this.position = {
            x: e.pageX - this.hitOffset.x,
            y: e.pageY - this.hitOffset.y
        };
        this.position.x = Math.round(this.position.x);
        this.position.y = Math.round(this.position.y);

        this.position.x = Math.min(700 - 1, Math.max(0, this.position.x));
        this.position.y = Math.min(700 - 1, Math.max(0, this.position.y));

        this.paint();
    }

    mouseUp(e) {
        this.marker.removeEventListener('mousemove', this.mouseMove);
        this.marker.removeEventListener('mouseup', this.mouseUp);
        this.marker.removeEventListener('mouseleave', this.mouseUp);
    }

    diameter() {
        return 1;
    }

    paint() {
        if (JSON.stringify(this.paintedPosition) !== JSON.stringify(this.position)) {
            this.paintedPosition = Object.assign({}, this.position);
        }

        if (this.position) {
            this.marker.style.left = `${100 * this.position.x / 700}%`;
            this.marker.style.top = `${100 * this.position.y / 700}%`;
        }
        return this;
    }

    render() {
        this.position = this.position || {
            x: 5,
            y: 5
        };
        this.offset = 0;
        return <div className='outer'
            ref = {ref => {
                this.canvasRef = ref;
            }}
        >
            <div className = 'marker'
                onMouseDown = {event => this.mouseDown(event)}
                ref = {ref => {
                    this.marker = ref;
                }} >
            </div>
        </div>;
    }

}

// export default ImageMarker;



ReactDOM.render(<ImageMarker />,
document.getElementById('root')
);

When i move my cursor slowly its working fine, but on fast movement mouseleave gets triggered and as a result div is not able to keep up with the cursor.

Can someone please tell me a potential fix for this.

Upvotes: 4

Views: 3820

Answers (1)

Xizario
Xizario

Reputation: 501

You could resolve that by attaching the mouseMove (and mouseUp)to the whole document This way they will be fired no matter if the mouse gets out of the element you want to drag. Just remember to detach the event during componentWillUnmount to avoid leaks.

Further more if you want you site to work on mobile you need to attach touch, pointer or drag events. See the code of the kendo-draggable abstraction for a reference. We are using it in our react components. Bind to the element on ComponentDidMount and detach on ComponentWillUnmount

Upvotes: 3

Related Questions