Visualized projects require elements that can be dragged and resized like graphics software. How do you do that? Why don’t we start with an easy version?

Click to enter github demo address, welcome to star github.com/songxuecc/R…

Basic JS events

  1. MouseDown: The button of the mouse is pressed down
  2. Mousemove: Moves the mouse over the target
  3. Mouseup: The button of the mouse is released and lifted
  4. Mouseleave: Triggered when the mouse moves out of the element range

The principle of

  1. Gets the start of the movement when the mouse is pressed over the box area and binds the Mousemove Mouseup Mouseleave event listener
  2. In the sliding process, the distance moved plus the width of the element is the final width of the element
  3. Unbind event after mouse release

Simple implementation of the effect and code

const SimpleDemo = () => {
  const [style, setState] = React.useState({ width: 250, height: 120 }); const origin = React.useRef(null); Style const onMouseMove = event => {event.stopPropagation(); event.preventDefault(); const clientX = event.clientX; const clientY = event.clientY; const width = style.width + clientX - origin.current.x; const height = style.height + clientY - origin.current.y;setState({ width, height }); }; // Mouse down const onMouseDown => {event.stopPropagation(); event.preventDefault(); const clientX = event.clientX; const clientY = event.clientY; Origin. current = {x: clientX, y: clientY};bindEvents(); }; Const onMouseUp = event => {unbindEvents(); }; constbindEvents = () => {
    document.addEventListener("mouseup", onMouseUp);
    document.addEventListener("mousemove", onMouseMove);
    document.addEventListener("mouseleave", onMouseUp);
  };
  const unbindEvents = () => {
    document.removeEventListener("mouseup", onMouseUp);
    document.removeEventListener("mousemove", onMouseMove);
    document.removeEventListener("mouseleave", onMouseUp);
  };

  React.useEffect(() => {
    return() => { unbindEvents(); }; } []);return (
    <div style={{ border: "1px solid green"}}> I am green box box <div onMouseDown={onMouseDown} style={{border:"1px solid red". Style}} > <h3> I am red box, click I drag to change the size </h3> </div> </div>); };Copy the code

Drag and resize as you would with a drawing software

The effect

The principle of

  1. Lock the six directional points and bind onMouseDown to each ponit
 const [pointList] = React.useState([
    "lt"."rt"."lb"."rb"."l"."r"."t"."b"
  ]);
Copy the code
  1. When YOU click on Ponit, you start binding events and the rest is pretty much the same as above
<div> <div> I'm going to change the size of the element A</div> <div> By dragging I can change the size of the element A< Point> </div> <div>Copy the code

Codesandbox.io /s/ Zen-Bogda…

const onMouseMove = moveEvent= > {
    const point = ref.current.pointId;
    let downEvent = moveEvent;
    downEvent.stopPropagation();
    downEvent.preventDefault();
    const activeNode = document.getElementById("box");
    const activeStyle = props.style;
    if(! activeNode) {return;
    }
    const { pos, startX, startY } = ref.current;
    constnextPos = { ... pos }; ref.current.hasMoved =true;
    let height = Number(nextPos.height);
    let width = Number(nextPos.width);
    let top = Number(nextPos.top) || 0;
    let left = Number(nextPos.left) || 0;
    let currX = moveEvent.clientX;
    let currY = moveEvent.clientY;
    let disY = currY - startY;
    let disX = currX - startX;
    let hasT = /t/.test(point);
    let hasB = /b/.test(point);
    let hasL = /l/.test(point);
    let hasR = /r/.test(point);
    let newHeight = +height + (hasT ? -disY : hasB ? disY : 0);
    let newWidth = +width + (hasL ? -disX : hasR ? disX : 0);
    nextPos.height = newHeight > 0 ? newHeight : 0;
    nextPos.width = newWidth > 0 ? newWidth : 0;
    nextPos.left = +left + (hasL ? disX : 0);
    nextPos.top = +top + (hasT ? disY : 0);
    // Calculate the drag result style according to the drag direction and keep cursor unchanged during the drag process
    // The canvas and the cursor of the dragged element are kept in line with the Point while being dragged
    conststyle = { ... activeStyle,left: `${nextPos.left}px`.top: `${nextPos.top}px`.width: `${nextPos.width}px`.height: `${nextPos.height}px`.cursor: directionKey[point]
    };
    const paiting = document.getElementById("painting-main");
    if (paiting) {
      paiting.style.cursor = directionKey[point];
    }
    stateRef.current = style;
    props.handleStyle(stateRef.current);
  };
  
  const onMouseUp = event= > {
    // Record the operation result
    if (ref.current.hasMoved) {
    }
    // Restore all data
    const paiting = document.getElementById("painting-main");
    if (paiting) {
      paiting.style.cursor = "default";
    }
    stateRef.current = _.omit(stateRef.current, ["cursor"]);
    props.handleStyle(stateRef.current);
    stateRef.current = {};
    ref.current = {};
    // Unbind
    unbindEvents();
  };
  
Copy the code

I hope you guys give me a thumbs up. Thank you