Descripción
PaintBoard es un lienzo de dibujo interactivo basado en la web, inspirado en las clásicas aplicaciones de pintura digital. Ofrece a los usuarios la libertad de crear con una variedad de herramientas de dibujo como lápiz, formas geométricas (cuadrados, círculos, elipses, triángulos, rectángulos redondeados y líneas), y un borrador. La aplicación proporciona un control intuitivo sobre el color de la línea y el relleno, así como el grosor del trazo. Incorpora guías visuales y un cursor preciso para mejorar la experiencia de dibujo, haciendo de PaintBoard una herramienta sencilla pero efectiva para la expresión artística digital.
Características clave
- Herramientas de Dibujo Variadas:
Incluye lápiz (trazado libre), cuadrado, círculo, elipse, triángulo, rectángulo redondeado y líneas, así como una herramienta de borrador.
- Control de Color:
Permite seleccionar colores de línea y de relleno a través de una paleta predefinida o un selector de color (color picker).
- Opciones de Borde y Relleno:
Posibilidad de desactivar el borde o el relleno de las formas, ofreciendo mayor flexibilidad creativa.
- Ajuste de Grosor:
Control de grosor para las líneas de dibujo y el tamaño del borrador.
- Guías Visuales:
Muestra reglas interactivas en los ejes X e Y, junto con un sistema de coordenadas y un cursor que sigue el puntero, ayudando a la precisión del dibujo.
- Retroalimentación del Cursor:
Cambia el icono del cursor según la herramienta seleccionada (lápiz, borrador, etc.).
- Interfaz Intuitiva:
Botones visuales para seleccionar herramientas y colores, facilitando su uso.
Aspectos destacados del código
- API de Canvas 2D:
Uso extensivo de HTMLCanvasElement.getContext('2d') y sus métodos (beginPath, moveTo, lineTo, arc, ellipse, rect, roundRect, stroke, fill, clearRect) para dibujar dinámicamente en el lienzo.
-
// Este fragmento muestra cómo se definen las rutas y se dibujan las formas en el canvas. // Por ejemplo, para dibujar una línea: const LineDrawing = (cursorX, cursorY) => { ctxCanvas.beginPath(); ctxCanvas.moveTo(initX, initY); ctxCanvas.lineTo(cursorX, cursorY); ctxCanvas.stroke(); } - Manejo Avanzado de Eventos de Mouse:
Implementación de mousedown, mousemove, y mouseup para capturar la interacción del usuario y dibujar en tiempo real, incluyendo el cálculo de posiciones y tamaños de formas.
-
const MouseDown = (e) => { initX = e.offsetX; initY = e.offsetY; ctxCanvas.lineWidth = lineTickness; ctxCanvas.strokeStyle = lineColor; ctxCanvas.fillStyle = fillColor; ctxCanvas.lineCap = "round"; ctxCanvas.lineJoin = "round"; // ... lógica para el tipo de dibujo ... canvas.addEventListener("mousemove", MouseMove); } - Manipulación Dinámica del DOM:
Creación y modificación de elementos HTML (como las reglas y las guías de dibujo) en función de las interacciones del usuario y el tamaño de la ventana.
-
function CreateRuleX() { let numberOfPixels = ruleXContainer.getBoundingClientRect().width / 5; let coorXRule = 0; for (let index = 0; index < numberOfPixels / 2; index++) { const drawingGuide = document.createElement('div'); ruleXContainer.appendChild(drawingGuide); if (index == 0) { drawingGuide.style.width = "11px"; } if (index % 10 == 0) { drawingGuide.style.height = "10px"; const newChildMeasX = document.createElement('p'); drawingGuide.appendChild(newChildMeasX); const newChildTextX = document.createTextNode(coorXRule); newChildMeasX.appendChild(newChildTextX); coorXRule += 100; } } sizeCanvas = ruleXContainer.getBoundingClientRect().width + "px"; } - Gestión de Herramientas y Estados:
Lógica para cambiar entre herramientas de dibujo, gestionar los colores activos (línea y relleno), y actualizar el grosor del trazo/borrador.
-
for (let index = 0; index < buttonsTools.length; index++) { buttonsTools.item(index).addEventListener("mousedown", function (e) { drawingType = index + 1; initX = null; initY = null; for (const button of buttonsTools) { button.classList.remove("selectedButtonTools"); } e.target.classList.add("selectedButtonTools"); // ... lógica para cursor y habilitar/deshabilitar sliders ... }); } - Guías de Dibujo en Tiempo Real:
Implementación de un div flotante (drawingGuide) que visualiza la forma que se está creando antes de dibujarla permanentemente en el canvas.
-
function CreateDrawingGuide(positionMove) { drawingGuide = document.createElement('div'); containerCanvas.appendChild(drawingGuide); if (positionMove) { drawingGuide.style.left = initX + "px"; drawingGuide.style.top = initY + "px"; } else { drawingGuide.style.left = (initX - eraserSize.value / 2) + "px"; drawingGuide.style.top = (initY - eraserSize.value / 2) + "px"; } }
Desafíos técnicos
- Rendimiento en el Dibujo en Tiempo Real:
Asegurar que el dibujo y la visualización de formas sean fluidos y sin latencia, especialmente con el lápiz (trazado libre), que requiere una actualización constante del Canvas.
- Precisión de Coordenadas:
Calcular correctamente las coordenadas y dimensiones para cada tipo de forma (cuadrados, círculos, triángulos, etc.) a medida que el usuario arrastra el mouse, y que estas se dibujen en la posición y tamaño esperados.
- Gestión del Estado de las Herramientas:
Mantener un seguimiento de la herramienta activa, el color seleccionado, el grosor del trazo, y si el relleno o el borde están activados, y aplicar estos estados correctamente a cada acción de dibujo.
- Interacción Compleja de Eventos:
Diferenciar entre los eventos mousedown, mousemove y mouseup para controlar el inicio, el proceso y la finalización de cada acción de dibujo (por ejemplo, arrastrar para dibujar una forma vs. un solo clic).
Aprendizajes obtenidos
- Dominio del API de Canvas 2D:
Profundicé en el uso de las diversas funciones del Canvas para dibujar formas complejas, gestionar rutas, y aplicar estilos.
- Sincronización de Eventos:
Aprendí a coordinar múltiples eventos del mouse para crear interacciones de dibujo más elaboradas, entendiendo el ciclo de vida de una acción de usuario (inicio, arrastre, fin).
- Programación Gráfica:
Adquirí experiencia en la lógica matemática necesaria para representar visualmente formas y líneas basadas en la entrada del usuario.
- Desarrollo de UI Dinámicas:
Mejoré mi capacidad para construir interfaces que reaccionan de manera instantánea y visual a las acciones del usuario, usando JavaScript para manipular tanto el Canvas como elementos HTML adicionales (reglas, guías).
Posibles mejoras / Ideas a implementar
- Función Deshacer/Rehacer:
Añadir un historial de acciones para permitir a los usuarios revertir o rehacer cambios.
- Guardar/Cargar Dibujos:
Implementar la capacidad de guardar el dibujo como una imagen (ej. PNG) y cargar dibujos existentes.
- Herramienta de Selección/Mover:
Permitir seleccionar formas u objetos dibujados para moverlos, redimensionarlos o eliminarlos.
- Herramienta de Texto:
Añadir la capacidad de insertar texto en el lienzo con opciones de fuente y tamaño.
- Más Pinceles:
Explorar diferentes tipos de pinceles o texturas para el lápiz.
- Relleno con Bote de Pintura:
Una herramienta para rellenar áreas cerradas con un color sólido.
- Zoom y Panorámica:
Funcionalidad para acercar/alejar y desplazarse por el lienzo.
- Capas:
Implementar un sistema básico de capas para organizar elementos del dibujo.
- Paleta de Colores Personalizable:
Permitir a los usuarios guardar sus colores favoritos.
Información
Herramientas
2023-01-14
JavaScript