diff --git a/src/components/Holos/Canvas.vue b/src/components/Holos/PDF/Canvas.vue
similarity index 73%
rename from src/components/Holos/Canvas.vue
rename to src/components/Holos/PDF/Canvas.vue
index e675454..92c32c1 100644
--- a/src/components/Holos/Canvas.vue
+++ b/src/components/Holos/PDF/Canvas.vue
@@ -31,12 +31,80 @@ const resizeStart = ref({ x: 0, y: 0, width: 0, height: 0 });
const fileInput = ref(null);
/** Propiedades computadas */
-const elementStyles = computed(() => ({
- left: `${props.element.x}px`,
- top: `${props.element.y}px`,
- width: `${props.element.width || 200}px`,
- height: `${props.element.height || 40}px`
-}));
+const elementStyles = computed(() => {
+ const baseStyles = {
+ left: `${props.element.x}px`,
+ top: `${props.element.y}px`,
+ width: `${props.element.width || 200}px`,
+ height: `${props.element.height || 40}px`
+ };
+
+ // Aplicar estilos de formato para elementos de texto
+ if (props.element.type === 'text' && props.element.formatting) {
+ const formatting = props.element.formatting;
+
+ if (formatting.fontSize) {
+ baseStyles.fontSize = `${formatting.fontSize}px`;
+ }
+
+ if (formatting.color) {
+ baseStyles.color = formatting.color;
+ }
+ }
+
+ return baseStyles;
+});
+
+// Propiedades computadas para clases CSS dinámicas
+const textContainerClasses = computed(() => {
+ if (props.element.type !== 'text') return {};
+
+ const formatting = props.element.formatting || {};
+
+ return {
+ 'font-bold': formatting.bold,
+ 'italic': formatting.italic,
+ 'underline': formatting.underline,
+ 'text-left': !formatting.textAlign || formatting.textAlign === 'left',
+ 'text-center': formatting.textAlign === 'center',
+ 'text-right': formatting.textAlign === 'right',
+ 'justify-start': !formatting.textAlign || formatting.textAlign === 'left',
+ 'justify-center': formatting.textAlign === 'center',
+ 'justify-end': formatting.textAlign === 'right'
+ };
+});
+
+const inputClasses = computed(() => {
+ if (props.element.type !== 'text') return {};
+
+ const formatting = props.element.formatting || {};
+
+ return {
+ 'font-bold': formatting.bold,
+ 'italic': formatting.italic,
+ 'underline': formatting.underline,
+ 'text-left': !formatting.textAlign || formatting.textAlign === 'left',
+ 'text-center': formatting.textAlign === 'center',
+ 'text-right': formatting.textAlign === 'right'
+ };
+});
+
+const inputStyles = computed(() => {
+ if (props.element.type !== 'text') return {};
+
+ const formatting = props.element.formatting || {};
+ const styles = {};
+
+ if (formatting.fontSize) {
+ styles.fontSize = `${formatting.fontSize}px`;
+ }
+
+ if (formatting.color) {
+ styles.color = formatting.color;
+ }
+
+ return styles;
+});
/** Watchers */
watch(() => props.isSelected, (selected) => {
@@ -304,7 +372,9 @@ const getMaxHeight = () => {
'cursor-text': isEditing && (element.type === 'text' || element.type === 'code'),
'cursor-se-resize': isResizing && resizeDirection === 'corner',
'cursor-e-resize': isResizing && resizeDirection === 'right',
- 'cursor-s-resize': isResizing && resizeDirection === 'bottom'
+ 'cursor-s-resize': isResizing && resizeDirection === 'bottom',
+ 'z-50': isSelected,
+ 'z-10': !isSelected
}"
>
@@ -316,10 +386,15 @@ const getMaxHeight = () => {
class="hidden"
/>
-
+
{
@blur="finishEditing"
@keydown="handleKeydown"
class="w-full bg-transparent outline-none cursor-text"
+ :class="inputClasses"
+ :style="inputStyles"
@mousedown.stop
/>
-
+
{{ element.content || 'Nuevo texto' }}
-
+
{
-
-
-
-
-
{{ element.fileName || 'script.js' }}
-
-
-
-
{{ element.content || 'console.log("Hola mundo");' }}
-
-
-
-
+
{
-
+
@@ -470,31 +528,60 @@ const getMaxHeight = () => {
-
-
+
-
+
startResizeEdge(event, 'right')"
- class="absolute top-1 bottom-1 -right-0.5 w-1 bg-blue-500 opacity-0 cursor-e-resize pointer-events-auto resize-handle-edge"
+ class="absolute top-2 bottom-2 -right-1 w-2 bg-blue-500 cursor-e-resize pointer-events-auto rounded-sm shadow-sm hover:bg-blue-600 transition-all"
title="Redimensionar ancho"
- >
+ >
+
+
+
-
+
startResizeEdge(event, 'bottom')"
- class="absolute -bottom-0.5 left-1 right-1 h-1 bg-blue-500 opacity-0 cursor-s-resize pointer-events-auto resize-handle-edge"
+ class="absolute -bottom-1 left-2 right-2 h-2 bg-blue-500 cursor-s-resize pointer-events-auto rounded-sm shadow-sm hover:bg-blue-600 transition-all"
title="Redimensionar alto"
- >
+ >
+
+
+
-
-
-
+
+
+
+
+
+
@@ -509,98 +596,55 @@ const getMaxHeight = () => {
class="absolute inset-0 bg-green-500 opacity-20 rounded pointer-events-none"
>
-
-
- {{ element.type === 'text' ? 'Doble clic para editar texto' : 'Doble clic para editar código' }}
- {{ element.type === 'code' ? ' (Ctrl+Enter para guardar)' : '' }}
-
-
-
-
- Arrastra las esquinas para redimensionar
-
-
- Guardar (Ctrl+Enter)
+ Guardar
{ isEditing = false; editValue = JSON.parse(JSON.stringify(element.content)); }"
class="px-3 py-1 bg-gray-600 hover:bg-gray-700 text-white text-xs rounded shadow-sm transition-colors"
>
- Cancelar (Esc)
+ Cancelar
\ No newline at end of file
diff --git a/src/components/Holos/Draggable.vue b/src/components/Holos/PDF/Draggable.vue
similarity index 100%
rename from src/components/Holos/Draggable.vue
rename to src/components/Holos/PDF/Draggable.vue
diff --git a/src/components/Holos/PDF/PDFViewport.vue b/src/components/Holos/PDF/PDFViewport.vue
new file mode 100644
index 0000000..5ea3d6a
--- /dev/null
+++ b/src/components/Holos/PDF/PDFViewport.vue
@@ -0,0 +1,353 @@
+
+
+
+
+
+
+
+
+ Página {{ currentPage }} de {{ totalPages }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ Math.round(ZOOM_LEVEL * 100) }}% • {{ currentPageSize.label }}
+
+
+
+
+ Nueva Página
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Página {{ pageIndex + 1 }}
+
+
+
+
+
+
+ {{ currentPageSize.label }}
+
+
+
+
+
+
+
+
+
+
handleDrop(e, pageIndex)"
+ @dragover="handleDragOver"
+ @click="(e) => handleClick(e, pageIndex)"
+ >
+
+
+
+
+
+
+
+
Página {{ pageIndex + 1 }}
+
Arrastra elementos aquí
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Generando PDF...
+
Procesando {{ totalPages }} página{{ totalPages !== 1 ? 's' : '' }}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/Holos/PDF/PageSizeSelector.vue b/src/components/Holos/PDF/PageSizeSelector.vue
new file mode 100644
index 0000000..1ec725e
--- /dev/null
+++ b/src/components/Holos/PDF/PageSizeSelector.vue
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
+ {{ selectedSize.name }}
+
+
+
+
+
+
+ Tamaños de página
+
+
+
+
+
+
+
+
{{ size.label }}
+
{{ size.description }}
+
+ {{ size.width }} x {{ size.height }} px
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/Holos/PDF/TextFormatter.vue b/src/components/Holos/PDF/TextFormatter.vue
new file mode 100644
index 0000000..eec22f7
--- /dev/null
+++ b/src/components/Holos/PDF/TextFormatter.vue
@@ -0,0 +1,233 @@
+
+
+
+
+
+
+
Estilo:
+
+
+ B
+
+
+
+ I
+
+
+
+ U
+
+
+
+
+
+
+
+
+
+ Tamaño:
+
+
+ {{ size }}px
+
+
+
+
+
+
+
+
+
+
Alinear:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Elemento de texto seleccionado
+
+
+
\ No newline at end of file
diff --git a/src/components/Holos/PDFViewport.vue b/src/components/Holos/PDFViewport.vue
deleted file mode 100644
index 967ca1b..0000000
--- a/src/components/Holos/PDFViewport.vue
+++ /dev/null
@@ -1,261 +0,0 @@
-
-
-
-
-
-
-
-
- Página {{ currentPage }} de {{ totalPages }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Nueva Página
-
-
-
-
-
-
-
-
-
-
-
- Página {{ pageIndex + 1 }}
-
-
-
-
-
-
-
-
handleDrop(e, pageIndex)"
- @dragover="handleDragOver"
- @click="(e) => handleClick(e, pageIndex)"
- >
-
-
-
-
-
-
-
-
-
-
-
Página {{ pageIndex + 1 }}
-
Arrastra elementos aquí
-
-
-
-
-
-
- 210 × 297 mm (A4)
-
-
-
-
-
-
- Nueva Página
-
-
-
-
-
-
-
-
-
Generando PDF...
-
Procesando {{ totalPages }} página{{ totalPages !== 1 ? 's' : '' }}
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/pages/Maquetador/Index.vue b/src/pages/Maquetador/Index.vue
index a9f2790..af51117 100644
--- a/src/pages/Maquetador/Index.vue
+++ b/src/pages/Maquetador/Index.vue
@@ -1,10 +1,11 @@