Untitled

 avatar
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