I have found the solution.
I have added a hidden hexagon teleported to the body tag and that is displayed only when I start to drag any of the visible hexagons.
This is the simplest way I have found.
Hello,
I'm using interact.js to handle drag and drop on an application (Laravel / VueJS).
Here is how the datas are displayed on the screen.
- page header
- page title
- section1
- - title1
- - wrapper1 (flex)
- - - data1 in a hexagon shape
- - - data2 in a hexagon shape
- - - ...
- section2
- - title2
- - wrapper2 (flex)
- - - data1 in a hexagon shape
- - - data2 in a hexagon shape
- - - ...
- page footer
...
In each wrapper, the hexagons are displayed in a flex container and each even line in the flex container has a shift to display the hexagon like in a honeycomb.
I need to drag and drop a hexagon.
The problem is : when I click on a hexagon from the first line in the first section, the position of the dragged hexagon works fine. But when I click on a hexagon from the second line or from the next secions, the position of the dragged hexagon is far from the mouse pointer (sometimes out of the screen).
Here is my HTML code.
<div class="devices-container self-center md:self-start flex flex-col gap-2">
<div
v-for="(row, rowIndex) in itemsIndexes"
:key="'devices-row-'+rowIndex"
class="flex gap-2"
:class="{ 'ml-[104px]': rowIndex % 2 !== 0, '-mt-[58px]': rowIndex > 0 }"
>
<device-component
v-for="(endpoint, endpointIndex) in endpoints.filter(function (item, itemIndex) {
return itemIndex >= row.startIndex && itemIndex < row.endIndex;
})"
:key="'endpoint-'+endpoint.id+'-'+endpoint.active_connection.branch_id"
:endpoint="endpoint"
tag="device sortable"
:data-id="endpoint.id"
></device-component>
</div>
</div>
Here is my JS code to calculate how the hexagons have to be displayed. Not with absolute positions, but just which ids have to be displayed on which line in a section.
const refreshPage = () => {
const itemsNumber = endpoints.value.length;
if (itemsNumber > 0) {
itemsIndexes.value = [];
let deviceWidth = 200;
const clientWidth = document.querySelector('body').clientWidth - 80;
let numberOfDevicesPerOddRow = Math.floor((clientWidth + 8) / (deviceWidth + 8));
if (numberOfDevicesPerOddRow < 1) {
numberOfDevicesPerOddRow = 1;
}
let numberOfDevicesPerEvenRow = Math.floor((clientWidth + 8 - 104) / (deviceWidth + 8));
if (numberOfDevicesPerEvenRow < 1) {
numberOfDevicesPerEvenRow = 1;
}
let remainingNumber = itemsNumber;
let odd = true;
let index = 0;
while (remainingNumber > 0) {
let number = 0;
if (odd) {
number = remainingNumber < numberOfDevicesPerOddRow ? remainingNumber : numberOfDevicesPerOddRow;
} else {
number = remainingNumber < numberOfDevicesPerEvenRow ? remainingNumber : numberOfDevicesPerEvenRow;
}
itemsIndexes.value.push({ startIndex: index, endIndex: index + number });
index = index + number;
remainingNumber = remainingNumber - number;
odd = !odd;
}
}
}
When I start to drag a hexagon, I want to :
keep the dragged hexagon visible
hide all other hexagons
display each section as a simple box only with a title
What do you suggest me ?
Thanks for your help.
V
I have found the solution.
I have added a hidden hexagon teleported to the body tag and that is displayed only when I start to drag any of the visible hexagons.
This is the simplest way I have found.
Please or to participate in this conversation.