import type { CSSProperties } from "react"; import type { CanvasNode } from "@/domain/design"; export const defaultFrameFillColor = "#ffffff"; export const defaultFrameStrokeColor = "#2f80ff"; export const defaultFrameStrokeWidth = 1; export const defaultFrameStrokeStyle = "solid"; export function framePreviewStyle(node: CanvasNode): CSSProperties { const opacity = typeof node.opacity === "number" ? node.opacity : 1; return { background: colorWithOpacity(node.fillColor || defaultFrameFillColor, opacity), borderColor: node.strokeColor || defaultFrameStrokeColor, borderWidth: `${node.strokeWidth || defaultFrameStrokeWidth}px`, borderStyle: normalizeStrokeStyle(node.strokeStyle) }; } export function normalizeStrokeStyle(value: string | undefined) { if (value === "dashed" || value === "dotted") return value; return defaultFrameStrokeStyle; } export function normalizeHexColor(value: string, fallback: string) { const trimmed = value.trim(); if (/^#[0-9a-f]{6}$/i.test(trimmed)) return trimmed.toUpperCase(); if (/^[0-9a-f]{6}$/i.test(trimmed)) return `#${trimmed.toUpperCase()}`; return fallback; } function colorWithOpacity(color: string, opacity: number) { if (color === "transparent") return color; const normalized = normalizeHexColor(color, defaultFrameFillColor); const r = Number.parseInt(normalized.slice(1, 3), 16); const g = Number.parseInt(normalized.slice(3, 5), 16); const b = Number.parseInt(normalized.slice(5, 7), 16); return `rgba(${r}, ${g}, ${b}, ${Math.min(Math.max(opacity, 0), 1)})`; }