Untitled
unknown
plain_text
3 months ago
5.2 kB
6
Indexable
import React, { useState, useRef } from 'react';
import { PDFDocument, rgb } from 'pdf-lib';
function App() {
const [fajl, setFajl] = useState(null);
const [url, setUrl] = useState(null);
const [kvadrati, setKvadrati] = useState([]);
const [trenutni, setTrenutni] = useState(null);
const [crtanje, setCrtanje] = useState(false);
const [mod, setMod] = useState(false);
const [boja, setBoja] = useState('#ff0000');
const [start, setStart] = useState({ x: 0, y: 0 });
const okviriRef = useRef(null);
const pretvoriBoje = (hex) => {
const r = parseInt(hex.slice(1, 3), 16) / 255;
const g = parseInt(hex.slice(3, 5), 16) / 255;
const b = parseInt(hex.slice(5, 7), 16) / 255;
return rgb(r, g, b);
};
const ucitajPdf = async (e) => {
const f = e.target.files[0];
if (f) {
const buffer = await f.arrayBuffer();
setFajl(buffer);
setUrl(URL.createObjectURL(f));
setKvadrati([]);
setMod(false);
}
};
const skiniPdf = async () => {
if (!fajl || kvadrati.length === 0) return;
const doc = await PDFDocument.load(fajl);
const stranica = doc.getPages()[0];
const { width: pW, height: pH } = stranica.getSize();
const dW = okviriRef.current.clientWidth;
const dH = okviriRef.current.clientHeight;
const sX = pW / dW;
const sY = pH / dH;
kvadrati.forEach((k) => {
stranica.drawRectangle({
x: k.x * sX,
y: pH - (k.y * sY) - (k.h * sY),
width: k.w * sX,
height: k.h * sY,
borderColor: pretvoriBoje(k.b),
borderWidth: 2,
});
});
const bytes = await doc.save();
const b = new Blob([bytes], { type: 'application/pdf' });
const a = document.createElement('a');
a.href = URL.createObjectURL(b);
a.download = "izmjena.pdf";
a.click();
};
return (
<div style={{ height: '100vh', display: 'flex', flexDirection: 'column', background: '#222', color: '#fff' }}>
<header style={{ padding: '15px', background: '#000', display: 'flex', gap: '15px', alignItems: 'center' }}>
<input type="file" accept=".pdf" onChange={ucitajPdf} />
{url && (
<>
<input type="color" value={boja} onChange={(e) => setBoja(e.target.value)} />
<button onClick={() => setMod(!mod)} style={{ background: mod ? 'orange' : '#2196f3', color: 'white', padding: '8px 15px', cursor: 'pointer' }}>
{mod ? "Ugasi" : "Crtaj"}
</button>
{kvadrati.length > 0 && (
<>
<button onClick={skiniPdf} style={{ background: 'green', color: 'white', padding: '8px 15px' }}>Sačuvaj</button>
<button onClick={() => setKvadrati([])} style={{ background: '#f44336', color: 'white', padding: '8px 15px' }}>Obriši</button>
</>
)}
</>
)}
</header>
<div style={{ flex: 1, display: 'flex', justifyContent: 'center', overflow: 'auto', padding: '20px' }}>
{url && (
<div
ref={okviriRef}
onMouseDown={(e) => {
if (!mod) return;
const r = okviriRef.current.getBoundingClientRect();
const x = e.clientX - r.left;
const y = e.clientY - r.top;
setCrtanje(true);
setStart({ x, y });
setTrenutni({ x, y, w: 0, h: 0, b: boja });
}}
onMouseMove={(e) => {
if (!crtanje) return;
const r = okviriRef.current.getBoundingClientRect();
const x = e.clientX - r.left;
const y = e.clientY - r.top;
setTrenutni({
...trenutni,
x: Math.min(start.x, x),
y: Math.min(start.y, y),
w: Math.abs(x - start.x),
h: Math.abs(y - start.y)
});
}}
onMouseUp={() => {
if (trenutni && trenutni.w > 5) setKvadrati([...kvadrati, trenutni]);
setCrtanje(false);
setTrenutni(null);
}}
style={{ position: 'relative', width: '800px', height: '1100px', background: '#fff' }}
>
<iframe
src={`${url}#toolbar=0&navpanes=0&view=FitH`}
style={{ width: '100%', height: '100%', border: 'none', pointerEvents: mod ? 'none' : 'auto' }}
/>
<div style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', pointerEvents: 'none' }}>
{kvadrati.map((k, i) => (
<div key={i} style={{ position: 'absolute', left: k.x, top: k.y, width: k.w, height: k.h, border: `2px solid ${k.b}` }} />
))}
{trenutni && (
<div style={{ position: 'absolute', left: trenutni.x, top: trenutni.y, width: trenutni.w, height: trenutni.h, border: `2px dotted ${trenutni.b}` }} />
)}
</div>
</div>
)}
</div>
</div>
);
}
export default App;
Editor is loading...
Leave a Comment