// view.ts /** * ============================================================================ * CONFIGURATION VIEWS - Visual Representation * ============================================================================ * * CONCEPTO: * * Una SECCIÓN puede tener MÚLTIPLES VISTAS * * Ejemplo: Sección "Salón" * - Vista "Frontal": Muestra pared frontal con ventanas y muebles * - Vista "Lateral": Muestra pared lateral con puerta * - Vista "Cenital": Vista desde arriba, muestra distribución * - Vista "360": Vista panorámica * * Cada vista tiene: * - Su propia imagen base * - Sus propios hotspots (puntos interactivos) * - Configuración de cómo se genera la URL de imagen * * ============================================================================ */ import type { ID } from './primitives.ts'; import type { I18nString } from './i18n'; import type { JsonLogic } from "./json_logic.ts"; import type {Attribute, AttrID} from "./vce_model.ts"; // ============================================================================ // VIEW TYPES (Tipos de Vista) // ============================================================================ export type ViewID = ID<'vw'>; export type HotspotID = ID<'hs'>; /** * Tipos de vista predefinidos */ type ViewType = | 'front' // Vista frontal | 'side' // Vista lateral | 'rear' // Vista posterior | 'top' // Vista desde arriba | 'isometric' // Vista isométrica/3D | 'panoramic' // Vista 360° panorámica | 'detail' // Vista de detalle/zoom | 'blueprint' // Plano/blueprint | 'custom'; // Tipo personalizado // ============================================================================ // HOTSPOT (Punto Interactivo) // ============================================================================ /** * Punto interactivo en una vista * Al hacer click, permite configurar un atributo específico */ export interface Hotspot { /** ID único del hotspot */ id: HotspotID; /** Nombre descriptivo */ name: I18nString; /** Posición X en porcentaje (0-100) */ x: number; /** Posición Y en porcentaje (0-100) */ y: number; /** Radio del hotspot en píxeles */ radius?: number; /** Color del hotspot (hex, rgb, etc.) */ color?: string; /** Icono del hotspot */ icon?: string; /** Tipo de scope al que referencia */ scopeType: 'global' | 'section'; /** ID del atributo que este hotspot controla */ targetAttributeId: AttrID; /** Si es visible (puede ser condicional) */ visible?: boolean | JsonLogic; /** Tooltip al hacer hover */ tooltip?: I18nString; /** Orden z-index para superposición */ zIndex?: number; } // ============================================================================ // VIEW (Vista Visual de una Sección) // ============================================================================ /** * Vista visual de una sección * Una sección puede tener múltiples vistas */ export interface SectionView { /** ID único de la vista */ id: ViewID; /** Nombre de la vista */ name: I18nString; /** Descripción */ description?: I18nString; /** Tipo de vista */ type: ViewType; /** Configuración visual de esta vista */ visualConfig: ViewVisualConfig; /** Hotspots interactivos (OPCIONAL) */ hotspots?: Hotspot[]; /** Orden de esta vista en la navegación */ order?: number; /** Si es la vista por defecto para esta sección */ isDefault?: boolean; /** Icono para el selector de vistas */ icon?: string; /** Si está visible (puede ser condicional) */ visible?: boolean | JsonLogic; } /** * Configuración visual específica de una vista */ export interface ViewVisualConfig { /** Estrategia de renderizado */ strategy: RenderingStrategy; /** Template para URL de imagen */ imageUrlTemplate?: string; /** Ruta base de imágenes */ basePath?: string; /** Atributos globales que afectan a esta vista */ globalAttributeDependencies?: AttrID[]; /** Atributos de sección que afectan a esta vista */ sectionAttributeDependencies?: AttrID[]; /** Imagen de fallback */ fallbackImage?: string; /** Config para API */ apiConfig?: { endpoint: string; method?: 'GET' | 'POST'; params?: AttrID[]; timeout?: number; }; /** Config 3D */ threeDConfig?: { modelUrl: string; cameraPosition?: { x: number; y: number; z: number }; textureAttributes?: Array<{ attributeId: AttrID; scope: 'global' | 'section'; }>; }; } export type RenderingStrategy = | 'static_image' | 'dynamic_image' | 'api_generated' | 'three_d' | 'composite_layers' | 'none';