Как реализовать функцию перетаскивания элемента с учетом его угла поворота?

Добрый день! У меня есть функция, которая отвечает за перемещение одного элемента внутри другого. Обычное перемещение работает корректно, однако при повороте элемента он начинает вести себя некорректно и "прыгает" в начале перемещения. <br/> <br/> Могу представить вам код этой функции: <br/> <pre><code class="javascript">startDrag(e, el) {
        if (this.isResizing || this.isRotating) return;

        e.preventDefault();
        this.isDragging = true;

        // Получаем текущие координаты элемента относительно родительского контейнера
        let parentRect = el.parentElement.getBoundingClientRect();
        let rect = el.getBoundingClientRect();

        // Получаем угол поворота элемента
        let transform = el.style.transform || 'rotate(0deg)';
        let angle = parseFloat(transform.match(/rotate\(([-\d.]+)deg\)/)[1]) || 0;
        let rad = (angle * Math.PI) / 180; // Переводим угол в радианы

        // Центр элемента относительно родительского контейнера
        let centerX = rect.left + rect.width / 2 - parentRect.left;
        let centerY = rect.top + rect.height / 2 - parentRect.top;

        // Смещение курсора относительно центра элемента
        let mouseOffsetX = e.clientX - parentRect.left - centerX;
        let mouseOffsetY = e.clientY - parentRect.top - centerY;

        // Корректировка смещения с учётом угла поворота
        let rotatedOffsetX = mouseOffsetX * Math.cos(-rad) - mouseOffsetY * Math.sin(-rad);
        let rotatedOffsetY = mouseOffsetX * Math.sin(-rad) + mouseOffsetY * Math.cos(-rad);

        let onMouseMove = (e) =&gt; {
            if (!this.isDragging) return;

            // Получаем новые координаты курсора относительно родительского контейнера
            let newMouseX = e.clientX - parent
  • 8 февраля 2025 г. 23:14
Ответы на вопрос 2
Для корректной реализации функции перетаскивания элемента с учетом его угла поворота, необходимо обработать смещения курсора относительно центра элемента с учетом данной трансформации.

Ваш представленный код выглядит достаточно хорошо, но давайте завершим его и добавим все необходимые шаги для обработки события `mousemove`, чтобы предотвратить "прыжки" элемента при старте перетаскивания.

Давайте я дополню вашу функцию и добавлю обработку события `mouseup`, чтобы завершить процесс перетаскивания:

```javascript
startDrag(e, el) {
    if (this.isResizing || this.isRotating) return;

    e.preventDefault();
    this.isDragging = true;

    // Получаем текущие координаты элемента относительно родительского контейнера
    let parentRect = el.parentElement.getBoundingClientRect();
    let rect = el.getBoundingClientRect();

    // Получаем угол поворота элемента
    let transform = el.style.transform || 'rotate(0deg)';
    let angle = parseFloat(transform.match(/rotate\(([-\d.]+)deg\)/)[1]) || 0;
    let rad = (angle * Math.PI) / 180; // Переводим угол в радианы

    // Центр элемента относительно родительского контейнера
    let centerX = rect.left + rect.width / 2 - parentRect.left;
    let centerY = rect.top + rect.height / 2 - parentRect.top;

    // Смещение курсора относительно центра элемента
    let mouseOffsetX = e.clientX - parentRect.left - centerX;
    let mouseOffsetY = e.clientY - parentRect.top - centerY;

    // Корректировка смещения с учётом угла поворота
    let rotatedOffsetX = mouseOffsetX * Math.cos(-rad) - mouseOffsetY * Math.sin(-rad);
    let rotatedOffsetY = mouseOffsetX * Math.sin(-rad) + mouseOffsetY * Math.cos(-rad);

    // Начальная позиция элемента при старте перетаскивания
    let initialLeft = el.offsetLeft;
    let initialTop = el.offsetTop;

    // Обработчик перемещения мыши
    const onMouseMove = (e) => {
        if (!this.isDragging) return;

        // Получаем новые координаты, добавляя смещение
        let newLeft = initialLeft + rotatedOffsetX;
        let newTop = initialTop + rotatedOffsetY;

        // Обновляем позицию элемента
        el.style.left = newLeft + 'px';
        el.style.top = newTop + 'px';
    };

    const onMouseUp = () => {
        this.isDragging = false;
        document.removeEventListener('mousemove', onMouseMove);
        document.removeEventListener('mouseup', onMouseUp);
    };

    // Добавляем обработчики событий
    document.addEventListener('mousemove', onMouseMove);
    document.addEventListener('mouseup', onMouseUp);
}
```

### Объяснение:

1. **Расчет смещения**: Мы начали с вычисления смещения курсора относительно центра элемента, учитывая угол его вращения.

2. **Сохранение начальных координат**: Мы сохраняем начальные координаты элемента, чтобы обновлять их при перетаскивании.

3. **Обработчик `mousemove`**: В этом обработчике мы обновляем позицию элемента, используя скорректированное смещение. Это позволит вам перемещать элемент, основываясь на текущем положении курсора и его смещении.

4. **Обработчик `mouseup`**: Этот обработчик убирает флаг `isDragging` и удаляет обработчики событий, когда вы отпускаете кнопку мыши.

Теперь, если вы произведете поворот элемента и начнете его перетаскивать, он не "прыгнет", а начнет двигаться корректно с учетом угла поворота.
в начале перетаскивания запомни координаты курсора и сдвиг элемента <br/> при перетаскивании изменяй сдвиг на величину смещения курсора
Похожие вопросы