@hypen-space/web 0.4.2 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/canvas/accessibility.d.ts +47 -0
- package/dist/canvas/events.d.ts +87 -0
- package/dist/canvas/index.d.ts +11 -0
- package/dist/canvas/index.js +32 -14
- package/dist/canvas/index.js.map +7 -7
- package/dist/canvas/input.d.ts +63 -0
- package/dist/canvas/input.js +14 -2
- package/dist/canvas/input.js.map +3 -3
- package/dist/canvas/layout.d.ts +10 -0
- package/dist/canvas/layout.js +17 -12
- package/dist/canvas/layout.js.map +4 -4
- package/dist/canvas/paint.d.ts +14 -0
- package/dist/canvas/paint.js +3 -2
- package/dist/canvas/paint.js.map +4 -4
- package/dist/canvas/renderer.d.ts +99 -0
- package/dist/canvas/renderer.js +32 -14
- package/dist/canvas/renderer.js.map +7 -7
- package/dist/canvas/text.d.ts +22 -0
- package/dist/canvas/text.js +2 -2
- package/dist/canvas/text.js.map +2 -2
- package/dist/canvas/types.d.ts +96 -0
- package/dist/canvas/utils.d.ts +44 -0
- package/dist/client.d.ts +19 -0
- package/dist/client.js +106 -43
- package/dist/client.js.map +12 -11
- package/dist/dom/applicators/advanced-layout.d.ts +5 -0
- package/dist/dom/applicators/advanced-layout.js +1 -114
- package/dist/dom/applicators/advanced-layout.js.map +4 -5
- package/dist/dom/applicators/background.d.ts +5 -0
- package/dist/dom/applicators/border.d.ts +5 -0
- package/dist/dom/applicators/color.d.ts +5 -0
- package/dist/dom/applicators/display.d.ts +5 -0
- package/dist/dom/applicators/effects.d.ts +5 -0
- package/dist/dom/applicators/events.d.ts +8 -0
- package/dist/dom/applicators/events.js +55 -3
- package/dist/dom/applicators/events.js.map +3 -3
- package/dist/dom/applicators/font.d.ts +29 -0
- package/dist/dom/applicators/index.d.ts +76 -0
- package/dist/dom/applicators/index.js +55 -9
- package/dist/dom/applicators/index.js.map +4 -4
- package/dist/dom/applicators/layout.d.ts +10 -0
- package/dist/dom/applicators/margin.d.ts +11 -0
- package/dist/dom/applicators/padding.d.ts +11 -0
- package/dist/dom/applicators/size.d.ts +14 -0
- package/dist/dom/applicators/transform.d.ts +5 -0
- package/dist/dom/applicators/transition.d.ts +5 -0
- package/dist/dom/applicators/types.d.ts +6 -0
- package/dist/dom/applicators/typography.d.ts +5 -0
- package/dist/dom/canvas/index.d.ts +12 -0
- package/dist/dom/components/app.d.ts +8 -0
- package/dist/dom/components/app.js +55 -0
- package/dist/dom/components/app.js.map +10 -0
- package/dist/dom/components/audio.d.ts +5 -0
- package/dist/dom/components/avatar.d.ts +5 -0
- package/dist/dom/components/badge.d.ts +5 -0
- package/dist/dom/components/button.d.ts +9 -0
- package/dist/dom/components/card.d.ts +5 -0
- package/dist/dom/components/center.d.ts +9 -0
- package/dist/dom/components/checkbox.d.ts +5 -0
- package/dist/dom/components/column.d.ts +8 -0
- package/dist/dom/components/container.d.ts +5 -0
- package/dist/dom/components/divider.d.ts +5 -0
- package/dist/dom/components/grid.d.ts +7 -0
- package/dist/dom/components/heading.d.ts +5 -0
- package/dist/dom/components/hypenapp.d.ts +19 -0
- package/dist/dom/components/hypenapp.js +2 -4
- package/dist/dom/components/hypenapp.js.map +3 -3
- package/dist/dom/components/image.d.ts +5 -0
- package/dist/dom/components/index.d.ts +29 -0
- package/dist/dom/components/index.js +29 -5
- package/dist/dom/components/index.js.map +7 -6
- package/dist/dom/components/input.d.ts +5 -0
- package/dist/dom/components/link.d.ts +5 -0
- package/dist/dom/components/list.d.ts +5 -0
- package/dist/dom/components/paragraph.d.ts +5 -0
- package/dist/dom/components/progressbar.d.ts +5 -0
- package/dist/dom/components/route.d.ts +6 -0
- package/dist/dom/components/route.js +2 -2
- package/dist/dom/components/route.js.map +2 -2
- package/dist/dom/components/router.d.ts +5 -0
- package/dist/dom/components/row.d.ts +7 -0
- package/dist/dom/components/select.d.ts +5 -0
- package/dist/dom/components/slider.d.ts +5 -0
- package/dist/dom/components/spacer.d.ts +5 -0
- package/dist/dom/components/spinner.d.ts +5 -0
- package/dist/dom/components/stack.d.ts +5 -0
- package/dist/dom/components/switch.d.ts +5 -0
- package/dist/dom/components/text.d.ts +5 -0
- package/dist/dom/components/textarea.d.ts +5 -0
- package/dist/dom/components/video.d.ts +5 -0
- package/dist/dom/debug.d.ts +63 -0
- package/dist/dom/debug.js +2 -2
- package/dist/dom/debug.js.map +2 -2
- package/dist/dom/element-data.d.ts +94 -0
- package/dist/dom/events.d.ts +39 -0
- package/dist/dom/events.js +2 -2
- package/dist/dom/events.js.map +2 -2
- package/dist/dom/index.d.ts +10 -0
- package/dist/dom/index.js +101 -25
- package/dist/dom/index.js.map +12 -11
- package/dist/dom/renderer.d.ts +115 -0
- package/dist/dom/renderer.js +100 -24
- package/dist/dom/renderer.js.map +11 -10
- package/dist/hypen.d.ts +140 -0
- package/dist/hypen.js +106 -43
- package/dist/hypen.js.map +12 -11
- package/dist/index.d.ts +28 -0
- package/dist/index.js +132 -38
- package/dist/index.js.map +17 -16
- package/package.json +3 -2
- package/src/canvas/input.ts +23 -1
- package/src/dom/applicators/events.ts +71 -0
- package/src/dom/renderer.ts +4 -4
- package/src/hypen.ts +7 -24
package/dist/canvas/paint.js.map
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
"sources": ["../src/canvas/utils.ts", "../src/canvas/text.ts", "../src/canvas/paint.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"/**\n * Canvas Renderer Utilities\n *\n * Common utility functions\n */\n\nimport type { BoxSpacing, Rectangle, Point, VirtualNode } from \"./types.js\";\n\n/**\n * Parse spacing value (margin, padding)\n * Supports: number, \"10\", \"10 20\", \"10 20 30 40\"\n */\nexport function parseSpacing(value: any): BoxSpacing {\n if (typeof value === \"number\") {\n return { top: value, right: value, bottom: value, left: value };\n }\n\n if (typeof value === \"string\") {\n const parts = value.split(/\\s+/).map((v) => parseFloat(v) || 0);\n if (parts.length === 1) {\n return { top: parts[0], right: parts[0], bottom: parts[0], left: parts[0] };\n }\n if (parts.length === 2) {\n return { top: parts[0], right: parts[1], bottom: parts[0], left: parts[1] };\n }\n if (parts.length === 4) {\n return { top: parts[0], right: parts[1], bottom: parts[2], left: parts[3] };\n }\n }\n\n if (typeof value === \"object\" && value !== null) {\n return {\n top: parseFloat(value.top) || 0,\n right: parseFloat(value.right) || 0,\n bottom: parseFloat(value.bottom) || 0,\n left: parseFloat(value.left) || 0,\n };\n }\n\n return { top: 0, right: 0, bottom: 0, left: 0 };\n}\n\n/**\n * Parse size value (width, height)\n * Returns pixel value or null for \"auto\"\n */\nexport function parseSize(value: any): number | null {\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\") {\n if (value === \"auto\") return null;\n const num = parseFloat(value);\n return isNaN(num) ? null : num;\n }\n return null;\n}\n\n/**\n * Check if point is inside rectangle\n */\nexport function isPointInRect(point: Point, rect: Rectangle): boolean {\n return (\n point.x >= rect.x &&\n point.x <= rect.x + rect.width &&\n point.y >= rect.y &&\n point.y <= rect.y + rect.height\n );\n}\n\n/**\n * Check if point is inside rounded rectangle\n */\nexport function isPointInRoundedRect(\n point: Point,\n rect: Rectangle,\n radius: number\n): boolean {\n const { x, y, width, height } = rect;\n\n // Quick reject if outside bounding box\n if (!isPointInRect(point, rect)) return false;\n\n // No radius means simple rectangle\n if (radius <= 0) return true;\n\n const px = point.x;\n const py = point.y;\n\n // Check corners\n // Top-left\n if (px < x + radius && py < y + radius) {\n return Math.pow(px - (x + radius), 2) + Math.pow(py - (y + radius), 2) <= Math.pow(radius, 2);\n }\n\n // Top-right\n if (px > x + width - radius && py < y + radius) {\n return (\n Math.pow(px - (x + width - radius), 2) + Math.pow(py - (y + radius), 2) <=\n Math.pow(radius, 2)\n );\n }\n\n // Bottom-left\n if (px < x + radius && py > y + height - radius) {\n return (\n Math.pow(px - (x + radius), 2) + Math.pow(py - (y + height - radius), 2) <=\n Math.pow(radius, 2)\n );\n }\n\n // Bottom-right\n if (px > x + width - radius && py > y + height - radius) {\n return (\n Math.pow(px - (x + width - radius), 2) + Math.pow(py - (y + height - radius), 2) <=\n Math.pow(radius, 2)\n );\n }\n\n // Inside rectangle\n return true;\n}\n\n/**\n * Merge rectangles into bounding box\n */\nexport function mergeRects(rects: Rectangle[]): Rectangle | null {\n if (rects.length === 0) return null;\n if (rects.length === 1) return rects[0];\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const rect of rects) {\n minX = Math.min(minX, rect.x);\n minY = Math.min(minY, rect.y);\n maxX = Math.max(maxX, rect.x + rect.width);\n maxY = Math.max(maxY, rect.y + rect.height);\n }\n\n return {\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY,\n };\n}\n\n/**\n * Create a canvas font string from font style\n */\nexport function createFontString(\n fontSize: number,\n fontWeight: string | number,\n fontFamily: string\n): string {\n return `${fontWeight} ${fontSize}px ${fontFamily}`;\n}\n\n/**\n * Walk tree depth-first\n */\nexport function walkTree(node: VirtualNode, callback: (node: VirtualNode) => void): void {\n callback(node);\n for (const child of node.children) {\n walkTree(child, callback);\n }\n}\n\n/**\n * Find node by ID in tree\n */\nexport function findNodeById(root: VirtualNode, id: string): VirtualNode | null {\n if (root.id === id) return root;\n\n for (const child of root.children) {\n const found = findNodeById(child, id);\n if (found) return found;\n }\n\n return null;\n}\n\n/**\n * Get absolute bounds of node (including transformations)\n */\nexport function getAbsoluteBounds(node: VirtualNode): Rectangle | null {\n if (!node.layout) return null;\n\n let x = node.layout.x;\n let y = node.layout.y;\n\n // Walk up tree to accumulate offsets\n let current = node.parent;\n while (current && current.layout) {\n x += current.layout.contentX;\n y += current.layout.contentY;\n current = current.parent;\n }\n\n return {\n x,\n y,\n width: node.layout.width,\n height: node.layout.height,\n };\n}\n\n\n\n\n\n\n\n\n\n\n\n",
|
|
6
|
-
"/**\n * Text Rendering System\n *\n * Text measurement, wrapping, and rendering\n */\n\nimport type { FontStyle, TextMetrics, TextStyle } from \"./types.js\";\nimport { createFontString } from \"./utils.js\";\nimport { frameworkLoggers } from \"@hypen-space/core\";\n\nconst log = frameworkLoggers.canvas;\n\n/**\n * Text metrics cache\n */\nconst textMetricsCache = new Map<string, TextMetrics>();\n\n/**\n * Get cache key for text metrics\n */\nfunction getCacheKey(text: string, fontStyle: FontStyle, maxWidth?: number): string {\n return `${text}|${fontStyle.fontSize}|${fontStyle.fontWeight}|${fontStyle.fontFamily}|${maxWidth || \"auto\"}`;\n}\n\n/**\n * Measure text dimensions\n */\nexport function measureText(\n ctx: CanvasRenderingContext2D,\n text: string,\n fontStyle: FontStyle,\n maxWidth?: number\n): TextMetrics {\n const cacheKey = getCacheKey(text, fontStyle, maxWidth);\n const cached = textMetricsCache.get(cacheKey);\n if (cached) return cached;\n\n const font = createFontString(fontStyle.fontSize, fontStyle.fontWeight, fontStyle.fontFamily);\n ctx.save();\n ctx.font = font;\n\n const lineHeight = fontStyle.lineHeight || fontStyle.fontSize * 1.2;\n\n // No wrapping needed\n if (!maxWidth) {\n const metrics = ctx.measureText(text);\n const result: TextMetrics = {\n width: metrics.width,\n height: lineHeight,\n lines: [text],\n lineHeight,\n };\n ctx.restore();\n textMetricsCache.set(cacheKey, result);\n return result;\n }\n\n // Wrap text\n const lines = wrapText(ctx, text, maxWidth);\n const width = Math.max(...lines.map((line) => ctx.measureText(line).width));\n const height = lines.length * lineHeight;\n\n const result: TextMetrics = {\n width,\n height,\n lines,\n lineHeight,\n };\n\n ctx.restore();\n textMetricsCache.set(cacheKey, result);\n return result;\n}\n\n/**\n * Wrap text to fit within maxWidth\n */\nfunction wrapText(ctx: CanvasRenderingContext2D, text: string, maxWidth: number): string[] {\n const lines: string[] = [];\n const paragraphs = text.split(\"\\n\");\n\n for (const paragraph of paragraphs) {\n const words = paragraph.split(\" \");\n let currentLine = \"\";\n\n for (const word of words) {\n const testLine = currentLine ? `${currentLine} ${word}` : word;\n const metrics = ctx.measureText(testLine);\n\n if (metrics.width > maxWidth && currentLine) {\n lines.push(currentLine);\n currentLine = word;\n } else {\n currentLine = testLine;\n }\n }\n\n if (currentLine) {\n lines.push(currentLine);\n }\n }\n\n return lines.length > 0 ? lines : [\"\"];\n}\n\n/**\n * Render text with style\n */\nexport function renderText(\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n width: number,\n height: number,\n style: TextStyle\n): void {\n const font = createFontString(style.fontSize, style.fontWeight, style.fontFamily);\n ctx.save();\n ctx.font = font;\n ctx.fillStyle = style.color;\n ctx.textBaseline = \"top\";\n\n const metrics = measureText(ctx, text, style, width);\n\n // Calculate starting Y based on vertical alignment\n let startY = y;\n if (style.verticalAlign === \"middle\") {\n startY = y + (height - metrics.height) / 2;\n } else if (style.verticalAlign === \"bottom\") {\n startY = y + height - metrics.height;\n }\n\n // Render each line\n for (let i = 0; i < metrics.lines.length; i++) {\n const line = metrics.lines[i];\n const lineY = startY + i * metrics.lineHeight;\n\n // Calculate X based on text alignment\n let lineX = x;\n if (style.textAlign === \"center\") {\n const lineWidth = ctx.measureText(line).width;\n lineX = x + (width - lineWidth) / 2;\n } else if (style.textAlign === \"right\") {\n const lineWidth = ctx.measureText(line).width;\n lineX = x + width - lineWidth;\n }\n\n ctx.fillText(line, lineX, lineY);\n }\n\n ctx.restore();\n}\n\n/**\n * Clear text metrics cache\n */\nexport function clearTextCache(): void {\n textMetricsCache.clear();\n}\n\n/**\n * Preload font to ensure it's available\n */\nexport async function loadFont(fontFamily: string, fontWeight: string | number = \"normal\"): Promise<void> {\n if (!(\"fonts\" in document)) return;\n\n const font = `${fontWeight} 16px ${fontFamily}`;\n try {\n await document.fonts.load(font);\n } catch (error) {\n log.warn(`Failed to load font: ${font}`, error);\n }\n}\n\n\n\n\n\n\n\n\n\n\n\n",
|
|
7
|
-
"/**\n * Paint System\n *\n * Drawing virtual nodes to canvas\n */\n\nimport type { VirtualNode, PainterFunction } from \"./types.js\";\nimport { renderText } from \"./text.js\";\n\n/**\n * Custom painters registry\n */\nconst customPainters = new Map<string, PainterFunction>();\n\n/**\n * Register a custom painter for a component type\n */\nexport function registerPainter(type: string, painter: PainterFunction): void {\n customPainters.set(type.toLowerCase(), painter);\n}\n\n/**\n * Paint a virtual node and its children\n */\nexport function paintNode(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n if (!node.visible || !node.layout) return;\n\n ctx.save();\n\n // Apply transforms\n applyTransforms(ctx, node);\n\n // Apply opacity\n if (node.opacity < 1) {\n ctx.globalAlpha = node.opacity;\n }\n\n // Check for custom painter\n const customPainter = customPainters.get(node.type.toLowerCase());\n if (customPainter) {\n customPainter(ctx, node);\n ctx.restore();\n return;\n }\n\n // Default painting based on type\n switch (node.type.toLowerCase()) {\n case \"column\":\n case \"row\":\n case \"stack\":\n paintContainer(ctx, node);\n break;\n case \"text\":\n paintText(ctx, node);\n break;\n case \"button\":\n paintButton(ctx, node);\n break;\n case \"input\":\n paintInput(ctx, node);\n break;\n case \"image\":\n paintImage(ctx, node);\n break;\n case \"spacer\":\n // Spacer is invisible, just takes up space\n break;\n case \"divider\":\n case \"separator\":\n paintDivider(ctx, node);\n break;\n case \"checkbox\":\n paintCheckbox(ctx, node);\n break;\n case \"radio\":\n paintRadio(ctx, node);\n break;\n case \"switch\":\n case \"toggle\":\n paintSwitch(ctx, node);\n break;\n case \"slider\":\n paintSlider(ctx, node);\n break;\n case \"progress\":\n case \"progressbar\":\n paintProgress(ctx, node);\n break;\n case \"spinner\":\n case \"loading\":\n paintSpinner(ctx, node);\n break;\n case \"card\":\n paintCard(ctx, node);\n break;\n case \"badge\":\n paintBadge(ctx, node);\n break;\n case \"avatar\":\n paintAvatar(ctx, node);\n break;\n case \"icon\":\n paintIcon(ctx, node);\n break;\n case \"link\":\n paintLink(ctx, node);\n break;\n case \"container\":\n case \"box\":\n paintContainer(ctx, node);\n break;\n default:\n paintContainer(ctx, node);\n }\n\n ctx.restore();\n\n // Paint children\n for (const child of node.children) {\n paintNode(ctx, child);\n }\n\n // Restore context if overflow clipping was applied\n if ((node as any)._needsRestore) {\n ctx.restore();\n delete (node as any)._needsRestore;\n }\n}\n\n/**\n * Paint a container (Column, Row, Stack, Box)\n */\nfunction paintContainer(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const x = layout.x;\n const y = layout.y;\n const width = layout.width;\n const height = layout.height;\n const radius = layout.border.radius;\n\n // Apply shadow if specified\n const shadow = props.shadow || props.boxShadow;\n if (shadow) {\n applyShadow(ctx, shadow);\n }\n\n // Draw background\n const backgroundColor = props.backgroundColor || props.background;\n if (backgroundColor) {\n // Support for gradients\n if (typeof backgroundColor === \"string\" && backgroundColor.includes(\"gradient\")) {\n ctx.fillStyle = parseGradient(ctx, backgroundColor, x, y, width, height);\n } else {\n ctx.fillStyle = backgroundColor;\n }\n\n if (radius > 0) {\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.fill();\n } else {\n ctx.fillRect(x, y, width, height);\n }\n }\n\n // Reset shadow for border\n if (shadow) {\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetX = 0;\n ctx.shadowOffsetY = 0;\n }\n\n // Draw border\n if (layout.border.width > 0 && layout.border.color !== \"transparent\") {\n ctx.strokeStyle = layout.border.color;\n ctx.lineWidth = layout.border.width;\n if (radius > 0) {\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.stroke();\n } else {\n ctx.strokeRect(x, y, width, height);\n }\n }\n\n // Apply overflow clipping for children\n const overflow = props.overflow || \"visible\";\n if (overflow === \"hidden\" || overflow === \"scroll\" || overflow === \"auto\") {\n ctx.save();\n ctx.beginPath();\n if (radius > 0) {\n drawRoundedRect(ctx, x, y, width, height, radius);\n } else {\n ctx.rect(x, y, width, height);\n }\n ctx.clip();\n\n // Mark that we need to restore later\n (node as any)._needsRestore = true;\n }\n}\n\n/**\n * Paint text node\n */\nfunction paintText(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n let text = String(props[0] || props.text || \"\");\n const color = props.color || \"#000000\";\n const fontSize = parseFloat(props.fontSize) || 16;\n const fontWeight = props.fontWeight || \"normal\";\n const fontFamily = props.fontFamily || \"system-ui, sans-serif\";\n const textAlign = props.textAlign || \"left\";\n const lineHeight = parseFloat(props.lineHeight) || fontSize * 1.2;\n const textDecoration = props.textDecoration || \"none\";\n const textTransform = props.textTransform || \"none\";\n const letterSpacing = parseFloat(props.letterSpacing) || 0;\n\n // Apply text transform\n if (textTransform === \"uppercase\") {\n text = text.toUpperCase();\n } else if (textTransform === \"lowercase\") {\n text = text.toLowerCase();\n } else if (textTransform === \"capitalize\") {\n text = text.replace(/\\b\\w/g, (char) => char.toUpperCase());\n }\n\n // Apply text shadow if specified\n const textShadow = props.textShadow || props.shadow;\n if (textShadow) {\n applyShadow(ctx, textShadow);\n }\n\n // Handle letter spacing\n const x = layout.x + layout.contentX;\n const y = layout.y + layout.contentY;\n\n if (letterSpacing !== 0) {\n // Manual letter spacing\n ctx.fillStyle = color;\n ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n\n let currentX = x;\n for (let i = 0; i < text.length; i++) {\n ctx.fillText(text[i], currentX, y);\n currentX += ctx.measureText(text[i]).width;\n // Add letter spacing after each character except the last\n if (i < text.length - 1) {\n currentX += letterSpacing;\n }\n }\n\n // Text decoration with letter spacing (now correct width)\n if (textDecoration !== \"none\") {\n applyTextDecoration(ctx, textDecoration, color, x, y, currentX - x, fontSize);\n }\n } else {\n // Normal text rendering\n renderText(\n ctx,\n text,\n x,\n y,\n layout.contentWidth,\n layout.contentHeight,\n {\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign: textAlign as any,\n verticalAlign: \"top\",\n lineHeight,\n }\n );\n\n // Text decoration (need to set font again for measurement)\n if (textDecoration !== \"none\") {\n ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;\n const textWidth = ctx.measureText(text).width;\n applyTextDecoration(ctx, textDecoration, color, x, y, textWidth, fontSize);\n }\n }\n\n // Reset shadow\n if (textShadow) {\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetX = 0;\n ctx.shadowOffsetY = 0;\n }\n}\n\n/**\n * Paint button node\n */\nfunction paintButton(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const x = layout.x;\n const y = layout.y;\n const width = layout.width;\n const height = layout.height;\n const radius = layout.border.radius || 4;\n\n // Apply shadow if specified\n const shadow = props.shadow || props.boxShadow;\n if (shadow) {\n applyShadow(ctx, shadow);\n }\n\n // Background color based on state\n let backgroundColor = props.backgroundColor || \"#007bff\";\n if (node.hovered) {\n backgroundColor = props.hoverColor || \"#0056b3\";\n }\n if (node.focused) {\n backgroundColor = props.focusColor || \"#004085\";\n }\n\n // Support gradients for button background\n if (typeof backgroundColor === \"string\" && backgroundColor.includes(\"gradient\")) {\n ctx.fillStyle = parseGradient(ctx, backgroundColor, x, y, width, height);\n } else {\n ctx.fillStyle = backgroundColor;\n }\n\n // Draw button background\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.fill();\n\n // Reset shadow for border\n if (shadow) {\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetX = 0;\n ctx.shadowOffsetY = 0;\n }\n\n // Draw border\n if (layout.border.width > 0) {\n ctx.strokeStyle = layout.border.color;\n ctx.lineWidth = layout.border.width;\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.stroke();\n }\n\n // Paint children (typically Text)\n for (const child of node.children) {\n paintNode(ctx, child);\n }\n}\n\n/**\n * Paint input node\n */\nfunction paintInput(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const x = layout.x;\n const y = layout.y;\n const width = layout.width;\n const height = layout.height;\n const radius = layout.border.radius || 4;\n\n // Background\n ctx.fillStyle = props.backgroundColor || \"#ffffff\";\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.fill();\n\n // Border (thicker if focused)\n const borderColor = node.focused ? \"#007bff\" : (layout.border.color || \"#cccccc\");\n const borderWidth = node.focused ? 2 : (layout.border.width || 1);\n ctx.strokeStyle = borderColor;\n ctx.lineWidth = borderWidth;\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.stroke();\n\n // Input value text\n const value = props.value || \"\";\n const placeholder = props.placeholder || \"\";\n const text = value || placeholder;\n const textColor = value ? (props.color || \"#000000\") : \"#999999\";\n\n if (text) {\n const fontSize = parseFloat(props.fontSize) || 16;\n const fontWeight = props.fontWeight || \"normal\";\n const fontFamily = props.fontFamily || \"system-ui, sans-serif\";\n const lineHeight = parseFloat(props.lineHeight) || fontSize * 1.2;\n\n renderText(\n ctx,\n text,\n layout.x + layout.contentX,\n layout.y + layout.contentY,\n layout.contentWidth,\n layout.contentHeight,\n {\n color: textColor,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign: \"left\",\n verticalAlign: \"middle\",\n lineHeight,\n }\n );\n }\n}\n\n/**\n * Paint image node\n */\nfunction paintImage(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const src = props.src || props[0];\n if (!src) return;\n\n // TODO: Load and cache images\n // For now, just draw a placeholder\n const x = layout.x;\n const y = layout.y;\n const width = layout.width;\n const height = layout.height;\n\n ctx.fillStyle = \"#e0e0e0\";\n ctx.fillRect(x, y, width, height);\n\n ctx.strokeStyle = \"#999999\";\n ctx.lineWidth = 1;\n ctx.strokeRect(x, y, width, height);\n\n // Draw \"IMG\" text\n ctx.fillStyle = \"#666666\";\n ctx.font = \"14px sans-serif\";\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(\"IMG\", x + width / 2, y + height / 2);\n}\n\n/**\n * Draw rounded rectangle path\n */\nfunction drawRoundedRect(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number,\n radius: number\n): void {\n if (radius <= 0) {\n ctx.rect(x, y, width, height);\n return;\n }\n\n ctx.beginPath();\n ctx.moveTo(x + radius, y);\n ctx.lineTo(x + width - radius, y);\n ctx.arcTo(x + width, y, x + width, y + radius, radius);\n ctx.lineTo(x + width, y + height - radius);\n ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius);\n ctx.lineTo(x + radius, y + height);\n ctx.arcTo(x, y + height, x, y + height - radius, radius);\n ctx.lineTo(x, y + radius);\n ctx.arcTo(x, y, x + radius, y, radius);\n ctx.closePath();\n}\n\n/**\n * Apply shadow to canvas context\n * Supports both simple and CSS-like shadow syntax:\n * - Simple: \"2 2 4 rgba(0,0,0,0.3)\"\n * - CSS-like: \"2px 2px 4px rgba(0,0,0,0.3)\"\n * - Named: {offsetX: 2, offsetY: 2, blur: 4, color: \"rgba(0,0,0,0.3)\"}\n */\nfunction applyShadow(ctx: CanvasRenderingContext2D, shadow: any): void {\n if (typeof shadow === \"string\") {\n // Parse CSS-like shadow string: \"offsetX offsetY blur color\"\n const parts = shadow.trim().split(/\\s+/);\n if (parts.length >= 3) {\n const offsetX = parseFloat(parts[0]);\n const offsetY = parseFloat(parts[1]);\n const blur = parseFloat(parts[2]);\n const color = parts.slice(3).join(\" \") || \"rgba(0,0,0,0.3)\";\n\n ctx.shadowOffsetX = offsetX;\n ctx.shadowOffsetY = offsetY;\n ctx.shadowBlur = blur;\n ctx.shadowColor = color;\n }\n } else if (typeof shadow === \"object\") {\n // Object syntax\n ctx.shadowOffsetX = shadow.offsetX || 0;\n ctx.shadowOffsetY = shadow.offsetY || 0;\n ctx.shadowBlur = shadow.blur || 0;\n ctx.shadowColor = shadow.color || \"rgba(0,0,0,0.3)\";\n }\n}\n\n/**\n * Parse gradient string and create canvas gradient\n * Supports:\n * - linear-gradient(direction, color1, color2, ...)\n * - radial-gradient(color1, color2, ...)\n */\nfunction parseGradient(\n ctx: CanvasRenderingContext2D,\n gradientStr: string,\n x: number,\n y: number,\n width: number,\n height: number\n): CanvasGradient | string {\n // Simple gradient parsing\n if (gradientStr.startsWith(\"linear-gradient\")) {\n // Extract content between parentheses\n const match = gradientStr.match(/linear-gradient\\((.*)\\)/);\n if (!match) return gradientStr;\n\n const parts = match[1].split(\",\").map((s) => s.trim());\n\n // Determine direction (default to bottom)\n let x0 = x, y0 = y, x1 = x, y1 = y + height;\n let colorStart = 0;\n\n if (parts[0].includes(\"deg\") || parts[0].includes(\"to \")) {\n colorStart = 1;\n const direction = parts[0];\n\n if (direction.includes(\"to right\") || direction === \"90deg\") {\n x1 = x + width;\n y1 = y;\n } else if (direction.includes(\"to left\") || direction === \"270deg\") {\n x0 = x + width;\n x1 = x;\n y0 = y;\n y1 = y;\n } else if (direction.includes(\"to top\") || direction === \"0deg\") {\n y0 = y + height;\n y1 = y;\n }\n // Default is \"to bottom\" which we already set\n }\n\n const gradient = ctx.createLinearGradient(x0, y0, x1, y1);\n\n // Add color stops\n const colors = parts.slice(colorStart);\n colors.forEach((color, i) => {\n const stop = i / (colors.length - 1);\n gradient.addColorStop(stop, color.trim());\n });\n\n return gradient;\n } else if (gradientStr.startsWith(\"radial-gradient\")) {\n // Extract content between parentheses\n const match = gradientStr.match(/radial-gradient\\((.*)\\)/);\n if (!match) return gradientStr;\n\n const parts = match[1].split(\",\").map((s) => s.trim());\n\n // Create radial gradient from center\n const centerX = x + width / 2;\n const centerY = y + height / 2;\n const radius = Math.max(width, height) / 2;\n\n const gradient = ctx.createRadialGradient(centerX, centerY, 0, centerX, centerY, radius);\n\n // Add color stops\n parts.forEach((color, i) => {\n const stop = i / (parts.length - 1);\n gradient.addColorStop(stop, color.trim());\n });\n\n return gradient;\n }\n\n return gradientStr;\n}\n\n/**\n * Apply CSS-like transforms to canvas context\n * Supports:\n * - translate(x, y)\n * - rotate(angle)\n * - scale(x, y)\n * - skew(x, y)\n * - transform: \"translate(10, 20) rotate(45) scale(1.5)\"\n */\nfunction applyTransforms(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const props = node.props;\n const layout = node.layout!;\n\n // Get transform origin (default to center)\n const originX = parseFloat(props.transformOriginX) || 0.5;\n const originY = parseFloat(props.transformOriginY) || 0.5;\n\n const centerX = layout.x + layout.width * originX;\n const centerY = layout.y + layout.height * originY;\n\n // Check for individual transform properties\n const translateX = parseFloat(props.translateX) || 0;\n const translateY = parseFloat(props.translateY) || 0;\n const rotate = parseFloat(props.rotate) || 0; // in degrees\n const scaleX = parseFloat(props.scaleX) || parseFloat(props.scale) || 1;\n const scaleY = parseFloat(props.scaleY) || parseFloat(props.scale) || 1;\n const skewX = parseFloat(props.skewX) || parseFloat(props.skew) || 0; // in degrees\n const skewY = parseFloat(props.skewY) || 0; // in degrees\n\n // Apply transforms in order: translate to origin, scale, rotate, skew, translate back, translate by offset\n if (translateX !== 0 || translateY !== 0 || rotate !== 0 || scaleX !== 1 || scaleY !== 1 || skewX !== 0 || skewY !== 0) {\n // Move to transform origin\n ctx.translate(centerX, centerY);\n\n // Apply scale\n if (scaleX !== 1 || scaleY !== 1) {\n ctx.scale(scaleX, scaleY);\n }\n\n // Apply rotation (convert degrees to radians)\n if (rotate !== 0) {\n ctx.rotate((rotate * Math.PI) / 180);\n }\n\n // Apply skew using transform matrix\n if (skewX !== 0 || skewY !== 0) {\n const skewXRad = (skewX * Math.PI) / 180;\n const skewYRad = (skewY * Math.PI) / 180;\n ctx.transform(1, Math.tan(skewYRad), Math.tan(skewXRad), 1, 0, 0);\n }\n\n // Move back from origin and apply translation\n ctx.translate(-centerX + translateX, -centerY + translateY);\n }\n\n // Also support compound transform string (optional, for future extensibility)\n if (props.transform && typeof props.transform === \"string\") {\n parseTransformString(ctx, props.transform, centerX, centerY);\n }\n}\n\n/**\n * Parse and apply a CSS-like transform string\n */\nfunction parseTransformString(\n ctx: CanvasRenderingContext2D,\n transformStr: string,\n originX: number,\n originY: number\n): void {\n // Simple transform parsing - matches translate(), rotate(), scale()\n const transforms = transformStr.match(/(\\w+)\\(([^)]+)\\)/g);\n if (!transforms) return;\n\n ctx.translate(originX, originY);\n\n for (const transform of transforms) {\n const match = transform.match(/(\\w+)\\(([^)]+)\\)/);\n if (!match) continue;\n\n const [, func, args] = match;\n const values = args.split(\",\").map((v) => parseFloat(v.trim()));\n\n switch (func.toLowerCase()) {\n case \"translate\":\n ctx.translate(values[0] || 0, values[1] || 0);\n break;\n case \"rotate\":\n ctx.rotate((values[0] * Math.PI) / 180);\n break;\n case \"scale\":\n ctx.scale(values[0] || 1, values[1] || values[0] || 1);\n break;\n }\n }\n\n ctx.translate(-originX, -originY);\n}\n\n/**\n * Paint divider/separator node\n */\nfunction paintDivider(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const orientation = props.orientation || \"horizontal\";\n const color = props.color || props.backgroundColor || \"#e0e0e0\";\n const thickness = parseFloat(props.thickness) || 1;\n\n ctx.strokeStyle = color;\n ctx.lineWidth = thickness;\n ctx.beginPath();\n\n if (orientation === \"vertical\") {\n const x = layout.x + layout.width / 2;\n ctx.moveTo(x, layout.y);\n ctx.lineTo(x, layout.y + layout.height);\n } else {\n const y = layout.y + layout.height / 2;\n ctx.moveTo(layout.x, y);\n ctx.lineTo(layout.x + layout.width, y);\n }\n\n ctx.stroke();\n}\n\n/**\n * Paint checkbox node\n */\nfunction paintCheckbox(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const size = Math.min(layout.width, layout.height);\n const x = layout.x;\n const y = layout.y;\n\n // Properly parse boolean values (handle string \"false\")\n const checkedValue = props.checked !== undefined ? props.checked : props.value;\n const checked = checkedValue === true || checkedValue === \"true\" || (checkedValue !== false && checkedValue !== \"false\" && !!checkedValue);\n\n const radius = parseFloat(props.borderRadius) || 2;\n\n // Background\n const bgColor = checked ? (props.checkedColor || \"#007bff\") : (props.backgroundColor || \"#ffffff\");\n ctx.fillStyle = bgColor;\n drawRoundedRect(ctx, x, y, size, size, radius);\n ctx.fill();\n\n // Border\n const borderColor = checked ? (props.checkedColor || \"#007bff\") : (props.borderColor || \"#cccccc\");\n ctx.strokeStyle = borderColor;\n ctx.lineWidth = node.focused ? 2 : 1;\n drawRoundedRect(ctx, x, y, size, size, radius);\n ctx.stroke();\n\n // Checkmark\n if (checked) {\n ctx.strokeStyle = props.checkColor || \"#ffffff\";\n ctx.lineWidth = 2;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n\n const padding = size * 0.25;\n ctx.beginPath();\n ctx.moveTo(x + padding, y + size / 2);\n ctx.lineTo(x + size * 0.4, y + size - padding);\n ctx.lineTo(x + size - padding, y + padding);\n ctx.stroke();\n }\n}\n\n/**\n * Paint radio button node\n */\nfunction paintRadio(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const size = Math.min(layout.width, layout.height);\n const centerX = layout.x + size / 2;\n const centerY = layout.y + size / 2;\n const radius = size / 2;\n\n // Properly parse boolean values (handle string \"false\")\n const checkedValue = props.checked !== undefined ? props.checked : props.value;\n const checked = checkedValue === true || checkedValue === \"true\" || (checkedValue !== false && checkedValue !== \"false\" && !!checkedValue);\n\n // Outer circle background\n const bgColor = props.backgroundColor || \"#ffffff\";\n ctx.fillStyle = bgColor;\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);\n ctx.fill();\n\n // Outer circle border\n const borderColor = checked ? (props.checkedColor || \"#007bff\") : (props.borderColor || \"#cccccc\");\n ctx.strokeStyle = borderColor;\n ctx.lineWidth = node.focused ? 2 : 1;\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);\n ctx.stroke();\n\n // Inner filled circle when checked\n if (checked) {\n ctx.fillStyle = props.checkedColor || \"#007bff\";\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius * 0.5, 0, Math.PI * 2);\n ctx.fill();\n }\n}\n\n/**\n * Paint switch/toggle node\n */\nfunction paintSwitch(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const width = layout.width;\n const height = layout.height;\n const x = layout.x;\n const y = layout.y;\n\n // Properly parse boolean values (handle string \"false\")\n const checkedValue = props.checked !== undefined ? props.checked : props.value;\n const checked = checkedValue === true || checkedValue === \"true\" || (checkedValue !== false && checkedValue !== \"false\" && !!checkedValue);\n\n const radius = height / 2;\n\n // Track background\n const trackColor = checked ? (props.checkedColor || \"#4caf50\") : (props.backgroundColor || \"#cccccc\");\n ctx.fillStyle = trackColor;\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.fill();\n\n // Thumb (circle)\n const thumbRadius = radius * 0.8;\n const thumbX = checked ? (x + width - radius) : (x + radius);\n const thumbY = y + radius;\n\n ctx.fillStyle = props.thumbColor || \"#ffffff\";\n ctx.beginPath();\n ctx.arc(thumbX, thumbY, thumbRadius, 0, Math.PI * 2);\n ctx.fill();\n\n // Thumb shadow\n if (props.shadow !== false) {\n ctx.shadowColor = \"rgba(0,0,0,0.2)\";\n ctx.shadowBlur = 2;\n ctx.shadowOffsetY = 1;\n ctx.beginPath();\n ctx.arc(thumbX, thumbY, thumbRadius, 0, Math.PI * 2);\n ctx.fill();\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetY = 0;\n }\n}\n\n/**\n * Paint slider node\n */\nfunction paintSlider(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const width = layout.width;\n const height = layout.height;\n const x = layout.x;\n const y = layout.y;\n\n const min = parseFloat(props.min) || 0;\n const max = parseFloat(props.max) || 100;\n const value = parseFloat(props.value) || min;\n const percentage = (value - min) / (max - min);\n\n const trackHeight = parseFloat(props.trackHeight) || 4;\n const thumbSize = parseFloat(props.thumbSize) || 16;\n const trackY = y + (height - trackHeight) / 2;\n\n // Track background\n ctx.fillStyle = props.trackColor || \"#e0e0e0\";\n drawRoundedRect(ctx, x, trackY, width, trackHeight, trackHeight / 2);\n ctx.fill();\n\n // Track fill\n const fillWidth = width * percentage;\n const fillColor = props.fillColor || props.color || \"#007bff\";\n\n // Support gradient fills\n if (typeof fillColor === \"string\" && fillColor.includes(\"gradient\")) {\n ctx.fillStyle = parseGradient(ctx, fillColor, x, trackY, fillWidth, trackHeight);\n } else {\n ctx.fillStyle = fillColor;\n }\n\n drawRoundedRect(ctx, x, trackY, fillWidth, trackHeight, trackHeight / 2);\n ctx.fill();\n\n // Thumb\n const thumbX = x + fillWidth;\n const thumbY = y + height / 2;\n\n ctx.fillStyle = props.thumbColor || \"#007bff\";\n ctx.beginPath();\n ctx.arc(thumbX, thumbY, thumbSize / 2, 0, Math.PI * 2);\n ctx.fill();\n\n // Thumb border\n ctx.strokeStyle = \"#ffffff\";\n ctx.lineWidth = 2;\n ctx.beginPath();\n ctx.arc(thumbX, thumbY, thumbSize / 2, 0, Math.PI * 2);\n ctx.stroke();\n}\n\n/**\n * Paint progress bar node\n */\nfunction paintProgress(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const width = layout.width;\n const height = layout.height;\n const x = layout.x;\n const y = layout.y;\n\n const min = parseFloat(props.min) || 0;\n const max = parseFloat(props.max) || 100;\n const value = parseFloat(props.value) || 0;\n const percentage = Math.min(Math.max((value - min) / (max - min), 0), 1);\n const radius = layout.border.radius || height / 2;\n\n // Background\n ctx.fillStyle = props.backgroundColor || \"#e0e0e0\";\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.fill();\n\n // Progress fill\n if (percentage > 0) {\n const fillWidth = width * percentage;\n\n // Support gradient fills\n const fillColor = props.fillColor || props.color || \"#007bff\";\n if (typeof fillColor === \"string\" && fillColor.includes(\"gradient\")) {\n ctx.fillStyle = parseGradient(ctx, fillColor, x, y, fillWidth, height);\n } else {\n ctx.fillStyle = fillColor;\n }\n\n drawRoundedRect(ctx, x, y, fillWidth, height, radius);\n ctx.fill();\n }\n\n // Optional text label\n if (props.showLabel) {\n const label = props.label || `${Math.round(percentage * 100)}%`;\n ctx.fillStyle = props.labelColor || \"#ffffff\";\n ctx.font = `${props.fontSize || 12}px ${props.fontFamily || \"sans-serif\"}`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(label, x + width / 2, y + height / 2);\n }\n}\n\n/**\n * Paint spinner/loading node\n */\nfunction paintSpinner(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const size = Math.min(layout.width, layout.height);\n const centerX = layout.x + size / 2;\n const centerY = layout.y + size / 2;\n const radius = size / 2 - 4;\n const thickness = parseFloat(props.thickness) || 4;\n const color = props.color || \"#007bff\";\n\n // Use timestamp for animation if available\n const rotation = (Date.now() / 1000) * Math.PI; // Rotate based on time\n\n ctx.strokeStyle = color;\n ctx.lineWidth = thickness;\n ctx.lineCap = \"round\";\n\n // Draw circular arc\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius, rotation, rotation + Math.PI * 1.5);\n ctx.stroke();\n\n // Fade out effect\n ctx.globalAlpha = 0.3;\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);\n ctx.stroke();\n ctx.globalAlpha = 1;\n}\n\n/**\n * Paint card node\n */\nfunction paintCard(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const x = layout.x;\n const y = layout.y;\n const width = layout.width;\n const height = layout.height;\n const radius = layout.border.radius || 8;\n\n // Default card shadow\n const shadow = props.shadow || props.boxShadow || \"0 2 8 rgba(0,0,0,0.1)\";\n applyShadow(ctx, shadow);\n\n // Background\n const backgroundColor = props.backgroundColor || \"#ffffff\";\n if (typeof backgroundColor === \"string\" && backgroundColor.includes(\"gradient\")) {\n ctx.fillStyle = parseGradient(ctx, backgroundColor, x, y, width, height);\n } else {\n ctx.fillStyle = backgroundColor;\n }\n\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.fill();\n\n // Reset shadow\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetX = 0;\n ctx.shadowOffsetY = 0;\n\n // Border\n if (layout.border.width > 0) {\n ctx.strokeStyle = layout.border.color;\n ctx.lineWidth = layout.border.width;\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.stroke();\n }\n\n // Paint children\n for (const child of node.children) {\n paintNode(ctx, child);\n }\n}\n\n/**\n * Paint badge node\n */\nfunction paintBadge(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const x = layout.x;\n const y = layout.y;\n const width = layout.width;\n const height = layout.height;\n const radius = layout.border.radius || height / 2;\n\n // Background\n const backgroundColor = props.backgroundColor || \"#dc3545\";\n ctx.fillStyle = backgroundColor;\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.fill();\n\n // Text content\n const text = String(props[0] || props.text || \"\");\n if (text) {\n ctx.fillStyle = props.color || \"#ffffff\";\n ctx.font = `${props.fontWeight || \"bold\"} ${props.fontSize || 10}px ${props.fontFamily || \"sans-serif\"}`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(text, x + width / 2, y + height / 2);\n }\n}\n\n/**\n * Paint avatar node\n */\nfunction paintAvatar(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const size = Math.min(layout.width, layout.height);\n const centerX = layout.x + size / 2;\n const centerY = layout.y + size / 2;\n const radius = size / 2;\n\n // Clip to circle\n ctx.save();\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);\n ctx.clip();\n\n // Background\n const backgroundColor = props.backgroundColor || \"#cccccc\";\n ctx.fillStyle = backgroundColor;\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);\n ctx.fill();\n\n // Text initials if provided\n const text = String(props[0] || props.text || props.initials || \"\");\n if (text) {\n ctx.fillStyle = props.color || \"#ffffff\";\n ctx.font = `${props.fontWeight || \"bold\"} ${props.fontSize || size / 2.5}px ${props.fontFamily || \"sans-serif\"}`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(text, centerX, centerY);\n }\n\n ctx.restore();\n\n // Border\n if (layout.border.width > 0) {\n ctx.strokeStyle = layout.border.color;\n ctx.lineWidth = layout.border.width;\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);\n ctx.stroke();\n }\n}\n\n/**\n * Paint icon node (simple placeholder - real icons would need SVG path support)\n */\nfunction paintIcon(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const size = Math.min(layout.width, layout.height);\n const x = layout.x;\n const y = layout.y;\n const color = props.color || \"#000000\";\n const iconName = props.icon || props.name || \"circle\";\n\n ctx.fillStyle = color;\n ctx.strokeStyle = color;\n ctx.lineWidth = 2;\n\n // Simple icon shapes\n switch (iconName.toLowerCase()) {\n case \"circle\":\n ctx.beginPath();\n ctx.arc(x + size / 2, y + size / 2, size / 3, 0, Math.PI * 2);\n ctx.fill();\n break;\n\n case \"square\":\n const padding = size * 0.2;\n ctx.fillRect(x + padding, y + padding, size - padding * 2, size - padding * 2);\n break;\n\n case \"star\":\n drawStar(ctx, x + size / 2, y + size / 2, 5, size / 3, size / 6);\n ctx.fill();\n break;\n\n case \"check\":\n case \"checkmark\":\n const p = size * 0.2;\n ctx.beginPath();\n ctx.moveTo(x + p, y + size / 2);\n ctx.lineTo(x + size * 0.4, y + size - p);\n ctx.lineTo(x + size - p, y + p);\n ctx.stroke();\n break;\n\n case \"x\":\n case \"close\":\n const pd = size * 0.2;\n ctx.beginPath();\n ctx.moveTo(x + pd, y + pd);\n ctx.lineTo(x + size - pd, y + size - pd);\n ctx.moveTo(x + size - pd, y + pd);\n ctx.lineTo(x + pd, y + size - pd);\n ctx.stroke();\n break;\n\n default:\n // Default: filled circle\n ctx.beginPath();\n ctx.arc(x + size / 2, y + size / 2, size / 3, 0, Math.PI * 2);\n ctx.fill();\n }\n}\n\n/**\n * Paint link node\n */\nfunction paintLink(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const text = String(props[0] || props.text || \"\");\n const color = node.hovered ? (props.hoverColor || \"#0056b3\") : (props.color || \"#007bff\");\n const fontSize = parseFloat(props.fontSize) || 16;\n const fontWeight = props.fontWeight || \"normal\";\n const fontFamily = props.fontFamily || \"system-ui, sans-serif\";\n const textDecoration = props.textDecoration !== undefined ? props.textDecoration : \"underline\";\n\n ctx.fillStyle = color;\n ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n\n const x = layout.x + layout.contentX;\n const y = layout.y + layout.contentY;\n\n ctx.fillText(text, x, y);\n\n // Underline\n if (textDecoration === \"underline\") {\n const textWidth = ctx.measureText(text).width;\n ctx.strokeStyle = color;\n ctx.lineWidth = 1;\n ctx.beginPath();\n ctx.moveTo(x, y + fontSize + 2);\n ctx.lineTo(x + textWidth, y + fontSize + 2);\n ctx.stroke();\n }\n}\n\n/**\n * Apply text decoration (underline, line-through, etc.)\n */\nfunction applyTextDecoration(\n ctx: CanvasRenderingContext2D,\n decoration: string,\n color: string,\n x: number,\n y: number,\n width: number,\n fontSize: number\n): void {\n ctx.strokeStyle = color;\n ctx.lineWidth = Math.max(1, fontSize / 16);\n\n ctx.beginPath();\n\n if (decoration === \"underline\") {\n const underlineY = y + fontSize + 2;\n ctx.moveTo(x, underlineY);\n ctx.lineTo(x + width, underlineY);\n } else if (decoration === \"line-through\" || decoration === \"strikethrough\") {\n const lineThroughY = y + fontSize / 2;\n ctx.moveTo(x, lineThroughY);\n ctx.lineTo(x + width, lineThroughY);\n } else if (decoration === \"overline\") {\n ctx.moveTo(x, y);\n ctx.lineTo(x + width, y);\n }\n\n ctx.stroke();\n}\n\n/**\n * Apply overflow clipping\n */\nfunction applyOverflowClip(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const props = node.props;\n const overflow = props.overflow || \"visible\";\n\n if (overflow === \"hidden\" || overflow === \"scroll\" || overflow === \"auto\") {\n const layout = node.layout!;\n const x = layout.x;\n const y = layout.y;\n const width = layout.width;\n const height = layout.height;\n const radius = layout.border.radius;\n\n ctx.save();\n ctx.beginPath();\n\n if (radius > 0) {\n drawRoundedRect(ctx, x, y, width, height, radius);\n } else {\n ctx.rect(x, y, width, height);\n }\n\n ctx.clip();\n }\n}\n\n/**\n * Helper: Draw a star shape\n */\nfunction drawStar(\n ctx: CanvasRenderingContext2D,\n cx: number,\n cy: number,\n spikes: number,\n outerRadius: number,\n innerRadius: number\n): void {\n let rot = (Math.PI / 2) * 3;\n let x = cx;\n let y = cy;\n const step = Math.PI / spikes;\n\n ctx.beginPath();\n ctx.moveTo(cx, cy - outerRadius);\n\n for (let i = 0; i < spikes; i++) {\n x = cx + Math.cos(rot) * outerRadius;\n y = cy + Math.sin(rot) * outerRadius;\n ctx.lineTo(x, y);\n rot += step;\n\n x = cx + Math.cos(rot) * innerRadius;\n y = cy + Math.sin(rot) * innerRadius;\n ctx.lineTo(x, y);\n rot += step;\n }\n\n ctx.lineTo(cx, cy - outerRadius);\n ctx.closePath();\n}\n\n\n\n\n\n\n\n\n\n"
|
|
6
|
+
"/**\n * Text Rendering System\n *\n * Text measurement, wrapping, and rendering\n */\n\nimport type { FontStyle, TextMetrics, TextStyle } from \"./types.js\";\nimport { createFontString } from \"./utils.js\";\nimport { frameworkLoggers } from \"@hypen-space/core/logger\";\n\nconst log = frameworkLoggers.canvas;\n\n/**\n * Text metrics cache\n */\nconst textMetricsCache = new Map<string, TextMetrics>();\n\n/**\n * Get cache key for text metrics\n */\nfunction getCacheKey(text: string, fontStyle: FontStyle, maxWidth?: number): string {\n return `${text}|${fontStyle.fontSize}|${fontStyle.fontWeight}|${fontStyle.fontFamily}|${maxWidth || \"auto\"}`;\n}\n\n/**\n * Measure text dimensions\n */\nexport function measureText(\n ctx: CanvasRenderingContext2D,\n text: string,\n fontStyle: FontStyle,\n maxWidth?: number\n): TextMetrics {\n const cacheKey = getCacheKey(text, fontStyle, maxWidth);\n const cached = textMetricsCache.get(cacheKey);\n if (cached) return cached;\n\n const font = createFontString(fontStyle.fontSize, fontStyle.fontWeight, fontStyle.fontFamily);\n ctx.save();\n ctx.font = font;\n\n const lineHeight = fontStyle.lineHeight || fontStyle.fontSize * 1.2;\n\n // No wrapping needed\n if (!maxWidth) {\n const metrics = ctx.measureText(text);\n const result: TextMetrics = {\n width: metrics.width,\n height: lineHeight,\n lines: [text],\n lineHeight,\n };\n ctx.restore();\n textMetricsCache.set(cacheKey, result);\n return result;\n }\n\n // Wrap text\n const lines = wrapText(ctx, text, maxWidth);\n const width = Math.max(...lines.map((line) => ctx.measureText(line).width));\n const height = lines.length * lineHeight;\n\n const result: TextMetrics = {\n width,\n height,\n lines,\n lineHeight,\n };\n\n ctx.restore();\n textMetricsCache.set(cacheKey, result);\n return result;\n}\n\n/**\n * Wrap text to fit within maxWidth\n */\nfunction wrapText(ctx: CanvasRenderingContext2D, text: string, maxWidth: number): string[] {\n const lines: string[] = [];\n const paragraphs = text.split(\"\\n\");\n\n for (const paragraph of paragraphs) {\n const words = paragraph.split(\" \");\n let currentLine = \"\";\n\n for (const word of words) {\n const testLine = currentLine ? `${currentLine} ${word}` : word;\n const metrics = ctx.measureText(testLine);\n\n if (metrics.width > maxWidth && currentLine) {\n lines.push(currentLine);\n currentLine = word;\n } else {\n currentLine = testLine;\n }\n }\n\n if (currentLine) {\n lines.push(currentLine);\n }\n }\n\n return lines.length > 0 ? lines : [\"\"];\n}\n\n/**\n * Render text with style\n */\nexport function renderText(\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n width: number,\n height: number,\n style: TextStyle\n): void {\n const font = createFontString(style.fontSize, style.fontWeight, style.fontFamily);\n ctx.save();\n ctx.font = font;\n ctx.fillStyle = style.color;\n ctx.textBaseline = \"top\";\n\n const metrics = measureText(ctx, text, style, width);\n\n // Calculate starting Y based on vertical alignment\n let startY = y;\n if (style.verticalAlign === \"middle\") {\n startY = y + (height - metrics.height) / 2;\n } else if (style.verticalAlign === \"bottom\") {\n startY = y + height - metrics.height;\n }\n\n // Render each line\n for (let i = 0; i < metrics.lines.length; i++) {\n const line = metrics.lines[i];\n const lineY = startY + i * metrics.lineHeight;\n\n // Calculate X based on text alignment\n let lineX = x;\n if (style.textAlign === \"center\") {\n const lineWidth = ctx.measureText(line).width;\n lineX = x + (width - lineWidth) / 2;\n } else if (style.textAlign === \"right\") {\n const lineWidth = ctx.measureText(line).width;\n lineX = x + width - lineWidth;\n }\n\n ctx.fillText(line, lineX, lineY);\n }\n\n ctx.restore();\n}\n\n/**\n * Clear text metrics cache\n */\nexport function clearTextCache(): void {\n textMetricsCache.clear();\n}\n\n/**\n * Preload font to ensure it's available\n */\nexport async function loadFont(fontFamily: string, fontWeight: string | number = \"normal\"): Promise<void> {\n if (!(\"fonts\" in document)) return;\n\n const font = `${fontWeight} 16px ${fontFamily}`;\n try {\n await document.fonts.load(font);\n } catch (error) {\n log.warn(`Failed to load font: ${font}`, error);\n }\n}\n\n\n\n\n\n\n\n\n\n\n\n",
|
|
7
|
+
"/**\n * Paint System\n *\n * Drawing virtual nodes to canvas\n */\n\nimport type { VirtualNode, PainterFunction } from \"./types.js\";\nimport { renderText } from \"./text.js\";\n\n/**\n * Custom painters registry\n */\nconst customPainters = new Map<string, PainterFunction>();\n\n/**\n * Register a custom painter for a component type\n */\nexport function registerPainter(type: string, painter: PainterFunction): void {\n customPainters.set(type.toLowerCase(), painter);\n}\n\n/**\n * Paint a virtual node and its children\n */\nexport function paintNode(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n if (!node.visible || !node.layout) return;\n\n ctx.save();\n\n // Apply transforms\n applyTransforms(ctx, node);\n\n // Apply opacity\n if (node.opacity < 1) {\n ctx.globalAlpha = node.opacity;\n }\n\n // Check for custom painter\n const customPainter = customPainters.get(node.type.toLowerCase());\n if (customPainter) {\n customPainter(ctx, node);\n ctx.restore();\n return;\n }\n\n // Default painting based on type\n switch (node.type.toLowerCase()) {\n case \"column\":\n case \"row\":\n case \"stack\":\n paintContainer(ctx, node);\n break;\n case \"text\":\n paintText(ctx, node);\n break;\n case \"button\":\n paintButton(ctx, node);\n break;\n case \"input\":\n paintInput(ctx, node);\n break;\n case \"image\":\n paintImage(ctx, node);\n break;\n case \"spacer\":\n // Spacer is invisible, just takes up space\n break;\n case \"divider\":\n case \"separator\":\n paintDivider(ctx, node);\n break;\n case \"checkbox\":\n paintCheckbox(ctx, node);\n break;\n case \"radio\":\n paintRadio(ctx, node);\n break;\n case \"switch\":\n case \"toggle\":\n paintSwitch(ctx, node);\n break;\n case \"slider\":\n paintSlider(ctx, node);\n break;\n case \"progress\":\n case \"progressbar\":\n paintProgress(ctx, node);\n break;\n case \"spinner\":\n case \"loading\":\n paintSpinner(ctx, node);\n break;\n case \"card\":\n paintCard(ctx, node);\n break;\n case \"badge\":\n paintBadge(ctx, node);\n break;\n case \"avatar\":\n paintAvatar(ctx, node);\n break;\n case \"icon\":\n paintIcon(ctx, node);\n break;\n case \"link\":\n paintLink(ctx, node);\n break;\n case \"app\":\n case \"container\":\n case \"box\":\n paintContainer(ctx, node);\n break;\n default:\n paintContainer(ctx, node);\n }\n\n ctx.restore();\n\n // Paint children\n for (const child of node.children) {\n paintNode(ctx, child);\n }\n\n // Restore context if overflow clipping was applied\n if ((node as any)._needsRestore) {\n ctx.restore();\n delete (node as any)._needsRestore;\n }\n}\n\n/**\n * Paint a container (Column, Row, Stack, Box)\n */\nfunction paintContainer(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const x = layout.x;\n const y = layout.y;\n const width = layout.width;\n const height = layout.height;\n const radius = layout.border.radius;\n\n // Apply shadow if specified\n const shadow = props.shadow || props.boxShadow;\n if (shadow) {\n applyShadow(ctx, shadow);\n }\n\n // Draw background\n const backgroundColor = props.backgroundColor || props.background;\n if (backgroundColor) {\n // Support for gradients\n if (typeof backgroundColor === \"string\" && backgroundColor.includes(\"gradient\")) {\n ctx.fillStyle = parseGradient(ctx, backgroundColor, x, y, width, height);\n } else {\n ctx.fillStyle = backgroundColor;\n }\n\n if (radius > 0) {\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.fill();\n } else {\n ctx.fillRect(x, y, width, height);\n }\n }\n\n // Reset shadow for border\n if (shadow) {\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetX = 0;\n ctx.shadowOffsetY = 0;\n }\n\n // Draw border\n if (layout.border.width > 0 && layout.border.color !== \"transparent\") {\n ctx.strokeStyle = layout.border.color;\n ctx.lineWidth = layout.border.width;\n if (radius > 0) {\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.stroke();\n } else {\n ctx.strokeRect(x, y, width, height);\n }\n }\n\n // Apply overflow clipping for children\n const overflow = props.overflow || \"visible\";\n if (overflow === \"hidden\" || overflow === \"scroll\" || overflow === \"auto\") {\n ctx.save();\n ctx.beginPath();\n if (radius > 0) {\n drawRoundedRect(ctx, x, y, width, height, radius);\n } else {\n ctx.rect(x, y, width, height);\n }\n ctx.clip();\n\n // Mark that we need to restore later\n (node as any)._needsRestore = true;\n }\n}\n\n/**\n * Paint text node\n */\nfunction paintText(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n let text = String(props[0] || props.text || \"\");\n const color = props.color || \"#000000\";\n const fontSize = parseFloat(props.fontSize) || 16;\n const fontWeight = props.fontWeight || \"normal\";\n const fontFamily = props.fontFamily || \"system-ui, sans-serif\";\n const textAlign = props.textAlign || \"left\";\n const lineHeight = parseFloat(props.lineHeight) || fontSize * 1.2;\n const textDecoration = props.textDecoration || \"none\";\n const textTransform = props.textTransform || \"none\";\n const letterSpacing = parseFloat(props.letterSpacing) || 0;\n\n // Apply text transform\n if (textTransform === \"uppercase\") {\n text = text.toUpperCase();\n } else if (textTransform === \"lowercase\") {\n text = text.toLowerCase();\n } else if (textTransform === \"capitalize\") {\n text = text.replace(/\\b\\w/g, (char) => char.toUpperCase());\n }\n\n // Apply text shadow if specified\n const textShadow = props.textShadow || props.shadow;\n if (textShadow) {\n applyShadow(ctx, textShadow);\n }\n\n // Handle letter spacing\n const x = layout.x + layout.contentX;\n const y = layout.y + layout.contentY;\n\n if (letterSpacing !== 0) {\n // Manual letter spacing\n ctx.fillStyle = color;\n ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n\n let currentX = x;\n for (let i = 0; i < text.length; i++) {\n ctx.fillText(text[i], currentX, y);\n currentX += ctx.measureText(text[i]).width;\n // Add letter spacing after each character except the last\n if (i < text.length - 1) {\n currentX += letterSpacing;\n }\n }\n\n // Text decoration with letter spacing (now correct width)\n if (textDecoration !== \"none\") {\n applyTextDecoration(ctx, textDecoration, color, x, y, currentX - x, fontSize);\n }\n } else {\n // Normal text rendering\n renderText(\n ctx,\n text,\n x,\n y,\n layout.contentWidth,\n layout.contentHeight,\n {\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign: textAlign as any,\n verticalAlign: \"top\",\n lineHeight,\n }\n );\n\n // Text decoration (need to set font again for measurement)\n if (textDecoration !== \"none\") {\n ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;\n const textWidth = ctx.measureText(text).width;\n applyTextDecoration(ctx, textDecoration, color, x, y, textWidth, fontSize);\n }\n }\n\n // Reset shadow\n if (textShadow) {\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetX = 0;\n ctx.shadowOffsetY = 0;\n }\n}\n\n/**\n * Paint button node\n */\nfunction paintButton(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const x = layout.x;\n const y = layout.y;\n const width = layout.width;\n const height = layout.height;\n const radius = layout.border.radius || 4;\n\n // Apply shadow if specified\n const shadow = props.shadow || props.boxShadow;\n if (shadow) {\n applyShadow(ctx, shadow);\n }\n\n // Background color based on state\n let backgroundColor = props.backgroundColor || \"#007bff\";\n if (node.hovered) {\n backgroundColor = props.hoverColor || \"#0056b3\";\n }\n if (node.focused) {\n backgroundColor = props.focusColor || \"#004085\";\n }\n\n // Support gradients for button background\n if (typeof backgroundColor === \"string\" && backgroundColor.includes(\"gradient\")) {\n ctx.fillStyle = parseGradient(ctx, backgroundColor, x, y, width, height);\n } else {\n ctx.fillStyle = backgroundColor;\n }\n\n // Draw button background\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.fill();\n\n // Reset shadow for border\n if (shadow) {\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetX = 0;\n ctx.shadowOffsetY = 0;\n }\n\n // Draw border\n if (layout.border.width > 0) {\n ctx.strokeStyle = layout.border.color;\n ctx.lineWidth = layout.border.width;\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.stroke();\n }\n\n // Paint children (typically Text)\n for (const child of node.children) {\n paintNode(ctx, child);\n }\n}\n\n/**\n * Paint input node\n */\nfunction paintInput(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const x = layout.x;\n const y = layout.y;\n const width = layout.width;\n const height = layout.height;\n const radius = layout.border.radius || 4;\n\n // Background\n ctx.fillStyle = props.backgroundColor || \"#ffffff\";\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.fill();\n\n // Border (thicker if focused)\n const borderColor = node.focused ? \"#007bff\" : (layout.border.color || \"#cccccc\");\n const borderWidth = node.focused ? 2 : (layout.border.width || 1);\n ctx.strokeStyle = borderColor;\n ctx.lineWidth = borderWidth;\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.stroke();\n\n // Input value text\n const value = props.value || \"\";\n const placeholder = props.placeholder || \"\";\n const text = value || placeholder;\n const textColor = value ? (props.color || \"#000000\") : \"#999999\";\n\n if (text) {\n const fontSize = parseFloat(props.fontSize) || 16;\n const fontWeight = props.fontWeight || \"normal\";\n const fontFamily = props.fontFamily || \"system-ui, sans-serif\";\n const lineHeight = parseFloat(props.lineHeight) || fontSize * 1.2;\n\n renderText(\n ctx,\n text,\n layout.x + layout.contentX,\n layout.y + layout.contentY,\n layout.contentWidth,\n layout.contentHeight,\n {\n color: textColor,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign: \"left\",\n verticalAlign: \"middle\",\n lineHeight,\n }\n );\n }\n}\n\n/**\n * Paint image node\n */\nfunction paintImage(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const src = props.src || props[0];\n if (!src) return;\n\n // TODO: Load and cache images\n // For now, just draw a placeholder\n const x = layout.x;\n const y = layout.y;\n const width = layout.width;\n const height = layout.height;\n\n ctx.fillStyle = \"#e0e0e0\";\n ctx.fillRect(x, y, width, height);\n\n ctx.strokeStyle = \"#999999\";\n ctx.lineWidth = 1;\n ctx.strokeRect(x, y, width, height);\n\n // Draw \"IMG\" text\n ctx.fillStyle = \"#666666\";\n ctx.font = \"14px sans-serif\";\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(\"IMG\", x + width / 2, y + height / 2);\n}\n\n/**\n * Draw rounded rectangle path\n */\nfunction drawRoundedRect(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n width: number,\n height: number,\n radius: number\n): void {\n if (radius <= 0) {\n ctx.rect(x, y, width, height);\n return;\n }\n\n ctx.beginPath();\n ctx.moveTo(x + radius, y);\n ctx.lineTo(x + width - radius, y);\n ctx.arcTo(x + width, y, x + width, y + radius, radius);\n ctx.lineTo(x + width, y + height - radius);\n ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius);\n ctx.lineTo(x + radius, y + height);\n ctx.arcTo(x, y + height, x, y + height - radius, radius);\n ctx.lineTo(x, y + radius);\n ctx.arcTo(x, y, x + radius, y, radius);\n ctx.closePath();\n}\n\n/**\n * Apply shadow to canvas context\n * Supports both simple and CSS-like shadow syntax:\n * - Simple: \"2 2 4 rgba(0,0,0,0.3)\"\n * - CSS-like: \"2px 2px 4px rgba(0,0,0,0.3)\"\n * - Named: {offsetX: 2, offsetY: 2, blur: 4, color: \"rgba(0,0,0,0.3)\"}\n */\nfunction applyShadow(ctx: CanvasRenderingContext2D, shadow: any): void {\n if (typeof shadow === \"string\") {\n // Parse CSS-like shadow string: \"offsetX offsetY blur color\"\n const parts = shadow.trim().split(/\\s+/);\n if (parts.length >= 3) {\n const offsetX = parseFloat(parts[0]);\n const offsetY = parseFloat(parts[1]);\n const blur = parseFloat(parts[2]);\n const color = parts.slice(3).join(\" \") || \"rgba(0,0,0,0.3)\";\n\n ctx.shadowOffsetX = offsetX;\n ctx.shadowOffsetY = offsetY;\n ctx.shadowBlur = blur;\n ctx.shadowColor = color;\n }\n } else if (typeof shadow === \"object\") {\n // Object syntax\n ctx.shadowOffsetX = shadow.offsetX || 0;\n ctx.shadowOffsetY = shadow.offsetY || 0;\n ctx.shadowBlur = shadow.blur || 0;\n ctx.shadowColor = shadow.color || \"rgba(0,0,0,0.3)\";\n }\n}\n\n/**\n * Parse gradient string and create canvas gradient\n * Supports:\n * - linear-gradient(direction, color1, color2, ...)\n * - radial-gradient(color1, color2, ...)\n */\nfunction parseGradient(\n ctx: CanvasRenderingContext2D,\n gradientStr: string,\n x: number,\n y: number,\n width: number,\n height: number\n): CanvasGradient | string {\n // Simple gradient parsing\n if (gradientStr.startsWith(\"linear-gradient\")) {\n // Extract content between parentheses\n const match = gradientStr.match(/linear-gradient\\((.*)\\)/);\n if (!match) return gradientStr;\n\n const parts = match[1].split(\",\").map((s) => s.trim());\n\n // Determine direction (default to bottom)\n let x0 = x, y0 = y, x1 = x, y1 = y + height;\n let colorStart = 0;\n\n if (parts[0].includes(\"deg\") || parts[0].includes(\"to \")) {\n colorStart = 1;\n const direction = parts[0];\n\n if (direction.includes(\"to right\") || direction === \"90deg\") {\n x1 = x + width;\n y1 = y;\n } else if (direction.includes(\"to left\") || direction === \"270deg\") {\n x0 = x + width;\n x1 = x;\n y0 = y;\n y1 = y;\n } else if (direction.includes(\"to top\") || direction === \"0deg\") {\n y0 = y + height;\n y1 = y;\n }\n // Default is \"to bottom\" which we already set\n }\n\n const gradient = ctx.createLinearGradient(x0, y0, x1, y1);\n\n // Add color stops\n const colors = parts.slice(colorStart);\n colors.forEach((color, i) => {\n const stop = i / (colors.length - 1);\n gradient.addColorStop(stop, color.trim());\n });\n\n return gradient;\n } else if (gradientStr.startsWith(\"radial-gradient\")) {\n // Extract content between parentheses\n const match = gradientStr.match(/radial-gradient\\((.*)\\)/);\n if (!match) return gradientStr;\n\n const parts = match[1].split(\",\").map((s) => s.trim());\n\n // Create radial gradient from center\n const centerX = x + width / 2;\n const centerY = y + height / 2;\n const radius = Math.max(width, height) / 2;\n\n const gradient = ctx.createRadialGradient(centerX, centerY, 0, centerX, centerY, radius);\n\n // Add color stops\n parts.forEach((color, i) => {\n const stop = i / (parts.length - 1);\n gradient.addColorStop(stop, color.trim());\n });\n\n return gradient;\n }\n\n return gradientStr;\n}\n\n/**\n * Apply CSS-like transforms to canvas context\n * Supports:\n * - translate(x, y)\n * - rotate(angle)\n * - scale(x, y)\n * - skew(x, y)\n * - transform: \"translate(10, 20) rotate(45) scale(1.5)\"\n */\nfunction applyTransforms(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const props = node.props;\n const layout = node.layout!;\n\n // Get transform origin (default to center)\n const originX = parseFloat(props.transformOriginX) || 0.5;\n const originY = parseFloat(props.transformOriginY) || 0.5;\n\n const centerX = layout.x + layout.width * originX;\n const centerY = layout.y + layout.height * originY;\n\n // Check for individual transform properties\n const translateX = parseFloat(props.translateX) || 0;\n const translateY = parseFloat(props.translateY) || 0;\n const rotate = parseFloat(props.rotate) || 0; // in degrees\n const scaleX = parseFloat(props.scaleX) || parseFloat(props.scale) || 1;\n const scaleY = parseFloat(props.scaleY) || parseFloat(props.scale) || 1;\n const skewX = parseFloat(props.skewX) || parseFloat(props.skew) || 0; // in degrees\n const skewY = parseFloat(props.skewY) || 0; // in degrees\n\n // Apply transforms in order: translate to origin, scale, rotate, skew, translate back, translate by offset\n if (translateX !== 0 || translateY !== 0 || rotate !== 0 || scaleX !== 1 || scaleY !== 1 || skewX !== 0 || skewY !== 0) {\n // Move to transform origin\n ctx.translate(centerX, centerY);\n\n // Apply scale\n if (scaleX !== 1 || scaleY !== 1) {\n ctx.scale(scaleX, scaleY);\n }\n\n // Apply rotation (convert degrees to radians)\n if (rotate !== 0) {\n ctx.rotate((rotate * Math.PI) / 180);\n }\n\n // Apply skew using transform matrix\n if (skewX !== 0 || skewY !== 0) {\n const skewXRad = (skewX * Math.PI) / 180;\n const skewYRad = (skewY * Math.PI) / 180;\n ctx.transform(1, Math.tan(skewYRad), Math.tan(skewXRad), 1, 0, 0);\n }\n\n // Move back from origin and apply translation\n ctx.translate(-centerX + translateX, -centerY + translateY);\n }\n\n // Also support compound transform string (optional, for future extensibility)\n if (props.transform && typeof props.transform === \"string\") {\n parseTransformString(ctx, props.transform, centerX, centerY);\n }\n}\n\n/**\n * Parse and apply a CSS-like transform string\n */\nfunction parseTransformString(\n ctx: CanvasRenderingContext2D,\n transformStr: string,\n originX: number,\n originY: number\n): void {\n // Simple transform parsing - matches translate(), rotate(), scale()\n const transforms = transformStr.match(/(\\w+)\\(([^)]+)\\)/g);\n if (!transforms) return;\n\n ctx.translate(originX, originY);\n\n for (const transform of transforms) {\n const match = transform.match(/(\\w+)\\(([^)]+)\\)/);\n if (!match) continue;\n\n const [, func, args] = match;\n const values = args.split(\",\").map((v) => parseFloat(v.trim()));\n\n switch (func.toLowerCase()) {\n case \"translate\":\n ctx.translate(values[0] || 0, values[1] || 0);\n break;\n case \"rotate\":\n ctx.rotate((values[0] * Math.PI) / 180);\n break;\n case \"scale\":\n ctx.scale(values[0] || 1, values[1] || values[0] || 1);\n break;\n }\n }\n\n ctx.translate(-originX, -originY);\n}\n\n/**\n * Paint divider/separator node\n */\nfunction paintDivider(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const orientation = props.orientation || \"horizontal\";\n const color = props.color || props.backgroundColor || \"#e0e0e0\";\n const thickness = parseFloat(props.thickness) || 1;\n\n ctx.strokeStyle = color;\n ctx.lineWidth = thickness;\n ctx.beginPath();\n\n if (orientation === \"vertical\") {\n const x = layout.x + layout.width / 2;\n ctx.moveTo(x, layout.y);\n ctx.lineTo(x, layout.y + layout.height);\n } else {\n const y = layout.y + layout.height / 2;\n ctx.moveTo(layout.x, y);\n ctx.lineTo(layout.x + layout.width, y);\n }\n\n ctx.stroke();\n}\n\n/**\n * Paint checkbox node\n */\nfunction paintCheckbox(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const size = Math.min(layout.width, layout.height);\n const x = layout.x;\n const y = layout.y;\n\n // Properly parse boolean values (handle string \"false\")\n const checkedValue = props.checked !== undefined ? props.checked : props.value;\n const checked = checkedValue === true || checkedValue === \"true\" || (checkedValue !== false && checkedValue !== \"false\" && !!checkedValue);\n\n const radius = parseFloat(props.borderRadius) || 2;\n\n // Background\n const bgColor = checked ? (props.checkedColor || \"#007bff\") : (props.backgroundColor || \"#ffffff\");\n ctx.fillStyle = bgColor;\n drawRoundedRect(ctx, x, y, size, size, radius);\n ctx.fill();\n\n // Border\n const borderColor = checked ? (props.checkedColor || \"#007bff\") : (props.borderColor || \"#cccccc\");\n ctx.strokeStyle = borderColor;\n ctx.lineWidth = node.focused ? 2 : 1;\n drawRoundedRect(ctx, x, y, size, size, radius);\n ctx.stroke();\n\n // Checkmark\n if (checked) {\n ctx.strokeStyle = props.checkColor || \"#ffffff\";\n ctx.lineWidth = 2;\n ctx.lineCap = \"round\";\n ctx.lineJoin = \"round\";\n\n const padding = size * 0.25;\n ctx.beginPath();\n ctx.moveTo(x + padding, y + size / 2);\n ctx.lineTo(x + size * 0.4, y + size - padding);\n ctx.lineTo(x + size - padding, y + padding);\n ctx.stroke();\n }\n}\n\n/**\n * Paint radio button node\n */\nfunction paintRadio(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const size = Math.min(layout.width, layout.height);\n const centerX = layout.x + size / 2;\n const centerY = layout.y + size / 2;\n const radius = size / 2;\n\n // Properly parse boolean values (handle string \"false\")\n const checkedValue = props.checked !== undefined ? props.checked : props.value;\n const checked = checkedValue === true || checkedValue === \"true\" || (checkedValue !== false && checkedValue !== \"false\" && !!checkedValue);\n\n // Outer circle background\n const bgColor = props.backgroundColor || \"#ffffff\";\n ctx.fillStyle = bgColor;\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);\n ctx.fill();\n\n // Outer circle border\n const borderColor = checked ? (props.checkedColor || \"#007bff\") : (props.borderColor || \"#cccccc\");\n ctx.strokeStyle = borderColor;\n ctx.lineWidth = node.focused ? 2 : 1;\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);\n ctx.stroke();\n\n // Inner filled circle when checked\n if (checked) {\n ctx.fillStyle = props.checkedColor || \"#007bff\";\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius * 0.5, 0, Math.PI * 2);\n ctx.fill();\n }\n}\n\n/**\n * Paint switch/toggle node\n */\nfunction paintSwitch(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const width = layout.width;\n const height = layout.height;\n const x = layout.x;\n const y = layout.y;\n\n // Properly parse boolean values (handle string \"false\")\n const checkedValue = props.checked !== undefined ? props.checked : props.value;\n const checked = checkedValue === true || checkedValue === \"true\" || (checkedValue !== false && checkedValue !== \"false\" && !!checkedValue);\n\n const radius = height / 2;\n\n // Track background\n const trackColor = checked ? (props.checkedColor || \"#4caf50\") : (props.backgroundColor || \"#cccccc\");\n ctx.fillStyle = trackColor;\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.fill();\n\n // Thumb (circle)\n const thumbRadius = radius * 0.8;\n const thumbX = checked ? (x + width - radius) : (x + radius);\n const thumbY = y + radius;\n\n ctx.fillStyle = props.thumbColor || \"#ffffff\";\n ctx.beginPath();\n ctx.arc(thumbX, thumbY, thumbRadius, 0, Math.PI * 2);\n ctx.fill();\n\n // Thumb shadow\n if (props.shadow !== false) {\n ctx.shadowColor = \"rgba(0,0,0,0.2)\";\n ctx.shadowBlur = 2;\n ctx.shadowOffsetY = 1;\n ctx.beginPath();\n ctx.arc(thumbX, thumbY, thumbRadius, 0, Math.PI * 2);\n ctx.fill();\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetY = 0;\n }\n}\n\n/**\n * Paint slider node\n */\nfunction paintSlider(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const width = layout.width;\n const height = layout.height;\n const x = layout.x;\n const y = layout.y;\n\n const min = parseFloat(props.min) || 0;\n const max = parseFloat(props.max) || 100;\n const value = parseFloat(props.value) || min;\n const percentage = (value - min) / (max - min);\n\n const trackHeight = parseFloat(props.trackHeight) || 4;\n const thumbSize = parseFloat(props.thumbSize) || 16;\n const trackY = y + (height - trackHeight) / 2;\n\n // Track background\n ctx.fillStyle = props.trackColor || \"#e0e0e0\";\n drawRoundedRect(ctx, x, trackY, width, trackHeight, trackHeight / 2);\n ctx.fill();\n\n // Track fill\n const fillWidth = width * percentage;\n const fillColor = props.fillColor || props.color || \"#007bff\";\n\n // Support gradient fills\n if (typeof fillColor === \"string\" && fillColor.includes(\"gradient\")) {\n ctx.fillStyle = parseGradient(ctx, fillColor, x, trackY, fillWidth, trackHeight);\n } else {\n ctx.fillStyle = fillColor;\n }\n\n drawRoundedRect(ctx, x, trackY, fillWidth, trackHeight, trackHeight / 2);\n ctx.fill();\n\n // Thumb\n const thumbX = x + fillWidth;\n const thumbY = y + height / 2;\n\n ctx.fillStyle = props.thumbColor || \"#007bff\";\n ctx.beginPath();\n ctx.arc(thumbX, thumbY, thumbSize / 2, 0, Math.PI * 2);\n ctx.fill();\n\n // Thumb border\n ctx.strokeStyle = \"#ffffff\";\n ctx.lineWidth = 2;\n ctx.beginPath();\n ctx.arc(thumbX, thumbY, thumbSize / 2, 0, Math.PI * 2);\n ctx.stroke();\n}\n\n/**\n * Paint progress bar node\n */\nfunction paintProgress(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const width = layout.width;\n const height = layout.height;\n const x = layout.x;\n const y = layout.y;\n\n const min = parseFloat(props.min) || 0;\n const max = parseFloat(props.max) || 100;\n const value = parseFloat(props.value) || 0;\n const percentage = Math.min(Math.max((value - min) / (max - min), 0), 1);\n const radius = layout.border.radius || height / 2;\n\n // Background\n ctx.fillStyle = props.backgroundColor || \"#e0e0e0\";\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.fill();\n\n // Progress fill\n if (percentage > 0) {\n const fillWidth = width * percentage;\n\n // Support gradient fills\n const fillColor = props.fillColor || props.color || \"#007bff\";\n if (typeof fillColor === \"string\" && fillColor.includes(\"gradient\")) {\n ctx.fillStyle = parseGradient(ctx, fillColor, x, y, fillWidth, height);\n } else {\n ctx.fillStyle = fillColor;\n }\n\n drawRoundedRect(ctx, x, y, fillWidth, height, radius);\n ctx.fill();\n }\n\n // Optional text label\n if (props.showLabel) {\n const label = props.label || `${Math.round(percentage * 100)}%`;\n ctx.fillStyle = props.labelColor || \"#ffffff\";\n ctx.font = `${props.fontSize || 12}px ${props.fontFamily || \"sans-serif\"}`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(label, x + width / 2, y + height / 2);\n }\n}\n\n/**\n * Paint spinner/loading node\n */\nfunction paintSpinner(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const size = Math.min(layout.width, layout.height);\n const centerX = layout.x + size / 2;\n const centerY = layout.y + size / 2;\n const radius = size / 2 - 4;\n const thickness = parseFloat(props.thickness) || 4;\n const color = props.color || \"#007bff\";\n\n // Use timestamp for animation if available\n const rotation = (Date.now() / 1000) * Math.PI; // Rotate based on time\n\n ctx.strokeStyle = color;\n ctx.lineWidth = thickness;\n ctx.lineCap = \"round\";\n\n // Draw circular arc\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius, rotation, rotation + Math.PI * 1.5);\n ctx.stroke();\n\n // Fade out effect\n ctx.globalAlpha = 0.3;\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);\n ctx.stroke();\n ctx.globalAlpha = 1;\n}\n\n/**\n * Paint card node\n */\nfunction paintCard(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const x = layout.x;\n const y = layout.y;\n const width = layout.width;\n const height = layout.height;\n const radius = layout.border.radius || 8;\n\n // Default card shadow\n const shadow = props.shadow || props.boxShadow || \"0 2 8 rgba(0,0,0,0.1)\";\n applyShadow(ctx, shadow);\n\n // Background\n const backgroundColor = props.backgroundColor || \"#ffffff\";\n if (typeof backgroundColor === \"string\" && backgroundColor.includes(\"gradient\")) {\n ctx.fillStyle = parseGradient(ctx, backgroundColor, x, y, width, height);\n } else {\n ctx.fillStyle = backgroundColor;\n }\n\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.fill();\n\n // Reset shadow\n ctx.shadowColor = \"transparent\";\n ctx.shadowBlur = 0;\n ctx.shadowOffsetX = 0;\n ctx.shadowOffsetY = 0;\n\n // Border\n if (layout.border.width > 0) {\n ctx.strokeStyle = layout.border.color;\n ctx.lineWidth = layout.border.width;\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.stroke();\n }\n\n // Paint children\n for (const child of node.children) {\n paintNode(ctx, child);\n }\n}\n\n/**\n * Paint badge node\n */\nfunction paintBadge(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const x = layout.x;\n const y = layout.y;\n const width = layout.width;\n const height = layout.height;\n const radius = layout.border.radius || height / 2;\n\n // Background\n const backgroundColor = props.backgroundColor || \"#dc3545\";\n ctx.fillStyle = backgroundColor;\n drawRoundedRect(ctx, x, y, width, height, radius);\n ctx.fill();\n\n // Text content\n const text = String(props[0] || props.text || \"\");\n if (text) {\n ctx.fillStyle = props.color || \"#ffffff\";\n ctx.font = `${props.fontWeight || \"bold\"} ${props.fontSize || 10}px ${props.fontFamily || \"sans-serif\"}`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(text, x + width / 2, y + height / 2);\n }\n}\n\n/**\n * Paint avatar node\n */\nfunction paintAvatar(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const size = Math.min(layout.width, layout.height);\n const centerX = layout.x + size / 2;\n const centerY = layout.y + size / 2;\n const radius = size / 2;\n\n // Clip to circle\n ctx.save();\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);\n ctx.clip();\n\n // Background\n const backgroundColor = props.backgroundColor || \"#cccccc\";\n ctx.fillStyle = backgroundColor;\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);\n ctx.fill();\n\n // Text initials if provided\n const text = String(props[0] || props.text || props.initials || \"\");\n if (text) {\n ctx.fillStyle = props.color || \"#ffffff\";\n ctx.font = `${props.fontWeight || \"bold\"} ${props.fontSize || size / 2.5}px ${props.fontFamily || \"sans-serif\"}`;\n ctx.textAlign = \"center\";\n ctx.textBaseline = \"middle\";\n ctx.fillText(text, centerX, centerY);\n }\n\n ctx.restore();\n\n // Border\n if (layout.border.width > 0) {\n ctx.strokeStyle = layout.border.color;\n ctx.lineWidth = layout.border.width;\n ctx.beginPath();\n ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);\n ctx.stroke();\n }\n}\n\n/**\n * Paint icon node (simple placeholder - real icons would need SVG path support)\n */\nfunction paintIcon(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const size = Math.min(layout.width, layout.height);\n const x = layout.x;\n const y = layout.y;\n const color = props.color || \"#000000\";\n const iconName = props.icon || props.name || \"circle\";\n\n ctx.fillStyle = color;\n ctx.strokeStyle = color;\n ctx.lineWidth = 2;\n\n // Simple icon shapes\n switch (iconName.toLowerCase()) {\n case \"circle\":\n ctx.beginPath();\n ctx.arc(x + size / 2, y + size / 2, size / 3, 0, Math.PI * 2);\n ctx.fill();\n break;\n\n case \"square\":\n const padding = size * 0.2;\n ctx.fillRect(x + padding, y + padding, size - padding * 2, size - padding * 2);\n break;\n\n case \"star\":\n drawStar(ctx, x + size / 2, y + size / 2, 5, size / 3, size / 6);\n ctx.fill();\n break;\n\n case \"check\":\n case \"checkmark\":\n const p = size * 0.2;\n ctx.beginPath();\n ctx.moveTo(x + p, y + size / 2);\n ctx.lineTo(x + size * 0.4, y + size - p);\n ctx.lineTo(x + size - p, y + p);\n ctx.stroke();\n break;\n\n case \"x\":\n case \"close\":\n const pd = size * 0.2;\n ctx.beginPath();\n ctx.moveTo(x + pd, y + pd);\n ctx.lineTo(x + size - pd, y + size - pd);\n ctx.moveTo(x + size - pd, y + pd);\n ctx.lineTo(x + pd, y + size - pd);\n ctx.stroke();\n break;\n\n default:\n // Default: filled circle\n ctx.beginPath();\n ctx.arc(x + size / 2, y + size / 2, size / 3, 0, Math.PI * 2);\n ctx.fill();\n }\n}\n\n/**\n * Paint link node\n */\nfunction paintLink(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const layout = node.layout!;\n const props = node.props;\n\n const text = String(props[0] || props.text || \"\");\n const color = node.hovered ? (props.hoverColor || \"#0056b3\") : (props.color || \"#007bff\");\n const fontSize = parseFloat(props.fontSize) || 16;\n const fontWeight = props.fontWeight || \"normal\";\n const fontFamily = props.fontFamily || \"system-ui, sans-serif\";\n const textDecoration = props.textDecoration !== undefined ? props.textDecoration : \"underline\";\n\n ctx.fillStyle = color;\n ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n\n const x = layout.x + layout.contentX;\n const y = layout.y + layout.contentY;\n\n ctx.fillText(text, x, y);\n\n // Underline\n if (textDecoration === \"underline\") {\n const textWidth = ctx.measureText(text).width;\n ctx.strokeStyle = color;\n ctx.lineWidth = 1;\n ctx.beginPath();\n ctx.moveTo(x, y + fontSize + 2);\n ctx.lineTo(x + textWidth, y + fontSize + 2);\n ctx.stroke();\n }\n}\n\n/**\n * Apply text decoration (underline, line-through, etc.)\n */\nfunction applyTextDecoration(\n ctx: CanvasRenderingContext2D,\n decoration: string,\n color: string,\n x: number,\n y: number,\n width: number,\n fontSize: number\n): void {\n ctx.strokeStyle = color;\n ctx.lineWidth = Math.max(1, fontSize / 16);\n\n ctx.beginPath();\n\n if (decoration === \"underline\") {\n const underlineY = y + fontSize + 2;\n ctx.moveTo(x, underlineY);\n ctx.lineTo(x + width, underlineY);\n } else if (decoration === \"line-through\" || decoration === \"strikethrough\") {\n const lineThroughY = y + fontSize / 2;\n ctx.moveTo(x, lineThroughY);\n ctx.lineTo(x + width, lineThroughY);\n } else if (decoration === \"overline\") {\n ctx.moveTo(x, y);\n ctx.lineTo(x + width, y);\n }\n\n ctx.stroke();\n}\n\n/**\n * Apply overflow clipping\n */\nfunction applyOverflowClip(ctx: CanvasRenderingContext2D, node: VirtualNode): void {\n const props = node.props;\n const overflow = props.overflow || \"visible\";\n\n if (overflow === \"hidden\" || overflow === \"scroll\" || overflow === \"auto\") {\n const layout = node.layout!;\n const x = layout.x;\n const y = layout.y;\n const width = layout.width;\n const height = layout.height;\n const radius = layout.border.radius;\n\n ctx.save();\n ctx.beginPath();\n\n if (radius > 0) {\n drawRoundedRect(ctx, x, y, width, height, radius);\n } else {\n ctx.rect(x, y, width, height);\n }\n\n ctx.clip();\n }\n}\n\n/**\n * Helper: Draw a star shape\n */\nfunction drawStar(\n ctx: CanvasRenderingContext2D,\n cx: number,\n cy: number,\n spikes: number,\n outerRadius: number,\n innerRadius: number\n): void {\n let rot = (Math.PI / 2) * 3;\n let x = cx;\n let y = cy;\n const step = Math.PI / spikes;\n\n ctx.beginPath();\n ctx.moveTo(cx, cy - outerRadius);\n\n for (let i = 0; i < spikes; i++) {\n x = cx + Math.cos(rot) * outerRadius;\n y = cy + Math.sin(rot) * outerRadius;\n ctx.lineTo(x, y);\n rot += step;\n\n x = cx + Math.cos(rot) * innerRadius;\n y = cy + Math.sin(rot) * innerRadius;\n ctx.lineTo(x, y);\n rot += step;\n }\n\n ctx.lineTo(cx, cy - outerRadius);\n ctx.closePath();\n}\n\n\n\n\n\n\n\n\n\n"
|
|
8
8
|
],
|
|
9
|
-
"mappings": "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",
|
|
10
|
-
"debugId": "
|
|
9
|
+
"mappings": "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",
|
|
10
|
+
"debugId": "07A6963F6299A38264756E2164756E21",
|
|
11
11
|
"names": []
|
|
12
12
|
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canvas Renderer
|
|
3
|
+
*
|
|
4
|
+
* Main renderer class that orchestrates layout, painting, and events
|
|
5
|
+
*/
|
|
6
|
+
import type { Renderer } from "@hypen-space/core/renderer";
|
|
7
|
+
import type { Patch } from "@hypen-space/core/types";
|
|
8
|
+
interface IEngine {
|
|
9
|
+
dispatchAction(name: string, payload?: any): void;
|
|
10
|
+
}
|
|
11
|
+
import type { VirtualNode, CanvasRendererOptions, PainterFunction } from "./types.js";
|
|
12
|
+
/**
|
|
13
|
+
* Canvas Renderer
|
|
14
|
+
*/
|
|
15
|
+
export declare class CanvasRenderer implements Renderer {
|
|
16
|
+
private canvas;
|
|
17
|
+
private ctx;
|
|
18
|
+
private engine;
|
|
19
|
+
private options;
|
|
20
|
+
private rootNode;
|
|
21
|
+
private nodes;
|
|
22
|
+
private eventManager;
|
|
23
|
+
private inputOverlay;
|
|
24
|
+
private accessibilityLayer;
|
|
25
|
+
private rafId;
|
|
26
|
+
private needsRedraw;
|
|
27
|
+
private frameCount;
|
|
28
|
+
private lastFrameTime;
|
|
29
|
+
constructor(canvas: HTMLCanvasElement, engine: IEngine, options?: Partial<CanvasRendererOptions>);
|
|
30
|
+
/**
|
|
31
|
+
* Setup HiDPI rendering
|
|
32
|
+
*/
|
|
33
|
+
private setupHiDPI;
|
|
34
|
+
/**
|
|
35
|
+
* Apply patches from engine
|
|
36
|
+
*/
|
|
37
|
+
applyPatches(patches: Patch[]): void;
|
|
38
|
+
/**
|
|
39
|
+
* Apply single patch
|
|
40
|
+
*/
|
|
41
|
+
private applyPatch;
|
|
42
|
+
/**
|
|
43
|
+
* Create new virtual node
|
|
44
|
+
*/
|
|
45
|
+
private onCreate;
|
|
46
|
+
/**
|
|
47
|
+
* Set property on node
|
|
48
|
+
*/
|
|
49
|
+
private onSetProp;
|
|
50
|
+
/**
|
|
51
|
+
* Set text on node
|
|
52
|
+
*/
|
|
53
|
+
private onSetText;
|
|
54
|
+
/**
|
|
55
|
+
* Insert node into tree
|
|
56
|
+
*/
|
|
57
|
+
private onInsert;
|
|
58
|
+
/**
|
|
59
|
+
* Move node in tree
|
|
60
|
+
*/
|
|
61
|
+
private onMove;
|
|
62
|
+
/**
|
|
63
|
+
* Remove node from tree
|
|
64
|
+
*/
|
|
65
|
+
private onRemove;
|
|
66
|
+
/**
|
|
67
|
+
* Schedule redraw
|
|
68
|
+
*/
|
|
69
|
+
private scheduleRedraw;
|
|
70
|
+
/**
|
|
71
|
+
* Main render function
|
|
72
|
+
*/
|
|
73
|
+
private render;
|
|
74
|
+
/**
|
|
75
|
+
* Draw layout bounds for debugging
|
|
76
|
+
*/
|
|
77
|
+
private drawLayoutBounds;
|
|
78
|
+
/**
|
|
79
|
+
* Get node by ID
|
|
80
|
+
*/
|
|
81
|
+
getNode(id: string): VirtualNode | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* Clear renderer
|
|
84
|
+
*/
|
|
85
|
+
clear(): void;
|
|
86
|
+
/**
|
|
87
|
+
* Register custom painter
|
|
88
|
+
*/
|
|
89
|
+
registerPainter(type: string, painter: PainterFunction): void;
|
|
90
|
+
/**
|
|
91
|
+
* Set renderer options
|
|
92
|
+
*/
|
|
93
|
+
setOptions(options: Partial<CanvasRendererOptions>): void;
|
|
94
|
+
/**
|
|
95
|
+
* Destroy renderer
|
|
96
|
+
*/
|
|
97
|
+
destroy(): void;
|
|
98
|
+
}
|
|
99
|
+
export {};
|
package/dist/canvas/renderer.js
CHANGED
|
@@ -151,7 +151,7 @@ function getAbsoluteBounds(node) {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
// src/canvas/text.ts
|
|
154
|
-
import { frameworkLoggers } from "@hypen-space/core";
|
|
154
|
+
import { frameworkLoggers } from "@hypen-space/core/logger";
|
|
155
155
|
var log = frameworkLoggers.canvas;
|
|
156
156
|
var textMetricsCache = new Map;
|
|
157
157
|
function getCacheKey(text, fontStyle, maxWidth) {
|
|
@@ -287,7 +287,12 @@ function computeLayout(ctx, node, availableWidth, availableHeight, x = 0, y = 0)
|
|
|
287
287
|
let width = parseSize(props.width);
|
|
288
288
|
let height = parseSize(props.height);
|
|
289
289
|
const type = node.type.toLowerCase();
|
|
290
|
-
if (type === "
|
|
290
|
+
if (type === "app") {
|
|
291
|
+
if (width === null)
|
|
292
|
+
width = availableAfterMargin.width;
|
|
293
|
+
if (height === null)
|
|
294
|
+
height = availableAfterMargin.height;
|
|
295
|
+
} else if (type === "spacer") {
|
|
291
296
|
if (width === null)
|
|
292
297
|
width = availableAfterMargin.width;
|
|
293
298
|
if (height === null)
|
|
@@ -410,10 +415,10 @@ function layoutChildren(ctx, parent) {
|
|
|
410
415
|
return;
|
|
411
416
|
}
|
|
412
417
|
const flexDirection = props.flexDirection || (parent.type === "column" ? "column" : "row");
|
|
413
|
-
const justifyContent = props.justifyContent || "flex-start";
|
|
414
|
-
const alignItems = props.alignItems || "flex-start";
|
|
415
|
-
const gap = parseFloat(props.gap) || 0;
|
|
416
418
|
const isColumn = flexDirection === "column";
|
|
419
|
+
const justifyContent = isColumn ? props.verticalAlignment || "flex-start" : props.horizontalAlignment || "flex-start";
|
|
420
|
+
const alignItems = isColumn ? props.horizontalAlignment || "flex-start" : props.verticalAlignment || "flex-start";
|
|
421
|
+
const gap = parseFloat(props.gap) || 0;
|
|
417
422
|
const availableWidth = layout.contentWidth;
|
|
418
423
|
const availableHeight = layout.contentHeight;
|
|
419
424
|
const childInfo = [];
|
|
@@ -526,8 +531,8 @@ function layoutChildren(ctx, parent) {
|
|
|
526
531
|
function layoutStackChildren(ctx, parent) {
|
|
527
532
|
const layout = parent.layout;
|
|
528
533
|
const props = parent.props;
|
|
529
|
-
const
|
|
530
|
-
const
|
|
534
|
+
const horizontalAlignment = props.horizontalAlignment || "flex-start";
|
|
535
|
+
const verticalAlignment = props.verticalAlignment || "flex-start";
|
|
531
536
|
const availableWidth = layout.contentWidth;
|
|
532
537
|
const availableHeight = layout.contentHeight;
|
|
533
538
|
for (const child of parent.children) {
|
|
@@ -535,14 +540,14 @@ function layoutStackChildren(ctx, parent) {
|
|
|
535
540
|
const childLayout = child.layout;
|
|
536
541
|
let x = 0;
|
|
537
542
|
let y = 0;
|
|
538
|
-
if (
|
|
543
|
+
if (horizontalAlignment === "center") {
|
|
539
544
|
x = (availableWidth - childLayout.width) / 2;
|
|
540
|
-
} else if (
|
|
545
|
+
} else if (horizontalAlignment === "flex-end") {
|
|
541
546
|
x = availableWidth - childLayout.width;
|
|
542
547
|
}
|
|
543
|
-
if (
|
|
548
|
+
if (verticalAlignment === "center") {
|
|
544
549
|
y = (availableHeight - childLayout.height) / 2;
|
|
545
|
-
} else if (
|
|
550
|
+
} else if (verticalAlignment === "flex-end") {
|
|
546
551
|
y = availableHeight - childLayout.height;
|
|
547
552
|
}
|
|
548
553
|
childLayout.x = layout.x + layout.contentX + x;
|
|
@@ -629,6 +634,7 @@ function paintNode(ctx, node) {
|
|
|
629
634
|
case "link":
|
|
630
635
|
paintLink(ctx, node);
|
|
631
636
|
break;
|
|
637
|
+
case "app":
|
|
632
638
|
case "container":
|
|
633
639
|
case "box":
|
|
634
640
|
paintContainer(ctx, node);
|
|
@@ -1607,13 +1613,17 @@ class InputOverlay {
|
|
|
1607
1613
|
overlay = null;
|
|
1608
1614
|
focusedNode = null;
|
|
1609
1615
|
onChangeCallback = null;
|
|
1616
|
+
bindPath = null;
|
|
1617
|
+
engine = null;
|
|
1610
1618
|
constructor(container) {
|
|
1611
1619
|
this.container = container || {};
|
|
1612
1620
|
}
|
|
1613
|
-
showInput(node, canvasBounds, onChange) {
|
|
1621
|
+
showInput(node, canvasBounds, onChange, engine) {
|
|
1614
1622
|
if (typeof document === "undefined")
|
|
1615
1623
|
return;
|
|
1616
1624
|
this.hideInput();
|
|
1625
|
+
this.bindPath = node.props.bind || null;
|
|
1626
|
+
this.engine = engine || null;
|
|
1617
1627
|
const bounds = getAbsoluteBounds(node);
|
|
1618
1628
|
if (!bounds)
|
|
1619
1629
|
return;
|
|
@@ -1637,6 +1647,8 @@ class InputOverlay {
|
|
|
1637
1647
|
}
|
|
1638
1648
|
this.focusedNode = null;
|
|
1639
1649
|
this.onChangeCallback = null;
|
|
1650
|
+
this.bindPath = null;
|
|
1651
|
+
this.engine = null;
|
|
1640
1652
|
}
|
|
1641
1653
|
updatePosition(node, canvasBounds) {
|
|
1642
1654
|
if (!this.overlay || node !== this.focusedNode)
|
|
@@ -1698,6 +1710,12 @@ class InputOverlay {
|
|
|
1698
1710
|
return;
|
|
1699
1711
|
const value = this.overlay.value;
|
|
1700
1712
|
this.onChangeCallback(value);
|
|
1713
|
+
if (this.bindPath && this.engine) {
|
|
1714
|
+
this.engine.dispatchAction("__hypen_bind", {
|
|
1715
|
+
path: this.bindPath,
|
|
1716
|
+
value
|
|
1717
|
+
});
|
|
1718
|
+
}
|
|
1701
1719
|
}
|
|
1702
1720
|
onBlur() {
|
|
1703
1721
|
this.hideInput();
|
|
@@ -1867,7 +1885,7 @@ class AccessibilityLayer {
|
|
|
1867
1885
|
}
|
|
1868
1886
|
|
|
1869
1887
|
// src/canvas/renderer.ts
|
|
1870
|
-
import { frameworkLoggers as frameworkLoggers2 } from "@hypen-space/core";
|
|
1888
|
+
import { frameworkLoggers as frameworkLoggers2 } from "@hypen-space/core/logger";
|
|
1871
1889
|
var log2 = frameworkLoggers2.canvas;
|
|
1872
1890
|
var DEFAULT_OPTIONS = {
|
|
1873
1891
|
devicePixelRatio: typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1,
|
|
@@ -2121,4 +2139,4 @@ export {
|
|
|
2121
2139
|
CanvasRenderer
|
|
2122
2140
|
};
|
|
2123
2141
|
|
|
2124
|
-
//# debugId=
|
|
2142
|
+
//# debugId=BE7E20D4D1A9D99264756E2164756E21
|