fix: transform screen coordinates to SVG space for isPointInFill()
CRITICAL FIX: isPointInFill() requires points in SVG coordinate space, not screen coordinates. Use getScreenCTM().inverse() to transform screen coordinates before hit testing. The previous commit broke region detection because it was passing screen pixel coordinates directly to isPointInFill(), which expects SVG viewBox coordinates. Now properly: 1. Get SVG's screen transformation matrix (getScreenCTM) 2. Invert it to get screen→SVG transform 3. Transform each test point before calling isPointInFill() 4. Fallback to bounding box detection if CTM unavailable This fixes the "zoom box is totally gone" issue. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
e255ce2c6f
commit
4c933be48a
|
|
@ -180,22 +180,39 @@ export function useRegionDetection(options: UseRegionDetectionOptions): UseRegio
|
|||
let overlaps = false
|
||||
let cursorInRegion = false
|
||||
|
||||
// Create SVG point for reuse
|
||||
const svgPoint = svgElement.createSVGPoint()
|
||||
// Get the transformation matrix to convert screen coordinates to SVG coordinates
|
||||
const screenCTM = svgElement.getScreenCTM()
|
||||
if (!screenCTM) {
|
||||
// Fallback to bounding box if we can't get coordinate transform
|
||||
overlaps = true
|
||||
cursorInRegion =
|
||||
cursorClientX >= regionLeft &&
|
||||
cursorClientX <= regionRight &&
|
||||
cursorClientY >= regionTop &&
|
||||
cursorClientY <= regionBottom
|
||||
} else {
|
||||
const inverseMatrix = screenCTM.inverse()
|
||||
|
||||
// Check if cursor point is inside the actual region path
|
||||
svgPoint.x = cursorClientX
|
||||
svgPoint.y = cursorClientY
|
||||
cursorInRegion = regionPath.isPointInFill(svgPoint)
|
||||
// Create SVG point for reuse
|
||||
let svgPoint = svgElement.createSVGPoint()
|
||||
|
||||
// Sample points in detection box to check for overlap
|
||||
for (let i = 0; i < samplesPerSide && !overlaps; i++) {
|
||||
for (let j = 0; j < samplesPerSide && !overlaps; j++) {
|
||||
svgPoint.x = boxLeft + i * sampleStep
|
||||
svgPoint.y = boxTop + j * sampleStep
|
||||
if (regionPath.isPointInFill(svgPoint)) {
|
||||
overlaps = true
|
||||
break
|
||||
// Check if cursor point is inside the actual region path
|
||||
svgPoint.x = cursorClientX
|
||||
svgPoint.y = cursorClientY
|
||||
svgPoint = svgPoint.matrixTransform(inverseMatrix)
|
||||
cursorInRegion = regionPath.isPointInFill(svgPoint)
|
||||
|
||||
// Sample points in detection box to check for overlap
|
||||
for (let i = 0; i < samplesPerSide && !overlaps; i++) {
|
||||
for (let j = 0; j < samplesPerSide && !overlaps; j++) {
|
||||
svgPoint = svgElement.createSVGPoint()
|
||||
svgPoint.x = boxLeft + i * sampleStep
|
||||
svgPoint.y = boxTop + j * sampleStep
|
||||
svgPoint = svgPoint.matrixTransform(inverseMatrix)
|
||||
if (regionPath.isPointInFill(svgPoint)) {
|
||||
overlaps = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue