moveable icon indicating copy to clipboard operation
moveable copied to clipboard

Problem when dragging or rezising elements after rotating them, rotation is undone

Open nathalieroemer opened this issue 4 years ago • 5 comments

Environments

  • Framework name: Vanilla JS
  • Moveable Component version: resizable, draggable

Description

I implemented moveable with selecto. However I face the issue that when I rotated elements and drag them, the previously changed angle is gone and the element looks like before (without rotation). The same happens when resizing the elements, the change that was made by rotating the element before is not saved. I am new to javascript and cannot figure out how to fix it. Any help is greatly appreciated!

Please find my code below:

const container = document.querySelector(".container_mine");
const frameMap = new Map();
const targets = [];


const selecto = new Selecto({
    container,
    dragContainer: ".selecto-area",
    selectableTargets: [".cube1", ".cube2", ".triangle"],
    hitRate: 0,
    selectByClick: true,
    selectFromInside: false,
    toggleContinueSelect: ["shift"],
    ratio: 100,
});

const moveable = new Moveable(container, {
    draggable: true,
    resizable: true,
    rotatable:true,
    snappable:true,
    bounds: {left:0, top:0, right:450, bottom:450}
}).on("clickGroup", e => {
    selecto.clickTarget(e.inputEvent, e.inputTarget);
}).on("dragStart", e => {
    const target = e.target;

    if (!frameMap.has(target)) {
        frameMap.set(target, {
            translate: [0, 0],
        });
    }
    const frame = frameMap.get(target);
    e.set(frame.translate);

}).on("drag", e => {
    const target = e.target;
    const frame = frameMap.get(target);
    frame.translate = e.beforeTranslate;
    target.style.transform = `translate(${frame.translate[0]}px, ${frame.translate[1]}px)`;

}).on("resize", ({ target, width, height, drag }) => {

    const beforeTranslate = drag.beforeTranslate;
    const frame = frameMap.get(target);
    frame.translate = beforeTranslate;
    target.style.width = `${width}px`;
    target.style.height = `${height}px`;
    target.style.transform = `translate(${beforeTranslate[0]}px, ${beforeTranslate[1]}px)`;

}).on("rotate", ({ target, transform }) => {
    target.style.transform = transform;
});


selecto.on("dragStart", e => {
    const target = e.inputEvent.target;
    if (
        moveable.isMoveableElement(target)
        || targets.some(t => t === target || t.contains(target))
    ) {
        e.stop();
    }
}).on("select", e => {
    targets = e.selected;
    moveable.target = targets;

}).on("selectEnd", e => {
    if (e.isDragStart) {
        e.inputEvent.preventDefault();

        setTimeout(() => {
             moveable.dragStart(e.inputEvent);
        });
    }
});

nathalieroemer avatar Nov 30 '20 16:11 nathalieroemer

@nathalieroemer

set translate value on rotateStart, resizeStart.

https://daybrush.com/moveable/storybook/?path=/story/basic--resizable

https://daybrush.com/moveable/storybook/?path=/story/basic--rotatable

daybrush avatar Dec 01 '20 17:12 daybrush

Thanks a lot, I'll try this !

nathalieroemer avatar Dec 02 '20 10:12 nathalieroemer

Thank you, it works! Thanks for the great support.

nathalieroemer avatar Dec 02 '20 15:12 nathalieroemer

Hi, I'm having the same issue. How do you set translate value on rotateStart and resizeStart?

I have this Moveable but the rotate doesn't work as expected, it jumps to the top left and it doesn't remember the drag position. Same thing for drag, and resize, they don't remember the rotate degrees.

