smithery/jhlee0409

canvas-debugging

Debug canvas layout issues, grid positioning problems, and component overlap. Use when troubleshooting Konva canvas rendering, grid constraints, snap-to-grid behavior, or visual layout mismatches. Includes Canvas→CSS Grid conversion debugging.

Installation

$ npx skills add smithery/jhlee0409 --skill canvas-debugging

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery/jhlee0409 · top by installs.

npx skills add smithery/jhlee0409

Browse all from smithery/jhlee0409

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Skill metadata

Parsed from SKILL.md frontmatter.

Allowed toolsRead, Glob, Grep

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 11,010 B
  • docs SUMMARY.md 269 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

Canvas Debugging Skill

Visual Layout Builder의 Konva 기반 Canvas 시스템 디버깅을 위한 전문 스킬입니다. Grid 위치 계산, 컴포넌트 충돌, 스냅 동작 문제를 해결합니다.

When to Use

  • Canvas에서 컴포넌트 위치가 잘못 표시될 때
  • Grid 스냅이 예상대로 동작하지 않을 때
  • 컴포넌트 겹침(overlap) 문제 발생 시
  • Canvas→CSS Grid 변환 오류 디버깅
  • Breakpoint 전환 시 레이아웃 문제
  • 드래그 앤 드롭 동작 이상
  • components/canvas/ 관련 이슈

Canvas System Architecture

Core Components

components/canvas/
├── KonvaCanvas.tsx      # Main canvas with Konva Stage/Layer
├── ComponentNode.tsx    # Individual component rendering
├── ComponentPreview.tsx # Drag preview
├── Canvas.tsx           # Canvas + component management
└── index.ts             # Public exports

Canvas Coordinate System

Canvas Grid (0-based coordinates)
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│0,0│1,0│2,0│3,0│4,0│5,0│6,0│7,0│8,0│9,0│10 │11 │ Row 0
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
│0,1│1,1│2,1│...│...│...│...│...│...│...│...│11,1 Row 1
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
│...│...│...│...│...│...│...│...│...│...│...│...│ ...
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘

CanvasLayout:
- x: Grid column start (0-based)
- y: Grid row start (0-based)
- width: Number of columns to span
- height: Number of rows to span

CSS Grid Conversion (1-based)

// Canvas (0-based) → CSS Grid (1-based)
gridColumn: `${x + 1} / ${x + width + 1}`
gridRow: `${y + 1} / ${y + height + 1}`
gridArea: `${y + 1} / ${x + 1} / ${y + height + 1} / ${x + width + 1}`

// Example: Canvas { x: 0, y: 0, width: 12, height: 1 }
// → CSS Grid: "1 / 1 / 2 / 13" (grid-area format)

Common Issues & Solutions

Issue 1: Component Position Mismatch

Symptom: Component appears in wrong position after drag

Debug Steps:

// 1. Check pixel-to-grid conversion
const cellWidth = canvasWidth / gridCols
const cellHeight = canvasHeight / gridRows

console.log('Cell dimensions:', { cellWidth, cellHeight })

// 2. Verify snap calculation
const gridX = Math.floor(pixelX / cellWidth)
const gridY = Math.floor(pixelY / cellHeight)

console.log('Grid position:', { gridX, gridY })

// 3. Check responsiveCanvasLayout
console.log('Component layout:', component.responsiveCanvasLayout?.[breakpoint])

Common Causes:

  • Math.round() vs Math.floor() inconsistency
  • Canvas padding/margin not accounted for
  • Breakpoint mismatch (editing mobile, viewing desktop)

Issue 2: Component Overlap Detection

Symptom: Components overlap but no warning shown

Debug with schema-validation.ts:

import { validateSchema } from '@/lib/schema-validation'

const result = validateSchema(schema)

// Check for overlap warnings
const overlapWarnings = result.warnings?.filter(
  w => w.code === 'CANVAS_COMPONENTS_OVERLAP'
)

