git / Editor-PDF.html
KEXEL's picture
1.1
d5c74b4 verified
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Editor de PDF</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.14.305/pdf.min.js"></script>
<style>
canvas {
border: 1px solid #ccc;
margin: 10px auto;
cursor: crosshair;
display: block;
}
</style>
</head>
<body class="bg-gray-100 text-gray-800 min-h-screen p-6">
<div class="max-w-4xl mx-auto bg-white shadow-lg rounded-lg p-6">
<h1 class="text-3xl font-bold mb-6 text-center">📄 Editor de PDF</h1>
<input type="file" id="pdfInput" accept="application/pdf" class="mb-4 block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100" />
<div class="flex flex-wrap gap-4 justify-center mb-4">
<button id="prevPage" class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">⬅️ Página Anterior</button>
<button id="nextPage" class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">➡️ Próxima Página</button>
<span id="pageInfo" class="text-lg self-center font-medium">Página 1</span>
</div>
<div class="flex flex-wrap gap-3 justify-center mb-4">
<button id="addTextBtn" class="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600">✍️ Adicionar Texto</button>
<button id="addRectBtn" class="bg-yellow-500 text-white px-4 py-2 rounded hover:bg-yellow-600">🟦 Adicionar Retângulo</button>
<button id="clearBtn" class="bg-red-500 text-white px-4 py-2 rounded hover:bg-red-600">🧹 Limpar Anotações</button>
<button id="downloadBtn" class="bg-purple-500 text-white px-4 py-2 rounded hover:bg-purple-600">⬇️ Baixar como PNG</button>
</div>
<canvas id="pdfCanvas" class="bg-white shadow-md mx-auto"></canvas>
</div>
<script>
const fileInput = document.getElementById('pdfInput');
const canvas = document.getElementById('pdfCanvas');
const ctx = canvas.getContext('2d');
const pageInfo = document.getElementById('pageInfo');
const addTextBtn = document.getElementById('addTextBtn');
const addRectBtn = document.getElementById('addRectBtn');
const clearBtn = document.getElementById('clearBtn');
const downloadBtn = document.getElementById('downloadBtn');
const prevPageBtn = document.getElementById('prevPage');
const nextPageBtn = document.getElementById('nextPage');
let pdfDoc = null;
let currentPage = 1;
let isAddingText = false;
let isAddingRect = false;
let tempRectStart = null;
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.14.305/pdf.worker.min.js';
fileInput.addEventListener('change', async (e) => {
const file = e.target.files[0];
if (!file) return;
const fileReader = new FileReader();
fileReader.onload = async () => {
pdfDoc = await pdfjsLib.getDocument({ data: fileReader.result }).promise;
currentPage = 1;
renderPage(currentPage);
};
fileReader.readAsBinaryString(file);
});
function renderPage(pageNumber) {
if (!pdfDoc) return;
pdfDoc.getPage(pageNumber).then(async (page) => {
const viewport = page.getViewport({ scale: 1.5 });
canvas.width = viewport.width;
canvas.height = viewport.height;
await page.render({ canvasContext: ctx, viewport }).promise;
pageInfo.textContent = `Página ${pageNumber} de ${pdfDoc.numPages}`;
});
}
prevPageBtn.addEventListener('click', () => {
if (currentPage > 1) {
currentPage--;
renderPage(currentPage);
}
});
nextPageBtn.addEventListener('click', () => {
if (currentPage < pdfDoc?.numPages) {
currentPage++;
renderPage(currentPage);
}
});
addTextBtn.addEventListener('click', () => {
isAddingText = true;
isAddingRect = false;
alert('Clique no local onde deseja inserir o texto.');
});
addRectBtn.addEventListener('click', () => {
isAddingRect = true;
isAddingText = false;
alert('Clique e arraste para desenhar um retângulo.');
});
canvas.addEventListener('click', (e) => {
if (isAddingText) {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const text = prompt("Digite o texto:");
if (text) {
ctx.fillStyle = 'red';
ctx.font = '20px Arial';
ctx.fillText(text, x, y);
}
isAddingText = false;
}
});
canvas.addEventListener('mousedown', (e) => {
if (isAddingRect) {
const rect = canvas.getBoundingClientRect();
tempRectStart = {
x: e.clientX - rect.left,
y: e.clientY - rect.top
};
}
});
canvas.addEventListener('mouseup', (e) => {
if (isAddingRect && tempRectStart) {
const rect = canvas.getBoundingClientRect();
const endX = e.clientX - rect.left;
const endY = e.clientY - rect.top;
const width = endX - tempRectStart.x;
const height = endY - tempRectStart.y;
ctx.strokeStyle = 'blue';
ctx.lineWidth = 2;
ctx.strokeRect(tempRectStart.x, tempRectStart.y, width, height);
tempRectStart = null;
isAddingRect = false;
}
});
clearBtn.addEventListener('click', () => {
renderPage(currentPage); // Re-renderiza a página sem as anotações
});
downloadBtn.addEventListener('click', () => {
const link = document.createElement('a');
link.download = `pagina_${currentPage}.png`;
link.href = canvas.toDataURL();
link.click();
});
</script>
</body>
</html>