`<Moveable ref={moveableRef} target={target2} draggable={true} throttleDrag={0} startDragRotate={0} throttleDragRotate={0}

            snappable={true}
            snapThreshold={5}
            snapCenter={false}
            bounds={{ left: 0, top: 0, bottom: height, right: width }}

            resizable={true}
            keepRatio={true}
            throttleResize={0}
            renderDirections={["nw","ne","sw","se"]}
            edge={false}

            rotatable={true}
            throttleRotate={0}
            rotationPosition={"top"}

            pinchable={true}
            pinchThreshold={20}

            zoom={1}
            origin={true}
            padding={{"left": 0, "top": 0, "right": 0, "bottom": 0}}

            onDragStart={e => {
                e.set(frame.translate);
            }}
            onDrag={e => {
                frame.translate = e.beforeTranslate;
                e.target.style.transform = `translate(${e.beforeTranslate[0]}px, ${e.beforeTranslate[1]}px)`;
            }}
            onRotateStart={e => {
                e.set(frame.rotate);
            }}
            onRotate={({beforeRotate, target}) => {
                frame.rotate = beforeRotate;
                target.style.transform = `rotate(${beforeRotate}deg)`;
            }}
            onResizeStart={e => {
                e.setOrigin(["%", "%"]);
                e.dragStart && e.dragStart.set(frame.translate);
            }}
            onResize={e => {
                const beforeTranslate = e.drag.beforeTranslate;
                frame.translate = beforeTranslate;
                e.target.style.width = `${e.width}px`;
                e.target.style.height = `${e.height}px`;
                e.target.style.transform = `translate(${beforeTranslate[0]}px, ${beforeTranslate[1]}px)`;
            }}
        />`

Thanks!

jeffceriello avatar Feb 28 '22 15:02 jeffceriello

Hi, I'm having the same issue. How do you set translate value on rotateStart and resizeStart?

I have this Moveable but the rotate doesn't work as expected, it jumps to the top left and it doesn't remember the drag position. Same thing for drag, and resize, they don't remember the rotate degrees.

`<Moveable ref={moveableRef} target={target2} draggable={true} throttleDrag={0} startDragRotate={0} throttleDragRotate={0}

Hi, I'm having the same issue. How do you set translate value on rotateStart and resizeStart?

I have this Moveable but the rotate doesn't work as expected, it jumps to the top left and it doesn't remember the drag position. Same thing for drag, and resize, they don't remember the rotate degrees.

`<Moveable ref={moveableRef} target={target2} draggable={true} throttleDrag={0} startDragRotate={0} throttleDragRotate={0}

            snappable={true}
            snapThreshold={5}
            snapCenter={false}
            bounds={{ left: 0, top: 0, bottom: height, right: width }}

            resizable={true}
            keepRatio={true}
            throttleResize={0}
            renderDirections={["nw","ne","sw","se"]}
            edge={false}

            rotatable={true}
            throttleRotate={0}
            rotationPosition={"top"}

            pinchable={true}
            pinchThreshold={20}

            zoom={1}
            origin={true}
            padding={{"left": 0, "top": 0, "right": 0, "bottom": 0}}

            onDragStart={e => {
                e.set(frame.translate);
            }}
            onDrag={e => {
                frame.translate = e.beforeTranslate;
                e.target.style.transform = `translate(${e.beforeTranslate[0]}px, ${e.beforeTranslate[1]}px)`;
            }}
            onRotateStart={e => {
                e.set(frame.rotate);
            }}
            onRotate={({beforeRotate, target}) => {
                frame.rotate = beforeRotate;
                target.style.transform = `rotate(${beforeRotate}deg)`;
            }}
            onResizeStart={e => {
                e.setOrigin(["%", "%"]);
                e.dragStart && e.dragStart.set(frame.translate);
            }}
            onResize={e => {
                const beforeTranslate = e.drag.beforeTranslate;
                frame.translate = beforeTranslate;
                e.target.style.width = `${e.width}px`;
                e.target.style.height = `${e.height}px`;
                e.target.style.transform = `translate(${beforeTranslate[0]}px, ${beforeTranslate[1]}px)`;
            }}
        />`

Thanks!

Hi. You have to merge all transforms. In example. You has moved your element to translate(5px, 10px) and your transform is

transform: translate(5px, 10px)

but after that you want to rotate your element by rotate(45deg) and your transform is:

transform: rotate(45deg)

but have to be:

transform: translate(5px, 10px) rotate(45deg)

got it?

rasfront avatar Feb 28 '22 18:02 rasfront