console.log('Overlapping components:', overlapWarnings)

Overlap Detection Logic:

function checkOverlap(a: CanvasLayout, b: CanvasLayout): boolean {
  // Check if rectangles overlap
  return !(
    a.x + a.width <= b.x ||   // a is left of b
    b.x + b.width <= a.x ||   // b is left of a
    a.y + a.height <= b.y ||  // a is above b
    b.y + b.height <= a.y     // b is above a
  )
}

Issue 3: Grid Snap Not Working

Symptom: Components don't snap to grid when dragged

Debug Steps:

// lib/snap-to-grid.ts
export function snapToGrid(
  x: number,
  y: number,
  cellWidth: number,
  cellHeight: number
): { x: number; y: number } {
  console.log('Input:', { x, y })
  console.log('Cell size:', { cellWidth, cellHeight })

  const snappedX = Math.round(x / cellWidth) * cellWidth
  const snappedY = Math.round(y / cellHeight) * cellHeight

  console.log('Snapped:', { snappedX, snappedY })

  return { x: snappedX, y: snappedY }
}

Check Grid Constraints:

import { GRID_CONSTRAINTS } from '@/lib/schema-utils'

console.log('Grid constraints:', {
  minCols: GRID_CONSTRAINTS.minCols,  // 4
  maxCols: GRID_CONSTRAINTS.maxCols,  // 24
  minRows: GRID_CONSTRAINTS.minRows,  // 4
  maxRows: GRID_CONSTRAINTS.maxRows   // 50
})

Issue 4: Canvas Out of Bounds

Symptom: Component placed outside grid bounds

Validation Code: CANVASOUTOF_BOUNDS

function validateBounds(layout: CanvasLayout, gridCols: number, gridRows: number) {
  const issues = []

  if (layout.x < 0 || layout.y < 0) {
    issues.push('CANVAS_NEGATIVE_COORDINATE')
  }

  if (layout.x + layout.width > gridCols) {
    issues.push(`Out of bounds: x(${layout.x}) + width(${layout.width}) > gridCols(${gridCols})`)
  }

  if (layout.y + layout.height > gridRows) {
    issues.push(`Out of bounds: y(${layout.y}) + height(${layout.height}) > gridRows(${gridRows})`)
  }

  return issues
}

Issue 5: Breakpoint Layout Inheritance

Symptom: Component has layout in mobile but not in desktop

Debug:

// Check responsiveCanvasLayout for all breakpoints
const component = schema.components.find(c => c.id === 'c1')

console.log('Canvas layouts by breakpoint:')
for (const bp of schema.breakpoints) {
  const layout = component?.responsiveCanvasLayout?.[bp.name]
  console.log(`  ${bp.name}:`, layout || 'MISSING')
}

// After normalization
const normalized = normalizeSchema(schema)
const normalizedComponent = normalized.components.find(c => c.id === 'c1')

console.log('After normalization:')
for (const bp of normalized.breakpoints) {
  const layout = normalizedComponent?.responsiveCanvasLayout?.[bp.name]
  console.log(`  ${bp.name}:`, layout || 'STILL MISSING')
}

Issue 6: CSS Grid Conversion Errors

Symptom: AI-generated code doesn't match canvas layout

Debug canvas-to-grid.ts:

import { canvasToGridPositions } from '@/lib/canvas-to-grid'

const positions = canvasToGridPositions(
  schema.components,
  'desktop',
  12,  // gridCols
  8    // gridRows
)

console.log('Grid positions:')
positions.forEach(p => {
  console.log(`  ${p.componentId}:`)
  console.log(`    gridColumn: ${p.gridColumn}`)
  console.log(`    gridRow: ${p.gridRow}`)
  console.log(`    gridArea: ${p.gridArea}`)
})

Expected Format:

c1 (Header):
  gridColumn: "1 / 13"    // Full width (12 cols)
  gridRow: "1 / 2"        // 1 row height
  gridArea: "1 / 1 / 2 / 13"

