# resizable - dnd - 拖拽改变元素尺寸

# 1. 介绍

拖拽元素边缘,改变元素的尺寸

# 2. 示例

<body>
  <style>
    #box {
      position: absolute;
      top: 100px;
      left: 200px;
      width: 100px;
      height: 100px;
      background: #eee;
    }
    

    .resizer-top {
      position: absolute;
      top: 0;
      right: 0;
      left: 0;
      height: 10px;
      background: red;
      cursor: n-resize;
    }
    
    .resizer-right {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      width: 10px;
      background: green;
      cursor: e-resize;
    }
  
    .resizer-bottom {
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
      height: 10px;
      background: blue;
      cursor:s-resize;
    }
  
    .resizer-left {
      position: absolute;
      left: 0;
      top: 0;
      bottom: 0;
      width: 10px;
      background: yellow;
      cursor: w-resize;
    }
  </style>
  
  <div id="box">
    <div class="resizer-top"></div>
    <div class="resizer-right"></div>
    <div class="resizer-bottom"></div>
    <div class="resizer-left"></div>
  </div>
  
  <script>
    class Draggable {
      constructor(target, { onStart, onMove }) {
        const position = {
          origin: { x: 0, y: 0 },
          mousedown: { x: 0, y: 0 },
          mousemove: { x: 0, y: 0 },
        };

        const update = () => {
          const { origin: { x, y }, mousedown, mousemove } = position; 

          const deltaX = mousemove.x - mousedown.x;
          const deltaY = mousemove.y - mousedown.y;

          onMove({ deltaX, deltaY });
        };

        const mousemoveHandler = (event) => {
          const { x, y } = event;

          position.mousemove.x = x;
          position.mousemove.y = y;

          update();
        };

        const mouseupHandler = () => {
          target.removeEventListener('mousemove', mousemoveHandler, false);
          target.removeEventListener('mouseup', mouseupHandler, false);
        };

        const mousedownHandler = (event) => {
          onStart();

          position.mousedown.x = event.x;
          position.mousedown.y = event.y;

          const { x, y } = target.getBoundingClientRect();
          position.origin.x = x;
          position.origin.y = y;

          target.addEventListener('mousemove', mousemoveHandler, false);
          target.addEventListener('mouseup', mouseupHandler, false);
        }

        target.addEventListener('mousedown', mousedownHandler, false);
      }
    }
  </script>

  <script>
    const box = document.querySelector('#box');
    const resizerRight = document.querySelector('.resizer-right');
    const resizerBottom = document.querySelector('.resizer-bottom');

    const resizerLeft = document.querySelector('.resizer-left');
    const resizerTop = document.querySelector('.resizer-top');

    let width;
    let height;
    let boxLeft;
    let boxTop;
    
    new Draggable(resizerRight, {
      onStart() {
        ({ width, height } = box.getBoundingClientRect());
      },
      onMove({ deltaX, deltaY }) {
        box.style.width = `${width + deltaX}px` ;
      },
    });
    
    new Draggable(resizerBottom, {
      onStart() {
        ({ width, height } = box.getBoundingClientRect());
      },
      onMove({ deltaX, deltaY }) {
        box.style.height = `${height + deltaY}px`;
      },
    });
    
    new Draggable(resizerLeft, {
      onStart() {
        ({ x: boxLeft, width, height } = box.getBoundingClientRect());
      },
      onMove({ deltaX, deltaY }) {
        box.style.left = `${boxLeft + deltaX}px` ;
        box.style.width = `${width - deltaX}px` ;
      },
    });
    
    new Draggable(resizerTop, {
      onStart() {
        ({ y: boxTop, width, height } = box.getBoundingClientRect());
      },
      onMove({ deltaX, deltaY }) {
        box.style.top = `${boxTop + deltaY}px` ;
        box.style.height = `${height - deltaY}px` ;
      },
    });
  </script>

</body>

# 3. 参考

本章目录