interact(".piece").draggable({ modifiers: [ interact.modifiers.snap({ targets: [ // 1. Match the grid to your square sizes (50px x 50px) interact.snappers.grid({ x: 104, y: 104 }), ], range: Infinity, // 2. Snap by the top-left corner (0,0) of the piece to align with square borders relativePoints: [{ x: 0, y: 0 }], // 3. Keep the element constrained within the 400x400 board boundaries offset: "parent", }), interact.modifiers.restrictRect({ restriction: "parent", endOnly: false, }), ], listeners: { move(event) { const target = event.target; const x = (parseFloat(target.getAttribute("data-x")) || 0) + event.dx; const y = (parseFloat(target.getAttribute("data-y")) || 0) + event.dy; console.log("console", x, y); target.style.transform = `translate(${x}px, ${y}px)`; target.setAttribute("data-x", x); target.setAttribute("data-y", y); }, end(event) { // Optional: Calculate and log the final algebraic notation (e.g., e4, a1) const target = event.target; const currentX = (parseFloat(target.getAttribute("data-x")) || 0) + 200; // Adding initial left offset const currentY = (parseFloat(target.getAttribute("data-y")) || 0) + 200; // Adding initial top offset const files = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "k"]; const fileIndex = Math.floor(currentX / 50); const rankIndex = 8 - Math.floor(currentY / 50); if (files[fileIndex] && rankIndex >= 1 && rankIndex <= 8) { console.log(`Piece landed on: ${files[fileIndex]}${rankIndex}`); } }, }, });