Visual Layout Descriptor Debugging

import { describeVisualLayout } from '@/lib/visual-layout-descriptor'

const description = describeVisualLayout(
  schema.components,
  'desktop',
  12,
  8
)

console.log('Summary:', description.summary)
console.log('\nRow by row:')
description.rowByRow.forEach(row => console.log('  ', row))

console.log('\nSpatial relationships:')
description.spatialRelationships.forEach(rel => console.log('  ', rel))

console.log('\nImplementation hints:')
description.implementationHints.forEach(hint => console.log('  ', hint))

Canvas Validation Codes

Code Type Description
CANVASLAYOUTORDER_MISMATCH Warning Canvas order ≠ DOM order
COMPLEXGRIDLAYOUT_DETECTED Warning Side-by-side components
CANVASCOMPONENTSOVERLAP Warning Components overlapping
CANVASOUTOF_BOUNDS Warning Outside grid bounds
CANVASZEROSIZE Warning width=0 or height=0
CANVASNEGATIVECOORDINATE Error x<0 or y<0
CANVASFRACTIONALCOORDINATE Warning Non-integer coordinates
CANVASCOMPONENTNOTINLAYOUT Warning Not in layout.components
MISSINGCANVASLAYOUT Warning No canvas position

Debugging Konva Rendering

Stage/Layer Issues

// In KonvaCanvas.tsx
useEffect(() => {
  console.log('Stage dimensions:', {
    width: stageRef.current?.width(),
    height: stageRef.current?.height()
  })

  console.log('Layer children:', layerRef.current?.children?.length)
}, [])

Component Node Position

// In ComponentNode.tsx
const handleDragEnd = (e: Konva.KonvaEventObject<DragEvent>) => {
  const node = e.target
  console.log('Drag end position:', {
    x: node.x(),
    y: node.y(),
    absolutePosition: node.absolutePosition()
  })

  // Convert to grid
  const gridX = Math.floor(node.x() / cellWidth)
  const gridY = Math.floor(node.y() / cellHeight)
  console.log('Grid position:', { gridX, gridY })
}

Grid Constraint Validation

import { calculateMinimumGridSize } from '@/lib/grid-constraints'

// Check if grid can be reduced
const { minCols, minRows } = calculateMinimumGridSize(
  schema.components,
  'desktop'
)

console.log('Minimum required grid:', { minCols, minRows })
console.log('Current grid:', {
  cols: breakpoint.gridCols,
  rows: breakpoint.gridRows
})

if (breakpoint.gridCols < minCols || breakpoint.gridRows < minRows) {
  console.warn('Grid too small for components!')
}

Quick Debug Checklist

# 1. Check current breakpoint
console.log('Current breakpoint:', currentBreakpoint)

# 2. Verify grid configuration
console.log('Grid config:', breakpoint)

# 3. Log all component positions
schema.components.forEach(c => {
  const layout = c.responsiveCanvasLayout?.[currentBreakpoint]
  console.log(`${c.id} (${c.name}):`, layout || 'NO LAYOUT')
})

# 4. Run validation
const result = validateSchema(schema)
console.log('Validation:', result)

# 5. Check CSS Grid output
const gridPositions = canvasToGridPositions(
  schema.components,
  currentBreakpoint,
  breakpoint.gridCols,
  breakpoint.gridRows
)
console.log('CSS Grid positions:', gridPositions)

Reference Files

  • components/canvas/KonvaCanvas.tsx - Canvas 렌더링
  • components/canvas/ComponentNode.tsx - 컴포넌트 노드
  • lib/canvas-to-grid.ts - Canvas→CSS Grid 변환
  • lib/canvas-utils.ts - Canvas 유틸리티
  • lib/grid-constraints.ts - Grid 제약 조건
  • lib/snap-to-grid.ts - 스냅 로직
  • lib/schema-validation.ts - Canvas 검증 로직
  • lib/visual-layout-descriptor.ts - 시각적 레이아웃 설명