HTML5 Javascript Canvas : Collision - Drag And Drop
Tags: javascript, webdev, canvas
Published: 2022-02-12 09:25:24

> Читать снизу вверх

Продолжение записей
[spsoi](https://dev.to/spsoi/html5-canvas-drag-and-drop-592i)

Код берём отсюда
[jsfiddle.net](https://jsfiddle.net/Spsoi/5say6d43/17/)

При наведении на элемент канваса, `cursor = pointer`

[jsfiddle.net](https://jsfiddle.net/Spsoi/cqrh72m0/16/)

```javascript
function changeCursor(event) { // постоянно отрисовываем
    console.log('changeCursor');
    let mouse = coordinateMouseByCanvas(event); // получаем координаты мыши
    console.log(mouse);
    for (element of elements) {
        x_final = element.left + element.width; // правый край элемента по x
        y_final = element.top + element.height; // низ края элемента по y
        if (mouse.x > element.left && mouse.x < x_final && mouse.y > element.top && mouse.y < y_final) {
            document.body.style.cursor = 'pointer';
            break;
        } else {
            document.body.style.cursor = 'default';
        }
    }
}
```

Проверяем, если мышка отпущена над элементом то передвигаемый элемент принимает координаты того элемента.

Если мышка не над элементом, проверяем сам элемент находится ли над каким либо элементом.

[jsfiddle.net](https://jsfiddle.net/Spsoi/cqrh72m0/8/)

```javascript
function releaseMouseButton (event) { // отпускаем мышку
    // 5
    let mouse = coordinateMouseByCanvas(event);
    if (!elementClick) { return }
    elementClickLeftEdge = elementClick.left; // левая сторона
    elementClickRightEdge = elementClick.left + elementClick.width; // правая сторона

    elementClickTopEdge = elementClick.top; // верхняя сторона
    elementClickBottomEdge = elementClick.top + elementClick.height; // нижняя сторона

    let elementFound = false;
    elements.forEach ( function (element) { // где находятся элементы

        x_final = element.left + element.width; // правый край элемента по x
        y_final = element.top + element.height; // низ края элемента по y

        // Мышка над элементом
        if (mouse.x > element.left && mouse.x < x_final && mouse.y > element.top && mouse.y < y_final) { //!*
            elementClick.top = element.top;
            elementClick.left = element.left;
            window.requestAnimationFrame(draw);
            elementFound = true;
        }

        // Мышка не над элементом, но передвигаемый элемент над элементом
        if (elementFound == false && elementClickTopEdge < y_final && // Меньше координата нижнее ребра
            elementClickTopEdge > element.top && 
            elementClickLeftEdge < x_final && 
            elementClickRightEdge > element.left) { // Меньше координата левого ребра

            elementClick.top = element.top;
            elementClick.left = element.left;
            window.requestAnimationFrame(draw);
        }
        
    });
    elementClick = null;
    
}
}
```

Теперь при событии когда мы левую кнопку мыши отпускаем, если наш передвигаемый элемент находится над другим элементом, он должен перенять его координаты (слиться с ним)

Для этого дополним функцию `releaseMouseButton`.

Определим координаты перетаскиваемого элемента, и элемента под ним.

[jsfiddle.net](https://jsfiddle.net/Spsoi/cqrh72m0/3/)
```javascript
function releaseMouseButton (event) { // отпускаем мышку
    // 5
    if (!elementClick) { return }
    elementClickLeftEdge = elementClick.left; // левая сторона
    elementClickRightEdge = elementClick.left + elementClick.width; // правая сторона

    elementClickTopEdge = elementClick.top; // верхняя сторона
    elementClickBottomEdge = elementClick.top + elementClick.height; // нижняя сторона

    elements.forEach ( function (element) { // где находятся элементы

        x_final = element.left + element.width; // правый край элемента по x
        y_final = element.top + element.height; // низ края элемента по y
        if ( elementClickTopEdge < y_final && // Меньше координата нижнего ребра
            elementClickTopEdge > element.top && 
            elementClickLeftEdge < x_final && 
            elementClickRightEdge > element.left) { // Меньше координата левого ребра
            
            elementClick.top = element.top;
            elementClick.left = element.left;
            window.requestAnimationFrame(draw);
        }
        
    });
    elementClick = null;
    
}
```

Для начала, выносим получение координат мыши над canvas, в отдельную функцию:
```javascript
function coordinateMouseByCanvas (event) {
    let infoPos = canvas.getBoundingClientRect(); // возвращает размер элемента и его позицию относительно viewport 
    x_click = event.clientX - infoPos.left; // пиксель по x внутри тэга canvas на который нажали
    y_click = event.clientY - infoPos.top; // пиксель по y внутри тэга canvas на который нажали
    return {x: x_click, y:y_click}
}
```