Robert
Robert

Reputation: 69

How to fix my draggable code in pure (vanilla) JavaScript, problem with moving div (div jumping or not moving)

I try to write pure draggable element, moving element, I want to click on div move and put div somewhere on container.

https://codepen.io/kotbezbutow/pen/VJMbeK

I dont now how to fix my problem. If I calculate the differences between the cursor and the edge of div, my div not moving.

        moveDraggable() {
            document.onmousemove = (e) => {

                let elementX = this.element.offsetLeft;
                let elementY = this.element.offsetTop;

                let mouseDownX = e.clientX;
                let mouseDownY = e.clientY;



                if (this.draggable == undefined) {
                    return;
                }

                let roznica = (mouseDownX - elementX);

                this.draggable.style.left = mouseDownX + roznica + "px";
                this.draggable.style.top = mouseDownY - 40 +  "px";
            }
        }

All my works is on codepen https://codepen.io/kotbezbutow/pen/VJMbeK

Upvotes: 0

Views: 136

Answers (2)

Thel-Rico
Thel-Rico

Reputation: 116

On mouse down, you need to store the delta between mouse position and div position. Then, on mouse move, you have to subtract the previous delta to event mouse position

element.addEventListener('mousedown', event => {
    const rel = (() => {
        const x = event.clientX - parseInt(this.style.left)
        const y = event.clientY - parseInt(this.style.top)
        return { x: x, y: y }
    })()
    const moveHandler = event => {
        this.style.left = event.clientX - rel.x + 'px'
        this.style.top = event.clientY - rel.y + 'px'
    }
    const endHandler = () => {
        window.removeEventListener('mousemove', moveHandler, false)
        window.removeEventListener('mouseup', endHandler, false)
    }
    window.addEventListener('mousemove', moveHandler, false)
    window.addEventListener('mouseup', endHandler, false)
}

EDIT : for smooth move, you should use css translate instead of element left / top

Upvotes: 1

Robert
Robert

Reputation: 69

I tried and tried and succeeded, thx for help. The most important is calclulate differance between curosr and div position in mousedown not mousemove.

class Move {
    constructor(element) {

        this.border = undefined;
        this.draggable = undefined;

        document.querySelector("body").addEventListener("mousedown", (e) => {

            // get element and init draggable
            this.draggable = e.target.closest(element);

            let mouseDownX = e.clientX;
            let mouseDownY = e.clientY;

            let elementX = this.draggable.offsetLeft;
            let elementY = this.draggable.offsetTop;

            this.differanceX = mouseDownX - elementX;
            this.differanceY = mouseDownY - elementY;

            // move draggable
            document.addEventListener('mousemove', (e) => {

                // return if end
                if (this.draggable == undefined) {
                    return;
                }

                let mouseDownX = e.clientX;
                let mouseDownY = e.clientY;

                this.draggable.style.left = mouseDownX - this.differanceX + "px";
                this.draggable.style.top = mouseDownY - this.differanceY + "px";

            });

            document.addEventListener('mouseup', (e) => {
                this.draggable = undefined;
            });

        });
    }
}

Upvotes: 0

Related Questions