daybrush / moveable

Moveable! Draggable! Resizable! Scalable! Rotatable! Warpable! Pinchable! Groupable! Snappable!
https://daybrush.com/moveable/
MIT License
10.08k stars 618 forks source link

Moveable + Selecto: How to correctly setup dragTarget with Multiple Selected Elements? #953

Closed jadiagaurang closed 1 year ago

jadiagaurang commented 1 year ago

Environments

Description

I am trying to use dragTarget property to move Elements specially contentEditable Text Elements.

It works for single element initially. I am facing issue when I select multiple elements then it doesn't drag the group. If I select single element after multiple selection then it stops dragging single element.

I have added Custom Able as following and setup dragTarget after initializing Moveable Object as follows;

const DragHandleAble = {
  name: "draghandleable",
  props: {},
  events: {},
  render(moveable, Renderer) {
    const rect = moveable.getRect();

    return Renderer.createElement("button", {
      key: "draghandleable",
      class: "dragHandle",
      style: {
        position: "absolute",
        left: `${rect.width / 2}px`,
        top: `${rect.height + 20}px`,
        background: "#4af",
        borderRadius: "2px",
        padding: "2px 4px",
        color: "white",
        fontSize: "13px",
        whiteSpace: "nowrap",
        fontWeight: "bold",
        willChange: "transform",
        transform: "translate(-50%, 0px)",
      }
    }, `dragHandle`);
  },
}

This is how I am setting up the dragTarget after initializing Moveable Object.

window.objMoveable = new Moveable(designCanvas, {
});
// The target(s) to drag Moveable target(s)
window.objMoveable.dragTarget = $(".dragHandle")[0];     // HTMLElement as Ref
daybrush commented 1 year ago

@jadiagaurang

In the case of Group <=> Single, the element of dragTarget is also regenerated because able is regenerated.

I will support several types of dragTarget.

In the next version you can use:

moveable.dragTarget = ".dragHandle";
jadiagaurang commented 1 year ago

Hi @daybrush

That will be helpful to pass the CSS Selector instead of the HTML Element Ref.

I'm looking forward to having this new feature, many thanks for considering my request.

daybrush commented 1 year ago

@jadiagaurang

moveable's new version is released.

various types are supported.


moveable.dragTarget = ".dragHandler";
moveable.dragTarget = dragHandlerRef;
jadiagaurang commented 1 year ago

@daybrush Thanks for the updates.

It works very well with Single Target as well as Multiple.

jadiagaurang commented 1 year ago

@daybrush Did you change something in 0.49.1 version for dragHandle? It has stopped working correctly for Group.

Testable Address(optional): https://codepen.io/jadiagaurang/pen/QWJyEaE

https://github.com/daybrush/moveable/assets/430637/fd764ec8-0456-41cd-8740-1496dc6dd306

jadiagaurang commented 1 year ago

@daybrush I have added a BUTTON as CustomAble, which asks as dragTarget for the Moveable.

Custom DragHandleAble!

const { html } = TaggedJSX;
const DragHandleAble = ({
    name: "draghandleable",
    props: {},
    events: {},
    render: function (moveable, Renderer) {
        const rect = moveable.getRect();
        const { pos2 } = moveable.state;

        const DragHandleViewer = moveable.useCSS("button", `{
            position: absolute;
            left: 0px;
            top: 0px;
            will-change: transform;
            transform-origin: 0px 0px;
        }
        .dragHandle {
            width: 24px;
            height: 24px;
            margin-bottom: 4px;
            background: #4af;
            border-radius: 4px;
            appearance: none;
            border: 0;
            color: white;
            font-weight: bold;
        }`);

        return html`<${DragHandleViewer} className="dragHandle" style=${{ transform: `translate(${pos2[0]}px, ${pos2[1]}px) rotate(${rect.rotation}deg) translate(10px)`, }}> </>`(Renderer.createElement);
    }
});

I tied to set up ".dragHandle" as CSSSelector and/or $(".dragHandle")[0] as a HTMLElement to the dragTarget config option.

  1. CSSSelector Implementation
    var objMoveable = new Moveable(canvasContainer, {
    draggable: true,
    dragTarget: ".dragHandle",
    ables: [
        DragHandleAble
    ],
    props: {
        draghandleable: true
    }
    });
  2. HTMLElement Implementation
    // The target(s) to drag Moveable target(s)
    objMoveable.dragTarget = $(".dragHandle")[0];

It works something and doesn't work other times. It is just Hit-or-Miss. It should work with a single target and multiple targets (grouping). It is one of the very important features in my project, and dragTarget helps users to drag contenteditable Texts!

Please spend some time debugging and help me figure out how to implement this feature correctly.

daybrush commented 1 year ago

@jadiagaurang

moveable's new version is released. Check it again.