1
0
Fork 0
mirror of https://github.com/24eme/signaturepdf synced 2024-05-22 07:36:37 +02:00

Interface de signature de la première page d'un pdf (Preuve de

conception)
This commit is contained in:
Vincent LAURENT 2021-05-04 00:30:20 +02:00
parent 267351212a
commit 31c5f0cdb1
4 changed files with 209 additions and 0 deletions

33
index.html.php Normal file
View file

@ -0,0 +1,33 @@
<!doctype html>
<html lang="fr_FR">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.4.1/font/bootstrap-icons.css">
<title>Signature PDF</title>
</head>
<body>
<div class="px-4 py-5 my-5 text-center">
<h1 class="display-5 fw-bold"><i class="bi bi-vector-pen"></i> Signer un PDF</h1>
<div class="col-lg-3 mx-auto">
<form action="/upload" method="POST" class="row g-3" enctype="multipart/form-data">
<div class="col-12">
<label for="formFileLg" class="form-label">Choisir un PDF</label>
<input class="form-control form-control-lg" name="pdf" type="file">
</div>
<div class="col-12">
<div class="d-grid gap-2">
<button class="btn btn-light" type="submit" id="save"><i class="bi bi-upload"></i> Transmettre le PDF</button>
</div>
</div>
</form>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js" integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf" crossorigin="anonymous"></script>
</body>
</html>

63
index.php Normal file
View file

@ -0,0 +1,63 @@
<?php
$f3 = require(__DIR__.'/vendor/fatfree/lib/base.php');
$f3->set('DEBUG',1);
$f3->set('UPLOADS', $f3->get('ROOT').'/data/');
if(!is_dir($f3->get('UPLOADS'))) {
mkdir($f3->get('UPLOADS'));
}
$f3->route('GET /',
function($f3) {
$f3->set('key', $f3->get('PARAMS.key'));
echo View::instance()->render('index.html.php');
}
);
$f3->route('POST /upload',
function($f3) {
$files = Web::instance()->receive(function($file,$formFieldName){
if(Web::instance()->mime($file['tmp_name'], true) != 'application/pdf') {
return false;
}
if($file['size'] > (20 * 1024 * 1024)) { // if bigger than 20 MB
return false;
}
return true;
}, true);
$key = null;
foreach($files as $file => $valid) {
if(!$valid) {
continue;
}
$key = md5_file($file);
rename($file, $f3->get('UPLOADS').'/'.$key.'.pdf');
}
if(!$key) {
$f3->error(403);
}
return $f3->reroute('/'.$key);
}
);
$f3->route('GET /@key',
function($f3) {
$f3->set('key', $f3->get('PARAMS.key'));
echo View::instance()->render('pdf.html.php');
}
);
$f3->route('POST /@key/save',
function($f3) {
$key = $f3->get('PARAMS.key');
$svgData = $_POST['svg'];
file_put_contents($f3->get('UPLOADS').'/'.$key.'.svg', $svgData);
shell_exec(sprintf("rsvg-convert -f pdf -o %s %s", $f3->get('UPLOADS').'/'.$key.'.svg.pdf', $f3->get('UPLOADS').'/'.$key.'.svg'));
shell_exec(sprintf("pdftk %s background %s output %s", $f3->get('UPLOADS').'/'.$key.'.svg.pdf', $f3->get('UPLOADS').'/'.$key.'.pdf', $f3->get('UPLOADS').'/'.$key.'_signe.pdf'));
Web::instance()->send($f3->get('UPLOADS').'/'.$key.'_signe.pdf');
}
);
$f3->run();

68
js/app.js Normal file
View file

@ -0,0 +1,68 @@
// Loaded via <script> tag, create shortcut to access PDF.js exports.
var pdfjsLib = window['pdfjs-dist/build/pdf'];
// The workerSrc property shall be specified.
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://mozilla.github.io/pdf.js/build/pdf.worker.js';
// Asynchronous download of PDF
var loadingTask = pdfjsLib.getDocument(url);
loadingTask.promise.then(function(pdf) {
console.log('PDF loaded');
var canvasEdition = null;
// Fetch the first page
var pageNumber = 1;
pdf.getPage(pageNumber).then(function(page) {
console.log('Page loaded');
var signaturePad = new SignaturePad(document.getElementById('signature-pad'), {
backgroundColor: 'rgba(255, 255, 255, 0)',
penColor: 'rgb(0, 0, 0)',
minWidth: 0.75,
maxWidth: 1.1
});
var scale = 1.0;
var viewport = page.getViewport({scale: scale});
var canvasPDF = document.getElementById('canvas-pdf');
var canvasEditionHTML = document.getElementById('canvas-edition');
// Prepare canvas using PDF page dimensions
var context = canvasPDF.getContext('2d');
canvasPDF.height = viewport.height;
canvasPDF.width = viewport.width;
canvasEditionHTML.height = viewport.height;
canvasEditionHTML.width = viewport.width;
canvasEdition = new fabric.Canvas('canvas-edition');
canvasEdition.on('mouse:dblclick', function(event) {
x = event.pointer.x
y = event.pointer.y
fabric.loadSVGFromURL(signaturePad.toDataURL("image/svg+xml"), function(objects, options) {
options.left = x
options.top = y
var obj = fabric.util.groupSVGElements(objects, options);
canvasEdition.add(obj).renderAll();
});
});
document.getElementById('save').addEventListener('click', function(event) {
document.getElementById('data-svg').value = canvasEdition.toSVG();
});
var renderContext = {
canvasContext: context,
viewport: viewport
};
var renderTask = page.render(renderContext);
renderTask.promise.then(function () {
console.log('Page rendered');
});
});
}, function (reason) {
console.error(reason);
});

45
pdf.html.php Normal file
View file

@ -0,0 +1,45 @@
<!doctype html>
<html lang="fr_FR">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.4.1/font/bootstrap-icons.css">
<title>Signature PDF</title>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-lg-10 col-md-9 col-sm-8 col-xs-6 bg-light">
<div class="position-relative mt-2 mb-2">
<canvas id="canvas-pdf" class="position-absolute top-0 start-0 shadow"></canvas>
<canvas id="canvas-edition" class="position-absolute top-0 start-0"></canvas>
</div>
</div>
<aside class="col-lg-2 col-md-3 col-sm-4 col-xs-6 mt-2 position-fixed end-0 bg-white">
<h4><i class="bi bi-vector-pen"></i> Signature</h4>
<canvas id="signature-pad" class="border bg-light" width=200 height=150></canvas>
<p><small class="text-muted">Double-cliquez sur le PDF pour ajouter la signature</small></p>
<form action="/<?php echo $key ?>/save" method="post">
<input name="svg" id="data-svg" type="hidden" value="" />
<div class="position-fixed bottom-0 mb-2">
<button class="btn btn-primary" type="submit" id="save"><i class="bi bi-download"></i> Télécharger le PDF</button>
</div>
</form>
</aside>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js" integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf" crossorigin="anonymous"></script>
<script src="https://mozilla.github.io/pdf.js/build/pdf.js"></script>
<script src="https://cdn.jsdelivr.net/npm/fabric@4.4.0/dist/fabric.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/signature_pad@3.0.0-beta.3/dist/signature_pad.umd.min.js"></script>
<script>
var url = '/data/<?php echo $key ?>.pdf';
</script>
<script src="/js/app.js"></script>
</body>
</html>