ISSUE 11: add edgeDetectionAndSnap functionality

This commit is contained in:
Ayobami
2025-07-02 20:57:31 +01:00
parent 8bcd4a014c
commit 046280e25c
2 changed files with 87 additions and 5 deletions
+1 -1
View File
@@ -113,7 +113,7 @@ export const Builder = ({ editor }) => {
imageUrl,
function (img) {
img.set({
left: 0, //Note that this starting pos is behind the sidebar
left: 240, //Note that this starting pos is behind the sidebar
top: 0,
scaleX: scaleFactor,
scaleY: scaleFactor,
+86 -4
View File
@@ -414,14 +414,96 @@ export const DockBuilder = () => {
};
function edgeDetectionAndSnap(options) {
if (this.isZoomed) {
if (editorMemo.getZoom() !== 1) {
return;
}
// TODO: Edge detection and snap to object within snap range
// TODO: Detect if the object is within the snap range of the selected object
// TODO: detect if the selected object contains dockData and dockData contains itemName of DockPanelCategories.Accessories || DockPanelCategories.BoatLift2 || DockPanelCategories.BoatLift4
// TODO: handle rotation of 0, 90, 180, 270 degrees
const selectedObj = options.target;
if (!selectedObj.dockData) return;
// TODO: Detect if the selected object is in the allowed categories
const snapCategories = [
DockPanelCategories.Accessories,
DockPanelCategories.BoatLift2,
DockPanelCategories.BoatLift4,
];
if (!snapCategories.includes(selectedObj.dockData.itemName)) return;
let closestSnapPoint = null;
let minDistance = edgeSnapThreshold;
editorMemo.forEachObject((obj) => {
if (obj === selectedObj || !obj.dockData) return;
// TODO: Only consider objects in the allowed categories
if (!snapCategories.includes(obj.dockData.itemName)) return;
// TODO: handle rotation of 0, 90, 180, 270 degrees
const rotation = obj.angle % 360;
const isRotated = rotation !== 0 && rotation !== 180;
const objCenter = obj.getCenterPoint();
const selectedCenter = selectedObj.getCenterPoint();
// Calculate potential snap points
const snapPoints = [];
// Center point
snapPoints.push(objCenter);
// Edge points
if (!isRotated || rotation === 0 || rotation === 180) {
// Horizontal edges
snapPoints.push(
new fabric.Point(objCenter.x, obj.getBoundingRect().top)
);
snapPoints.push(
new fabric.Point(
objCenter.x,
obj.getBoundingRect().top + obj.getBoundingRect().height
)
);
}
if (!isRotated || rotation === 90 || rotation === 270) {
// Vertical edges
snapPoints.push(
new fabric.Point(obj.getBoundingRect().left, objCenter.y)
);
snapPoints.push(
new fabric.Point(
obj.getBoundingRect().left + obj.getBoundingRect().width,
objCenter.y
)
);
}
// Find closest snap point
snapPoints.forEach((point) => {
const distance = Math.sqrt(
Math.pow(selectedCenter.x - point.x, 2) +
Math.pow(selectedCenter.y - point.y, 2)
);
if (distance < minDistance) {
minDistance = distance;
closestSnapPoint = point;
}
});
});
// Snap to closest point if found
if (closestSnapPoint) {
const selectedCenter = selectedObj.getCenterPoint();
selectedObj.set({
left: selectedObj.left + (closestSnapPoint.x - selectedCenter.x),
top: selectedObj.top + (closestSnapPoint.y - selectedCenter.y),
});
selectedObj.setCoords();
editorMemo.renderAll();
}
editorMemo.defaultCursor = "default";
prevPointer = null;