Open josvos opened 3 years ago
@josvos
You have to set all the values of the transform. translate, rotate, scale
const transform = translate(${translate[0]}px, ${translate[1]}px) rotate(${rotate}deg) scale(${scale[0]}, ${scale[1]})
;
or use helper
import MoveableHelper from "moveable-helper";
const [helper] = React.useState(() => {
return new MoveableHelper();
})
const targetRef = React.useRef <Moveable
target={targetRef}
draggable={true}
resizable={true}
rotatable={true}
onDragStart={helper.onDragStart}
onDrag={helper.onDrag}
onResizeStart={helper.onResizeStart}
onResize={helper.onResize}
onRotateStart={helper.onRotateStart}
onRotate={helper.onRotate}
/>
</div>;
@ set all the values: ok, but the order does matter, as translate => rotate differs from rotate => translate. I could calculate one matrix/matrix3d(...), e.g. using the rematrix package, and administer the accumulated transformation. But the problem is still that the transform origin is kept at the original center. Also, a resize breaks the accumulated transformation, as it needs recalculating the translate.
@ moveable-helper: tried it and yeah, this is exactly the behavior I need (except one thing, see below). But moveable-helper pulls in scenejs and more, a huge amount of code, just for this, which looks like overkill.. One problem I also still see: how do I specify an existing transform to start with, that keeps being honored by the subsequent actions?
@josvos If possible, keep the order of T => R => S
Also, as you say, the order of transforms can be changed.
It's still in beta and try this feature
onBeforeRenderStart={e => {
e.setTransform(`translate(0px, 0px) rotate(30deg) scale(1, 2)`);
}}
onDragStart={e => {
e.setTransformIndex(0);
}}
onDrag={e => {
e.target.style.transform = e.transform;
})
onRotateStart={e => {
e.setTransformIndex(1);
e.dragStart && e.dragStart.setTransformIndex(0);
}}
onRotate={e => {
e.target.style.transform = e.drag.transform;
}}
I guess the onBeforeRenderStart should get parameters for the transform (translate x/y, degree etc.) from a saved state of previous actions, that has to be updated at on{Drag,Rotate}End events?
And how to deal with resize? Should I adapt the width/height and correct the translate accordingly (dependent on the resize "direction")?
@josvos
Right. Save the previous value to the last end event or progress event.
onDragEnd={e => {
e.lastEvent && setState(....);
}}
And resize, scale, and rotate all change the translate value.
I made some progression and I can now do mixed set of drag/resize/rotate actions while the frame responds correctly (note that I didn't try scale, skew etc. yet). I'm happy to share the code when ready (although it is wrapped in a Vue component now).
But now the next question is how to initialize the frame with the saved properties. So, when I save the translate, rotate, width, and height values, how to create the frame again and continue to perform actions, saving the properties again, etc. All attempts I tried so far resulted in a bad initial frame and/or strange behavior when performing actions.
Hi, any suggestions related to my last question, about how to save and restore/initialize transform properties between sessions?
@josvos Did you eventually figure out the best way to do this ( & within a vue component? ). Im using the vue moveable package (tho it hasn't been updated in about 6 months) and i'm running into similar issues and questions as you and hit this issue. Would love to see your take on it. I'm struggling a bit with the combination of rotations and transforms. Same reasons as stated above.
The "vanilla" example code for the callbacks shown in the handbook (https://github.com/daybrush/moveable/blob/master/handbook/handbook.md) doesn't support multiple operations in sequence. E.g, doing a rotation works fine, but starting a drag a resize afterwards undoes the rotation. I would like to have it all working together, similar to the demo (https://daybrush.com/moveable/) ;-).
Background: I want to do all kinds of operations on the frame and finally take its CSS props (transform, width, height, etc.) to store as new CSS for an element (a div acting as some zone).