/** * Utility for debugging SVG rendering issues */ /** * Adds a visible debug overlay to the SVG to test z-index rendering * @param {SVGElement} svgElement - The SVG DOM element */ export function addDebugOverlay(svgElement) { if (!svgElement) return; const svgNS = "http://www.w3.org/2000/svg"; // Create a debug group at the highest level const debugGroup = document.createElementNS(svgNS, "g"); debugGroup.setAttribute("id", "debug-overlay"); debugGroup.setAttribute( "style", "pointer-events: none; z-index: 10000; position: relative;" ); // Add a semi-transparent rectangle across the entire SVG const svgWidth = svgElement.viewBox?.baseVal?.width || 1000; const svgHeight = svgElement.viewBox?.baseVal?.height || 1000; const rect = document.createElementNS(svgNS, "rect"); rect.setAttribute("x", "0"); rect.setAttribute("y", "0"); rect.setAttribute("width", svgWidth.toString()); rect.setAttribute("height", svgHeight.toString()); rect.setAttribute("fill", "rgba(255, 255, 0, 0.1)"); rect.setAttribute("stroke", "none"); // Add some test circles at fixed positions const testPositions = [ { x: 50, y: 50, color: "red" }, { x: 150, y: 150, color: "blue" }, { x: 250, y: 250, color: "green" }, { x: 350, y: 350, color: "purple" }, ]; testPositions.forEach((pos, i) => { const testCircle = document.createElementNS(svgNS, "circle"); testCircle.setAttribute("cx", pos.x.toString()); testCircle.setAttribute("cy", pos.y.toString()); testCircle.setAttribute("r", "20"); testCircle.setAttribute("fill", pos.color); testCircle.setAttribute("fill-opacity", "0.5"); testCircle.setAttribute("stroke", "black"); testCircle.setAttribute("stroke-width", "2"); testCircle.setAttribute("class", "debug-circle"); debugGroup.appendChild(testCircle); }); // Add the debug group to the SVG svgElement.appendChild(debugGroup); console.log("Debug overlay added to SVG"); } /** * Checks if clue points are visible and fixes rendering issues * @param {SVGElement} svgElement - The SVG DOM element */ export function fixCluePointsRendering(svgElement) { if (!svgElement) return; // Find the clue points overlay group let overlayGroup = svgElement.querySelector(".clue-points-overlay"); // If no overlay group exists, create one if (!overlayGroup) { console.log("No clue points overlay found, creating one"); overlayGroup = document.createElementNS("http://www.w3.org/2000/svg", "g"); overlayGroup.setAttribute("class", "clue-points-overlay"); overlayGroup.setAttribute( "style", "pointer-events: all !important; z-index: 9999 !important; position: relative !important;" ); svgElement.appendChild(overlayGroup); } // Find all clue points const cluePoints = svgElement.querySelectorAll(".clue-point"); const clickAreas = svgElement.querySelectorAll(".clue-click-area"); console.log( `Found ${cluePoints.length} clue points and ${clickAreas.length} click areas` ); // Ensure all clue points are in the overlay group and have proper styles cluePoints.forEach((point, i) => { // Clone the point to remove any existing event handlers and styling issues const newPoint = point.cloneNode(true); // Apply explicit styles to ensure visibility newPoint.setAttribute( "style", "fill: #ff9800; stroke: #e65100; stroke-width: 3px; " + "pointer-events: all !important; cursor: pointer !important; " + "z-index: 9999 !important; position: relative !important; " + "r: 14px; fill-opacity: 1; stroke-opacity: 1; " + "filter: drop-shadow(0px 0px 5px rgba(0, 0, 0, 0.7));" ); // Move to overlay group if (point.parentNode !== overlayGroup) { // Remove from current location if (point.parentNode) { point.parentNode.removeChild(point); } // Add to overlay group overlayGroup.appendChild(newPoint); } }); // Move the overlay group to be the last child of the SVG svgElement.appendChild(overlayGroup); console.log("Clue points rendering fixed"); }