frontend/semag/infi/scripts/MergeEngine.js
2024-08-07 02:51:11 -04:00

152 lines
5.7 KiB
JavaScript

// Add event listener to the canvas to detect element drops
canvas.addEventListener("mouseup", function (event) {
const droppedElement = event.target;
const canvasRect = canvas.getBoundingClientRect();
const x = event.clientX - canvasRect.left;
const y = event.clientY - canvasRect.top;
// Check if the dropped element is an element on the canvas
if (droppedElement.classList.contains("element")) {
// Check if the dropped element overlaps with any other element
const elements = canvas.querySelectorAll(".element");
elements.forEach((element) => {
if (
element !== droppedElement &&
isOverlapping(droppedElement, element)
) {
// Merge the elements if they can be merged
const mergedElement = mergeElements(droppedElement, element);
if (mergedElement) {
// Remove the original elements
droppedElement.remove();
element.remove();
// Place the merged element at the drop location without snapping
const mergedElementRect = mergedElement.getBoundingClientRect();
const offsetX = mergedElementRect.width / 2;
const offsetY = mergedElementRect.height / 2;
mergedElement.style.position = "absolute";
mergedElement.style.left = `${x - offsetX}px`;
mergedElement.style.top = `${y - offsetY}px`;
// Add animation
requestAnimationFrame(() => {
mergedElement.style.transform = "scale(1.5)";
mergedElement.style.transition = "transform 0.5s ease";
});
// Listen for transition end event
mergedElement.addEventListener(
"transitionend",
function transitionEndHandler() {
// Remove animation properties after animation is complete
mergedElement.style.transition = "none";
mergedElement.style.transform = "scale(1)";
// Remove event listener
mergedElement.removeEventListener(
"transitionend",
transitionEndHandler
);
}
);
canvas.appendChild(mergedElement);
}
}
});
}
});
// Function to check if two elements overlap
function isOverlapping(element1, element2) {
const rect1 = element1.getBoundingClientRect();
const rect2 = element2.getBoundingClientRect();
return !(
rect1.right < rect2.left ||
rect1.left > rect2.right ||
rect1.bottom < rect2.top ||
rect1.top > rect2.bottom
);
}
// Function to merge two elements
function mergeElements(element1, element2) {
const element1Type = element1.id;
const element2Type = element2.id;
// Check if merge rule exists for the combination of the two elements
if (mergeRules[element1Type] && mergeRules[element1Type][element2Type]) {
const newElementType = mergeRules[element1Type][element2Type];
// Remove emoji from the merged element type
const newElementTypeWithoutEmoji = newElementType
.replace(/[^\x00-\x7F]/g, "")
.replace(" ", "")
.toLowerCase(); // Remove non-ASCII characters (emojis)
// Create a new element representing the merged result
const mergedElement = document.createElement("div");
mergedElement.classList.add("element");
mergedElement.id = newElementTypeWithoutEmoji
.replace(" ", "")
.toLowerCase(); // Assign the ID without emoji
mergedElement.textContent = newElementType;
// Add the merged element to the sidebar if it doesn't already exist
const sidebar = document.getElementById("sidebar");
const elemId = `#${newElementTypeWithoutEmoji
.replace(" ", "")
.toLowerCase()}`;
if (!sidebar.querySelector(elemId)) {
const newElementDiv = document.createElement("div");
newElementDiv.classList.add("element");
newElementDiv.id = newElementTypeWithoutEmoji
.replace(" ", "")
.toLowerCase();
newElementDiv.textContent = newElementType;
sidebar.appendChild(newElementDiv);
newElementDiv.addEventListener("mousedown", function (event) {
createDraggableClone(newElementDiv, event);
});
}
// Return the merged element
return mergedElement;
} else if (
mergeRules[element2Type] &&
mergeRules[element2Type][element1Type]
) {
const newElementType = mergeRules[element2Type][element1Type];
// Remove emoji from the merged element type
const newElementTypeWithoutEmoji = newElementType
.replace(/[^\x00-\x7F]/g, "")
.replace(" ", "")
.toLowerCase(); // Remove non-ASCII characters (emojis)
// Create a new element representing the merged result
const mergedElement = document.createElement("div");
mergedElement.classList.add("element");
mergedElement.id = newElementTypeWithoutEmoji
.replace(" ", "")
.toLowerCase(); // Assign the ID without emoji
mergedElement.textContent = newElementType;
// Add the merged element to the sidebar if it doesn't already exist
const sidebar = document.getElementById("sidebar");
const elemId = `#${newElementTypeWithoutEmoji
.replace(" ", "")
.toLowerCase()}`;
if (!sidebar.querySelector(elemId)) {
const newElementDiv = document.createElement("div");
newElementDiv.classList.add("element");
newElementDiv.id = newElementTypeWithoutEmoji
.replace(" ", "")
.toLowerCase();
newElementDiv.textContent = newElementType;
sidebar.appendChild(newElementDiv);
newElementDiv.addEventListener("mousedown", function (event) {
createDraggableClone(newElementDiv, event);
});
}
return mergedElement;
} else {
// No merge rule exists for the combination of the two elements
return null;
}
}