- 29 Сен 2021
- 1,288
- 761
- 181
- 34
Приветствую. В чем может быть проблема при перетаскивании предмета? Он просто остается на одном месте.
Использую TypeScript/NodeJs/React
Index.tsx
styles.sass
Использую TypeScript/NodeJs/React
Index.tsx
JSX:
import React, { useEffect, useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { RootState } from './data';
import { openInventory, closeInventory } from './reducer';
import rpc from '../../../../shared/rpc';
import './styles.sass';
const Inventory: React.FC = () => {
const dispatch = useDispatch();
const { isOpen, inventoryData } = useSelector((state: RootState) => state.inventory);
const [draggedItem, setDraggedItem] = useState<{ id: number; image: string } | null>(null);
const [dragStartPos, setDragStartPos] = useState<{ x: number; y: number } | null>(null);
const handleMouseMove = (event: MouseEvent) => {
if (draggedItem && dragStartPos) {
const offsetX = event.clientX - dragStartPos.x;
const offsetY = event.clientY - dragStartPos.y;
const draggingItem = document.querySelector('.inventory-item.dragging') as HTMLElement;
if (draggingItem) {
draggingItem.style.transform = `translate(${offsetX}px, ${offsetY}px)`;
}
}
};
useEffect(() => {
// Добавляем слушатель события mousemove при открытии инвентаря
document.addEventListener('mousemove', handleMouseMove);
// Удаляем слушатель события mousemove при закрытии инвентаря
return () => {
document.removeEventListener('mousemove', handleMouseMove);
};
}, [draggedItem, dragStartPos]);
const handleDragEnter = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
// Дополнительная логика при вхождении элемента
};
const handleDragLeave = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
};
const handleDragOver = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
// Дополнительная логика при перемещении над элементом
};
const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
event.preventDefault();
if (draggedItem) {
// Обработка события "падения" предмета
// Отправить RPC-запрос на сервер для обновления данных инвентаря
}
handleDragEnd();
};
const handleDragStart = (event: React.DragEvent<HTMLLIElement>, item: { id: number; image: string }) => {
console.log('handleDragStart: item', item);
console.log('handleDragStart: x', event.clientX);
console.log('handleDragStart: y', event.clientY);
event.preventDefault();
// Устанавливаем атрибут dataTransfer, чтобы предотвратить создание копии элемента
event.dataTransfer.setData('text/plain', 'dummy');
setDraggedItem(item);
setDragStartPos({ x: event.clientX, y: event.clientY });
};
const handleDragEnd = () => {
setDraggedItem(null);
setDragStartPos(null);
const draggingItem = document.querySelector('.inventory-item.dragging') as HTMLElement;
if (draggingItem) {
draggingItem.style.transform = 'translate(0, 0)';
draggingItem.classList.remove('dragging');
}
};
useEffect(() => {
rpc.register('executeRpc:inventory', async (params: { playerId: number; inventoryData: any }) => {
dispatch(openInventory(params));
});
rpc.register('executeRpc:closeinventory', async (params: { playerId: number; inventoryData: string }) => {
dispatch(closeInventory());
});
}, [dispatch]);
const inventoryContainerClass = `inventory-container ${isOpen ? 'inventory-open' : 'inventory-close'}`;
return (
<div
className={inventoryContainerClass}
onDragEnter={handleDragEnter}
onDragLeave={handleDragLeave}
onDragOver={handleDragOver}
onDrop={handleDrop}
>
<h2>Инвентарь</h2>
<ul className="inventory-list">
{inventoryData &&
inventoryData.map(({ id, image }) => (
<li
key={id}
className="inventory-item inventory-data"
draggable
onDragStart={(event) => handleDragStart(event, { id, image })}
onDragEnd={handleDragEnd}
>
{image}
</li>
))}
</ul>
</div>
);
};
export default Inventory;
styles.sass
SCSS:
.inventory-container
position: fixed
top: 50%
left: 50%
transform: translate(-50%, -50%)
background-color: rgba(255, 255, 255, 0.2)
padding: 20px
border-radius: 10px
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3)
width: 600px
height: 600px
&.inventory-close
display: none
h2
margin-bottom: 10px
.inventory-list
list-style-type: none
padding: 0
.inventory-item
margin-bottom: 20px
cursor: grab
display: flex
align-items: center
border: 2px solid #ccc
padding: 10px
border-radius: 10px
&:hover
background-color: #f0f0f0
&.dragging
opacity: 0.5
background-color: yellow
cursor: grabbing
.inventory-item img
margin-right: 10px
width: 45px
height: 45px
.inventory-data
font-weight: bold
width: 90px
height: 90px