moveable
moveable copied to clipboard
Problem when dragging or rezising elements after rotating them, rotation is undone
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
set translate value on rotateStart, resizeStart.
https://daybrush.com/moveable/storybook/?path=/story/basic--resizable
https://daybrush.com/moveable/storybook/?path=/story/basic--rotatable
Thanks a lot, I'll try this !
Thank you, it works! Thanks for the great support.
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, 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?