Implementa o editor interativo de Canvas para montagem livre de cartazes
This commit is contained in:
+521
-6
@@ -7185,10 +7185,35 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const tamanho = document.getElementById('cartazTamanhoSelect') ? document.getElementById('cartazTamanhoSelect').value : 'A4';
|
||||
const orientacao = document.getElementById('cartazOrientacaoSelect') ? document.getElementById('cartazOrientacaoSelect').value : 'retrato';
|
||||
|
||||
const imgContainerHtml = cartazPreviewImageContainer.style.display === 'block'
|
||||
const imgContainerHtml = cartazPreviewImageContainer.style.display === 'block' && !canvasModeActive
|
||||
? `<div style="width: 100%; margin-bottom: 20px; border-radius: 8px; overflow: hidden; border: 2px solid rgba(0,0,0,0.1); text-align: center; background: rgba(0,0,0,0.02);"><img src="${cartazPreviewImage.src}" style="max-width: 100%; max-height: 350px; object-fit: contain; display: inline-block;"></div>`
|
||||
: '';
|
||||
|
||||
let printContent = '';
|
||||
if (canvasModeActive) {
|
||||
// Clone printable area and cleanup handles / active state borders for print output
|
||||
const tempContainer = document.createElement('div');
|
||||
tempContainer.innerHTML = cartazPrintableArea.innerHTML;
|
||||
tempContainer.querySelectorAll('.canvas-resize-handle').forEach(h => h.remove());
|
||||
tempContainer.querySelectorAll('.canvas-item').forEach(item => {
|
||||
item.classList.remove('active-item');
|
||||
item.removeAttribute('contenteditable');
|
||||
// We can remove border style only if it was a dashed editing border
|
||||
if (item.style.border.includes('dashed')) {
|
||||
item.style.border = 'none';
|
||||
}
|
||||
});
|
||||
printContent = tempContainer.innerHTML;
|
||||
} else {
|
||||
printContent = `
|
||||
<h1>${title}</h1>
|
||||
${imgContainerHtml}
|
||||
<div class="content-area">
|
||||
${cartazPreviewContent.innerHTML}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
const printWindow = window.open('', '_blank');
|
||||
printWindow.document.write(`
|
||||
<html>
|
||||
@@ -7225,6 +7250,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
border: ${border === 'none' ? 'none' : `${border} ${text}`};
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
container-type: inline-size;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
@@ -7260,6 +7288,18 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
li {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
/* Estilos específicos do Canvas no PDF/Print */
|
||||
.canvas-item {
|
||||
position: absolute !important;
|
||||
box-sizing: border-box;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
@media print {
|
||||
body { background: transparent; padding: 0; display: block; }
|
||||
.cartaz-frame {
|
||||
@@ -7277,11 +7317,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
</head>
|
||||
<body>
|
||||
<div class="cartaz-frame">
|
||||
<h1>${title}</h1>
|
||||
${imgContainerHtml}
|
||||
<div class="content-area">
|
||||
${cartazPreviewContent.innerHTML}
|
||||
</div>
|
||||
${printContent}
|
||||
</div>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
@@ -7409,4 +7445,483 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
cartazesHistoryContainer.innerHTML = '<div style="color: #ef4444; padding: 20px;">Erro ao carregar histórico de cartazes.</div>';
|
||||
}
|
||||
}
|
||||
|
||||
// --- MODO DESIGN CANVAS (EDITOR INTERATIVO DE CARTAZES) ---
|
||||
const btnCanvasModeToggle = document.getElementById('btnCanvasModeToggle');
|
||||
const canvasControlPanel = document.getElementById('canvasControlPanel');
|
||||
const btnCanvasAddText = document.getElementById('btnCanvasAddText');
|
||||
const btnCanvasAddCard = document.getElementById('btnCanvasAddCard');
|
||||
const canvasFontFamily = document.getElementById('canvasFontFamily');
|
||||
const canvasFontSize = document.getElementById('canvasFontSize');
|
||||
const canvasTextColor = document.getElementById('canvasTextColor');
|
||||
const canvasBgColorInput = document.getElementById('canvasBgColor');
|
||||
const btnCanvasZIndexUp = document.getElementById('btnCanvasZIndexUp');
|
||||
const btnCanvasZIndexDown = document.getElementById('btnCanvasZIndexDown');
|
||||
const btnCanvasDelete = document.getElementById('btnCanvasDelete');
|
||||
|
||||
let canvasModeActive = false;
|
||||
let selectedCanvasItem = null;
|
||||
let isDraggingCanvas = false;
|
||||
let isResizingCanvas = false;
|
||||
let dragStartX, dragStartY;
|
||||
let dragStartLeft, dragStartTop;
|
||||
let dragStartWidth, dragStartHeight;
|
||||
|
||||
function enterCanvasMode() {
|
||||
canvasModeActive = true;
|
||||
if (btnCanvasModeToggle) {
|
||||
btnCanvasModeToggle.textContent = '💾 Salvar Canvas';
|
||||
btnCanvasModeToggle.style.background = '#10a37f';
|
||||
btnCanvasModeToggle.style.color = 'white';
|
||||
}
|
||||
if (canvasControlPanel) canvasControlPanel.style.display = 'flex';
|
||||
|
||||
cartazPrintableArea.style.position = 'relative';
|
||||
const rectParent = cartazPrintableArea.getBoundingClientRect();
|
||||
|
||||
const items = [];
|
||||
if (cartazPreviewTitle) items.push(cartazPreviewTitle);
|
||||
if (cartazPreviewImageContainer && cartazPreviewImageContainer.style.display !== 'none') {
|
||||
items.push(cartazPreviewImageContainer);
|
||||
}
|
||||
|
||||
const cards = Array.from(cartazPreviewContent.children);
|
||||
cards.forEach(card => {
|
||||
items.push(card);
|
||||
});
|
||||
|
||||
const clientRects = items.map(item => item.getBoundingClientRect());
|
||||
|
||||
items.forEach((item, index) => {
|
||||
const rect = clientRects[index];
|
||||
|
||||
const leftPercent = ((rect.left - rectParent.left) / rectParent.width) * 100;
|
||||
const topPercent = ((rect.top - rectParent.top) / rectParent.height) * 100;
|
||||
const widthPercent = (rect.width / rectParent.width) * 100;
|
||||
const heightPercent = (rect.height / rectParent.height) * 100;
|
||||
|
||||
item.classList.add('canvas-item');
|
||||
item.style.position = 'absolute';
|
||||
item.style.left = `${leftPercent}%`;
|
||||
item.style.top = `${topPercent}%`;
|
||||
item.style.width = `${widthPercent}%`;
|
||||
item.style.height = `${heightPercent}%`;
|
||||
item.style.margin = '0';
|
||||
|
||||
item.setAttribute('contenteditable', 'true');
|
||||
|
||||
if (!item.querySelector('.canvas-resize-handle')) {
|
||||
const handle = document.createElement('div');
|
||||
handle.className = 'canvas-resize-handle';
|
||||
item.appendChild(handle);
|
||||
}
|
||||
|
||||
if (item.parentNode === cartazPreviewContent) {
|
||||
cartazPrintableArea.appendChild(item);
|
||||
}
|
||||
|
||||
setupCanvasItemEvents(item);
|
||||
});
|
||||
|
||||
cartazPreviewContent.style.display = 'none';
|
||||
showToast('Modo Design Canvas ativado! Arraste, redimensione e clique duas vezes para editar o texto.', 'info');
|
||||
}
|
||||
|
||||
function exitCanvasMode() {
|
||||
canvasModeActive = false;
|
||||
if (btnCanvasModeToggle) {
|
||||
btnCanvasModeToggle.textContent = '🎨 Design Canvas';
|
||||
btnCanvasModeToggle.style.background = 'transparent';
|
||||
btnCanvasModeToggle.style.color = 'var(--text-secondary)';
|
||||
}
|
||||
if (canvasControlPanel) canvasControlPanel.style.display = 'none';
|
||||
|
||||
if (selectedCanvasItem) {
|
||||
selectedCanvasItem.classList.remove('active-item');
|
||||
selectedCanvasItem = null;
|
||||
}
|
||||
|
||||
const items = cartazPrintableArea.querySelectorAll('.canvas-item');
|
||||
items.forEach(item => {
|
||||
item.removeAttribute('contenteditable');
|
||||
});
|
||||
|
||||
showToast('Layout do Canvas salvo com sucesso!', 'success');
|
||||
}
|
||||
|
||||
function setupCanvasItemEvents(item) {
|
||||
item.addEventListener('click', (e) => {
|
||||
if (!canvasModeActive) return;
|
||||
e.stopPropagation();
|
||||
|
||||
if (selectedCanvasItem) {
|
||||
selectedCanvasItem.classList.remove('active-item');
|
||||
}
|
||||
selectedCanvasItem = item;
|
||||
item.classList.add('active-item');
|
||||
|
||||
updateToolbarForSelected();
|
||||
});
|
||||
|
||||
item.addEventListener('mousedown', (e) => {
|
||||
if (!canvasModeActive) return;
|
||||
if (e.target.classList.contains('canvas-resize-handle')) return;
|
||||
|
||||
if (document.activeElement === item && e.target !== item && !e.target.classList.contains('canvas-item')) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
selectedCanvasItem = item;
|
||||
document.querySelectorAll('.canvas-item').forEach(el => el.classList.remove('active-item'));
|
||||
item.classList.add('active-item');
|
||||
updateToolbarForSelected();
|
||||
|
||||
isDraggingCanvas = true;
|
||||
dragStartX = e.clientX;
|
||||
dragStartY = e.clientY;
|
||||
|
||||
const parentRect = cartazPrintableArea.getBoundingClientRect();
|
||||
const itemRect = item.getBoundingClientRect();
|
||||
|
||||
dragStartLeft = ((itemRect.left - parentRect.left) / parentRect.width) * 100;
|
||||
dragStartTop = ((itemRect.top - parentRect.top) / parentRect.height) * 100;
|
||||
|
||||
document.addEventListener('mousemove', handleCanvasDrag);
|
||||
document.addEventListener('mouseup', stopCanvasDrag);
|
||||
});
|
||||
|
||||
item.addEventListener('touchstart', (e) => {
|
||||
if (!canvasModeActive) return;
|
||||
if (e.target.classList.contains('canvas-resize-handle')) return;
|
||||
|
||||
if (document.activeElement === item && e.target !== item) return;
|
||||
|
||||
selectedCanvasItem = item;
|
||||
document.querySelectorAll('.canvas-item').forEach(el => el.classList.remove('active-item'));
|
||||
item.classList.add('active-item');
|
||||
updateToolbarForSelected();
|
||||
|
||||
isDraggingCanvas = true;
|
||||
const touch = e.touches[0];
|
||||
dragStartX = touch.clientX;
|
||||
dragStartY = touch.clientY;
|
||||
|
||||
const parentRect = cartazPrintableArea.getBoundingClientRect();
|
||||
const itemRect = item.getBoundingClientRect();
|
||||
|
||||
dragStartLeft = ((itemRect.left - parentRect.left) / parentRect.width) * 100;
|
||||
dragStartTop = ((itemRect.top - parentRect.top) / parentRect.height) * 100;
|
||||
|
||||
document.addEventListener('touchmove', handleCanvasTouchDrag, { passive: false });
|
||||
document.addEventListener('touchend', stopCanvasDrag);
|
||||
});
|
||||
|
||||
const handle = item.querySelector('.canvas-resize-handle');
|
||||
if (handle) {
|
||||
handle.addEventListener('mousedown', (e) => {
|
||||
if (!canvasModeActive) return;
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
isResizingCanvas = true;
|
||||
dragStartX = e.clientX;
|
||||
dragStartY = e.clientY;
|
||||
|
||||
const parentRect = cartazPrintableArea.getBoundingClientRect();
|
||||
const itemRect = item.getBoundingClientRect();
|
||||
|
||||
dragStartWidth = (itemRect.width / parentRect.width) * 100;
|
||||
dragStartHeight = (itemRect.height / parentRect.height) * 100;
|
||||
|
||||
document.addEventListener('mousemove', handleCanvasResize);
|
||||
document.addEventListener('mouseup', stopCanvasResize);
|
||||
});
|
||||
|
||||
handle.addEventListener('touchstart', (e) => {
|
||||
if (!canvasModeActive) return;
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
isResizingCanvas = true;
|
||||
const touch = e.touches[0];
|
||||
dragStartX = touch.clientX;
|
||||
dragStartY = touch.clientY;
|
||||
|
||||
const parentRect = cartazPrintableArea.getBoundingClientRect();
|
||||
const itemRect = item.getBoundingClientRect();
|
||||
|
||||
dragStartWidth = (itemRect.width / parentRect.width) * 100;
|
||||
dragStartHeight = (itemRect.height / parentRect.height) * 100;
|
||||
|
||||
document.addEventListener('touchmove', handleCanvasTouchResize, { passive: false });
|
||||
document.addEventListener('touchend', stopCanvasResize);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function handleCanvasDrag(e) {
|
||||
if (!isDraggingCanvas || !selectedCanvasItem) return;
|
||||
const dx = e.clientX - dragStartX;
|
||||
const dy = e.clientY - dragStartY;
|
||||
const parentRect = cartazPrintableArea.getBoundingClientRect();
|
||||
const dxPercent = (dx / parentRect.width) * 100;
|
||||
const dyPercent = (dy / parentRect.height) * 100;
|
||||
|
||||
let newLeft = dragStartLeft + dxPercent;
|
||||
let newTop = dragStartTop + dyPercent;
|
||||
|
||||
const itemRect = selectedCanvasItem.getBoundingClientRect();
|
||||
const itemWPercent = (itemRect.width / parentRect.width) * 100;
|
||||
const itemHPercent = (itemRect.height / parentRect.height) * 100;
|
||||
|
||||
if (newLeft < 0) newLeft = 0;
|
||||
if (newTop < 0) newTop = 0;
|
||||
if (newLeft + itemWPercent > 100) newLeft = 100 - itemWPercent;
|
||||
if (newTop + itemHPercent > 100) newTop = 100 - itemHPercent;
|
||||
|
||||
selectedCanvasItem.style.left = `${newLeft}%`;
|
||||
selectedCanvasItem.style.top = `${newTop}%`;
|
||||
}
|
||||
|
||||
function handleCanvasTouchDrag(e) {
|
||||
if (!isDraggingCanvas || !selectedCanvasItem) return;
|
||||
e.preventDefault();
|
||||
const touch = e.touches[0];
|
||||
const dx = touch.clientX - dragStartX;
|
||||
const dy = touch.clientY - dragStartY;
|
||||
const parentRect = cartazPrintableArea.getBoundingClientRect();
|
||||
const dxPercent = (dx / parentRect.width) * 100;
|
||||
const dyPercent = (dy / parentRect.height) * 100;
|
||||
|
||||
let newLeft = dragStartLeft + dxPercent;
|
||||
let newTop = dragStartTop + dyPercent;
|
||||
|
||||
const itemRect = selectedCanvasItem.getBoundingClientRect();
|
||||
const itemWPercent = (itemRect.width / parentRect.width) * 100;
|
||||
const itemHPercent = (itemRect.height / parentRect.height) * 100;
|
||||
|
||||
if (newLeft < 0) newLeft = 0;
|
||||
if (newTop < 0) newTop = 0;
|
||||
if (newLeft + itemWPercent > 100) newLeft = 100 - itemWPercent;
|
||||
if (newTop + itemHPercent > 100) newTop = 100 - itemHPercent;
|
||||
|
||||
selectedCanvasItem.style.left = `${newLeft}%`;
|
||||
selectedCanvasItem.style.top = `${newTop}%`;
|
||||
}
|
||||
|
||||
function stopCanvasDrag() {
|
||||
isDraggingCanvas = false;
|
||||
document.removeEventListener('mousemove', handleCanvasDrag);
|
||||
document.removeEventListener('mouseup', stopCanvasDrag);
|
||||
document.removeEventListener('touchmove', handleCanvasTouchDrag);
|
||||
document.removeEventListener('touchend', stopCanvasDrag);
|
||||
}
|
||||
|
||||
function handleCanvasResize(e) {
|
||||
if (!isResizingCanvas || !selectedCanvasItem) return;
|
||||
const dx = e.clientX - dragStartX;
|
||||
const dy = e.clientY - dragStartY;
|
||||
const parentRect = cartazPrintableArea.getBoundingClientRect();
|
||||
const dxPercent = (dx / parentRect.width) * 100;
|
||||
const dyPercent = (dy / parentRect.height) * 100;
|
||||
|
||||
let newWidth = dragStartWidth + dxPercent;
|
||||
let newHeight = dragStartHeight + dyPercent;
|
||||
|
||||
if (newWidth < 10) newWidth = 10;
|
||||
if (newHeight < 5) newHeight = 5;
|
||||
|
||||
const itemLeft = parseFloat(selectedCanvasItem.style.left) || 0;
|
||||
const itemTop = parseFloat(selectedCanvasItem.style.top) || 0;
|
||||
|
||||
if (itemLeft + newWidth > 100) newWidth = 100 - itemLeft;
|
||||
if (itemTop + newHeight > 100) newHeight = 100 - itemTop;
|
||||
|
||||
selectedCanvasItem.style.width = `${newWidth}%`;
|
||||
selectedCanvasItem.style.height = `${newHeight}%`;
|
||||
}
|
||||
|
||||
function handleCanvasTouchResize(e) {
|
||||
if (!isResizingCanvas || !selectedCanvasItem) return;
|
||||
e.preventDefault();
|
||||
const touch = e.touches[0];
|
||||
const dx = touch.clientX - dragStartX;
|
||||
const dy = touch.clientY - dragStartY;
|
||||
const parentRect = cartazPrintableArea.getBoundingClientRect();
|
||||
const dxPercent = (dx / parentRect.width) * 100;
|
||||
const dyPercent = (dy / parentRect.height) * 100;
|
||||
|
||||
let newWidth = dragStartWidth + dxPercent;
|
||||
let newHeight = dragStartHeight + dyPercent;
|
||||
|
||||
if (newWidth < 10) newWidth = 10;
|
||||
if (newHeight < 5) newHeight = 5;
|
||||
|
||||
const itemLeft = parseFloat(selectedCanvasItem.style.left) || 0;
|
||||
const itemTop = parseFloat(selectedCanvasItem.style.top) || 0;
|
||||
|
||||
if (itemLeft + newWidth > 100) newWidth = 100 - itemLeft;
|
||||
if (itemTop + newHeight > 100) newHeight = 100 - itemTop;
|
||||
|
||||
selectedCanvasItem.style.width = `${newWidth}%`;
|
||||
selectedCanvasItem.style.height = `${newHeight}%`;
|
||||
}
|
||||
|
||||
function stopCanvasResize() {
|
||||
isResizingCanvas = false;
|
||||
document.removeEventListener('mousemove', handleCanvasResize);
|
||||
document.removeEventListener('mouseup', stopCanvasResize);
|
||||
document.removeEventListener('touchmove', handleCanvasTouchResize);
|
||||
document.removeEventListener('touchend', stopCanvasResize);
|
||||
}
|
||||
|
||||
function rgbToHex(rgb) {
|
||||
if (!rgb || rgb === 'transparent') return '#ffffff';
|
||||
if (rgb.startsWith('#')) return rgb;
|
||||
const match = rgb.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)$/);
|
||||
if (!match) return '#ffffff';
|
||||
const r = parseInt(match[1]);
|
||||
const g = parseInt(match[2]);
|
||||
const b = parseInt(match[3]);
|
||||
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
|
||||
}
|
||||
|
||||
function updateToolbarForSelected() {
|
||||
if (!selectedCanvasItem) return;
|
||||
|
||||
const ff = window.getComputedStyle(selectedCanvasItem).fontFamily.replace(/['"]/g, '').split(',')[0].trim();
|
||||
if (canvasFontFamily) canvasFontFamily.value = ff;
|
||||
|
||||
const fs = parseFloat(window.getComputedStyle(selectedCanvasItem).fontSize);
|
||||
if (canvasFontSize) canvasFontSize.value = Math.round(fs);
|
||||
|
||||
const col = rgbToHex(window.getComputedStyle(selectedCanvasItem).color);
|
||||
if (canvasTextColor) canvasTextColor.value = col;
|
||||
|
||||
const bg = rgbToHex(window.getComputedStyle(selectedCanvasItem).backgroundColor);
|
||||
if (canvasBgColorInput) canvasBgColorInput.value = bg;
|
||||
}
|
||||
|
||||
if (canvasFontFamily) {
|
||||
canvasFontFamily.addEventListener('change', () => {
|
||||
if (selectedCanvasItem) selectedCanvasItem.style.fontFamily = canvasFontFamily.value;
|
||||
});
|
||||
}
|
||||
if (canvasFontSize) {
|
||||
canvasFontSize.addEventListener('input', () => {
|
||||
if (selectedCanvasItem) selectedCanvasItem.style.fontSize = `${canvasFontSize.value}px`;
|
||||
});
|
||||
}
|
||||
if (canvasTextColor) {
|
||||
canvasTextColor.addEventListener('input', () => {
|
||||
if (selectedCanvasItem) selectedCanvasItem.style.color = canvasTextColor.value;
|
||||
});
|
||||
}
|
||||
if (canvasBgColorInput) {
|
||||
canvasBgColorInput.addEventListener('input', () => {
|
||||
if (selectedCanvasItem) selectedCanvasItem.style.backgroundColor = canvasBgColorInput.value;
|
||||
});
|
||||
}
|
||||
if (btnCanvasZIndexUp) {
|
||||
btnCanvasZIndexUp.addEventListener('click', () => {
|
||||
if (selectedCanvasItem) {
|
||||
const currentZ = parseInt(selectedCanvasItem.style.zIndex) || 1;
|
||||
selectedCanvasItem.style.zIndex = currentZ + 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (btnCanvasZIndexDown) {
|
||||
btnCanvasZIndexDown.addEventListener('click', () => {
|
||||
if (selectedCanvasItem) {
|
||||
const currentZ = parseInt(selectedCanvasItem.style.zIndex) || 1;
|
||||
selectedCanvasItem.style.zIndex = Math.max(1, currentZ - 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (btnCanvasDelete) {
|
||||
btnCanvasDelete.addEventListener('click', () => {
|
||||
if (selectedCanvasItem) {
|
||||
selectedCanvasItem.remove();
|
||||
selectedCanvasItem = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (btnCanvasAddText) {
|
||||
btnCanvasAddText.addEventListener('click', () => {
|
||||
if (!canvasModeActive) return;
|
||||
const textItem = document.createElement('div');
|
||||
textItem.className = 'canvas-item';
|
||||
textItem.innerHTML = 'Novo Texto (Clique duplo para editar)';
|
||||
textItem.style.left = '10%';
|
||||
textItem.style.top = '15%';
|
||||
textItem.style.width = '50%';
|
||||
textItem.style.height = '8%';
|
||||
textItem.style.fontSize = '20px';
|
||||
textItem.style.color = cartazTextColor.value || '#2d3748';
|
||||
textItem.style.fontFamily = cartazFontSelect.value || 'Fredoka';
|
||||
textItem.setAttribute('contenteditable', 'true');
|
||||
|
||||
const handle = document.createElement('div');
|
||||
handle.className = 'canvas-resize-handle';
|
||||
textItem.appendChild(handle);
|
||||
|
||||
cartazPrintableArea.appendChild(textItem);
|
||||
setupCanvasItemEvents(textItem);
|
||||
textItem.click();
|
||||
});
|
||||
}
|
||||
|
||||
if (btnCanvasAddCard) {
|
||||
btnCanvasAddCard.addEventListener('click', () => {
|
||||
if (!canvasModeActive) return;
|
||||
const cardItem = document.createElement('div');
|
||||
cardItem.className = 'canvas-item';
|
||||
cardItem.style.background = 'rgba(255, 255, 255, 0.4)';
|
||||
cardItem.style.border = '2px dashed ' + (cartazTextColor.value || '#2d3748');
|
||||
cardItem.style.borderRadius = '12px';
|
||||
cardItem.style.left = '20%';
|
||||
cardItem.style.top = '25%';
|
||||
cardItem.style.width = '45%';
|
||||
cardItem.style.height = '20%';
|
||||
cardItem.style.padding = '15px';
|
||||
cardItem.innerHTML = '<h3>Novo Card</h3><p>Edite este texto...</p>';
|
||||
cardItem.style.fontFamily = cartazFontSelect.value || 'Fredoka';
|
||||
cardItem.setAttribute('contenteditable', 'true');
|
||||
|
||||
const handle = document.createElement('div');
|
||||
handle.className = 'canvas-resize-handle';
|
||||
cardItem.appendChild(handle);
|
||||
|
||||
cartazPrintableArea.appendChild(cardItem);
|
||||
setupCanvasItemEvents(cardItem);
|
||||
cardItem.click();
|
||||
});
|
||||
}
|
||||
|
||||
if (btnCanvasModeToggle) {
|
||||
btnCanvasModeToggle.addEventListener('click', () => {
|
||||
if (canvasModeActive) {
|
||||
exitCanvasMode();
|
||||
} else {
|
||||
if (cartazEditArea && cartazEditArea.style.display !== 'none') {
|
||||
btnEditCartazToggle.click();
|
||||
}
|
||||
enterCanvasMode();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (cartazPrintableArea) {
|
||||
cartazPrintableArea.addEventListener('click', (e) => {
|
||||
if (!canvasModeActive) return;
|
||||
if (e.target === cartazPrintableArea) {
|
||||
if (selectedCanvasItem) {
|
||||
selectedCanvasItem.classList.remove('active-item');
|
||||
selectedCanvasItem = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
+38
-1
@@ -1850,11 +1850,48 @@
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--border-light); padding-bottom: 8px;">
|
||||
<h4 style="margin: 0; color: var(--text-primary);">👁️ Visualização do Cartaz</h4>
|
||||
<div style="display: flex; gap: 8px;">
|
||||
<button id="btnEditCartazToggle" class="btn-save-settings" style="background: transparent; border: 1px solid var(--border-light); color: var(--text-secondary); padding: 5px 10px; font-size: 0.75rem;">✏️ Editar Conteúdo</button>
|
||||
<button id="btnCanvasModeToggle" class="btn-save-settings" style="background: transparent; border: 1px solid var(--border-light); color: var(--text-secondary); padding: 5px 10px; font-size: 0.75rem;">🎨 Design Canvas</button>
|
||||
<button id="btnEditCartazToggle" class="btn-save-settings" style="background: transparent; border: 1px solid var(--border-light); color: var(--text-secondary); padding: 5px 10px; font-size: 0.75rem;">✏️ Editar HTML</button>
|
||||
<button id="btnPrintCartaz" class="btn-save-settings" style="background: #3b82f6; border: none; color: white; padding: 5px 12px; font-size: 0.75rem; font-weight: bold; border-radius: 6px;">🖨️ Imprimir Cartaz</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Painel de Controle do Canvas (Apenas visível no Modo Canvas) -->
|
||||
<div id="canvasControlPanel" style="display: none; background: var(--bg-secondary); border: 1px solid var(--border-light); padding: 10px; border-radius: 8px; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 8px;">
|
||||
<button id="btnCanvasAddText" class="btn-save-settings" style="background: #10a37f; color: white; border: none; padding: 4px 10px; font-size: 0.75rem; font-weight: 600; border-radius: 6px; cursor: pointer;">➕ Texto</button>
|
||||
<button id="btnCanvasAddCard" class="btn-save-settings" style="background: #a855f7; color: white; border: none; padding: 4px 10px; font-size: 0.75rem; font-weight: 600; border-radius: 6px; cursor: pointer;">➕ Card</button>
|
||||
|
||||
<div style="height: 20px; width: 1px; background: var(--border-light);"></div>
|
||||
|
||||
<!-- Controles do Item Selecionado -->
|
||||
<span style="font-size: 0.75rem; color: var(--text-secondary);">Item:</span>
|
||||
<select id="canvasFontFamily" class="obs-select" style="padding: 2px 5px; font-size: 0.75rem; min-width: 90px; margin: 0;">
|
||||
<option value="Fredoka">Fredoka</option>
|
||||
<option value="Outfit">Outfit</option>
|
||||
<option value="Caveat">Caveat</option>
|
||||
<option value="Playfair Display">Playfair</option>
|
||||
<option value="Arial">Arial</option>
|
||||
</select>
|
||||
|
||||
<input type="number" id="canvasFontSize" class="obs-input" style="width: 55px; padding: 2px 5px; font-size: 0.75rem; margin: 0;" min="8" max="72" value="16" title="Tamanho da fonte (px)">
|
||||
|
||||
<div style="display: flex; align-items: center; gap: 4px;">
|
||||
<label style="font-size: 0.72rem; color: var(--text-secondary);">Cor:</label>
|
||||
<input type="color" id="canvasTextColor" style="width: 24px; height: 24px; border: 1px solid var(--border-light); border-radius: 4px; padding: 0; cursor: pointer; background: transparent; margin: 0;">
|
||||
</div>
|
||||
|
||||
<div style="display: flex; align-items: center; gap: 4px;">
|
||||
<label style="font-size: 0.72rem; color: var(--text-secondary);">Fundo:</label>
|
||||
<input type="color" id="canvasBgColor" style="width: 24px; height: 24px; border: 1px solid var(--border-light); border-radius: 4px; padding: 0; cursor: pointer; background: transparent; margin: 0;">
|
||||
</div>
|
||||
|
||||
<div style="display: flex; gap: 4px; align-items: center;">
|
||||
<button id="btnCanvasZIndexUp" class="btn-save-settings" style="background: transparent; border: 1px solid var(--border-light); color: var(--text-secondary); padding: 2px 6px; font-size: 0.7rem; cursor: pointer;" title="Trazer para Frente">🔺</button>
|
||||
<button id="btnCanvasZIndexDown" class="btn-save-settings" style="background: transparent; border: 1px solid var(--border-light); color: var(--text-secondary); padding: 2px 6px; font-size: 0.7rem; cursor: pointer;" title="Enviar para Trás">🔻</button>
|
||||
<button id="btnCanvasDelete" class="btn-save-settings" style="background: #ef4444; color: white; border: none; padding: 2px 8px; font-size: 0.7rem; font-weight: bold; border-radius: 4px; cursor: pointer;" title="Excluir Elemento">🗑️ Excluir</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Área de Edição do Conteúdo (Inicialmente Oculta) -->
|
||||
<div id="cartazEditArea" style="display: none; flex-direction: column; gap: 8px;">
|
||||
<label style="color: var(--text-secondary); font-size: 0.78rem; font-weight: 600; text-transform: uppercase;">Editor HTML do Cartaz</label>
|
||||
|
||||
@@ -3685,6 +3685,60 @@ code {
|
||||
max-height: 100% !important;
|
||||
}
|
||||
|
||||
/* Estilos de Itens do Canvas (Arrastáveis e Redimensionáveis) */
|
||||
.canvas-item {
|
||||
position: absolute !important;
|
||||
box-sizing: border-box;
|
||||
cursor: move;
|
||||
border: 1px dashed rgba(59, 130, 246, 0.4);
|
||||
padding: 10px;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
border-radius: 8px;
|
||||
user-select: text; /* Permite selecionar texto interno para edição */
|
||||
}
|
||||
|
||||
.canvas-item:hover {
|
||||
border-color: rgba(59, 130, 246, 0.8);
|
||||
box-shadow: 0 0 8px rgba(59, 130, 246, 0.2);
|
||||
}
|
||||
|
||||
.canvas-item.active-item {
|
||||
border: 2.5px solid #3b82f6 !important;
|
||||
box-shadow: 0 0 12px rgba(59, 130, 246, 0.4);
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
/* Alça de redimensionamento do card */
|
||||
.canvas-resize-handle {
|
||||
position: absolute;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
background: #3b82f6;
|
||||
border: 2px solid white;
|
||||
border-radius: 50%;
|
||||
bottom: -7px;
|
||||
right: -7px;
|
||||
cursor: se-resize;
|
||||
z-index: 10;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.canvas-item.active-item .canvas-resize-handle {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Oculte alças e tracejados na impressão e exportação */
|
||||
@media print {
|
||||
.canvas-resize-handle {
|
||||
display: none !important;
|
||||
}
|
||||
.canvas-item {
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
cursor: default !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user