TheFrenchDemos commited on
Commit
4c38f62
·
verified ·
1 Parent(s): 651b66f

deux icônes et pdf

Browse files
Files changed (1) hide show
  1. templates/index.html +46 -61
templates/index.html CHANGED
@@ -16,25 +16,21 @@
16
  --apple-border: #d1d1d6;
17
  --apple-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
18
  }
19
-
20
  body {
21
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
22
  background: var(--apple-gray);
23
  color: #1c1c1e;
24
  }
25
-
26
  h1,
27
  h2,
28
  h5 {
29
  font-weight: 600;
30
  }
31
-
32
  /* thumbnails */
33
  .preset-image-container {
34
  overflow: hidden;
35
  margin-bottom: 12px;
36
  }
37
-
38
  .preset-image {
39
  width: 100%;
40
  border-radius: 12px;
@@ -43,15 +39,12 @@
43
  transition: transform 0.3s ease, border-color 0.3s ease;
44
  cursor: pointer;
45
  }
46
-
47
  .preset-image:hover {
48
  transform: scale(1.05);
49
  }
50
-
51
  .preset-image.selected {
52
  border-color: var(--apple-blue);
53
  }
54
-
55
  /* dropzone */
56
  .dropzone {
57
  border: 2px dashed var(--apple-border);
@@ -61,7 +54,6 @@
61
  text-align: center;
62
  box-shadow: var(--apple-shadow);
63
  }
64
-
65
  /* preview */
66
  .preview-image {
67
  max-width: 220px;
@@ -70,22 +62,18 @@
70
  opacity: 0;
71
  transition: opacity 0.4s ease;
72
  }
73
-
74
  .preview-image.visible {
75
  opacity: 1;
76
  }
77
-
78
  /* buttons */
79
  .btn-primary {
80
  background: var(--apple-blue);
81
  border: none;
82
  font-weight: 500;
83
  }
84
-
85
  .btn-primary:hover {
86
  background: #005ecb;
87
  }
88
-
89
  /* gauge */
90
  .jauge-container {
91
  display: none;
@@ -93,7 +81,6 @@
93
  gap: 24px;
94
  margin-top: 24px;
95
  }
96
-
97
  .jauge {
98
  width: 24px;
99
  height: 160px;
@@ -103,7 +90,6 @@
103
  overflow: hidden;
104
  border: 1px solid var(--apple-border);
105
  }
106
-
107
  .jauge-level {
108
  position: absolute;
109
  bottom: 0;
@@ -112,7 +98,6 @@
112
  background: var(--apple-blue);
113
  transition: height 0.6s ease, background 0.3s ease;
114
  }
115
-
116
  .jauge-labels {
117
  font-size: 0.7rem;
118
  color: #636366;
@@ -121,7 +106,6 @@
121
  justify-content: space-between;
122
  height: 160px;
123
  }
124
-
125
  /* icon column */
126
  .icon-buttons {
127
  display: none;
@@ -131,7 +115,6 @@
131
  align-items: center;
132
  margin-left: 12px;
133
  }
134
-
135
  .icon-buttons button {
136
  background: none;
137
  border: none;
@@ -139,7 +122,6 @@
139
  font-size: 24px;
140
  cursor: pointer;
141
  }
142
-
143
  /* section hidden until first preview shown */
144
  #compareSection {
145
  margin-top: 40px;
@@ -202,9 +184,16 @@
202
  <span>most certainly</span><span>very probably</span><span>probably</span><span>possibly</span><span>probably not</span><span>definitely not</span>
203
  </div>
204
  </div>
 
205
  <div class="icon-buttons" id="iconButtons">
206
- <button title="Print" onclick="generatePDF()"><i class="fas fa-print"></i></button>
207
- <button title="Certificate"><i class="fa-solid fa-file-certificate"></i></button>
 
 
 
 
 
 
208
  </div>
209
  </div>
210
  </div>
@@ -218,14 +207,12 @@
218
  <script>
219
  let file1 = null,
220
  file2 = null;
221
-
222
  function resetSelection(target) {
223
  for (let i = 1; i <= 3; i++) {
224
  const thumb = document.getElementById(`preset-${i}-${target}`);
225
  if (thumb) thumb.classList.remove("selected");
226
  }
227
  }
228
-
229
  function selectPreset(n, target) {
230
  const imgEl = document.getElementById(`preset-${n}-${target}`);
231
  const src = imgEl.src;
@@ -244,7 +231,6 @@
244
  checkReady();
245
  });
246
  }
247
-
248
  function updatePreview(fileOrBlob, target) {
249
  const reader = new FileReader();
250
  reader.onload = (e) => {
@@ -255,7 +241,6 @@
255
  };
256
  reader.readAsDataURL(fileOrBlob);
257
  }
258
-
259
  document.getElementById("fileInput1").addEventListener("change", (e) => {
260
  if (e.target.files.length) {
261
  file1 = e.target.files[0];
@@ -272,7 +257,6 @@
272
  checkReady();
273
  }
274
  });
275
-
276
  function checkReady() {
277
  const container = document.getElementById("compareButtonContainer");
278
  if (file1 && file2) {
@@ -282,7 +266,6 @@
282
  container.innerHTML = "";
283
  }
284
  }
285
-
286
  async function processImages() {
287
  const fd = new FormData();
288
  fd.append("image1", file1);
@@ -313,41 +296,43 @@
313
  resDiv.innerHTML = '<div class="text-danger">Error processing images.</div>';
314
  }
315
  }
316
-
317
- async function generatePDF() {
318
- const { jsPDF } = window.jspdf;
319
- const pdf = new jsPDF({ orientation: "portrait", unit: "pt", format: "a4" });
320
-
321
- // capture the score block including gauge & icons (icons will be hidden by CSS print media maybe, but fine)
322
- const target = document.querySelector("#compareSection .d-flex");
323
- const canvas = await html2canvas(target, { backgroundColor: null });
324
- const imgData = canvas.toDataURL("image/png");
325
- const pageWidth = pdf.internal.pageSize.getWidth();
326
- const margin = 40;
327
- const availableWidth = pageWidth - margin * 2;
328
-
329
- // header
330
- pdf.setFont("helvetica", "normal");
331
- pdf.setFontSize(24);
332
- pdf.text("Fraud Score", pageWidth / 2, 50, { align: "center" });
333
- pdf.setFontSize(12);
334
- pdf.text("Is my work used by generative AI ?", pageWidth / 2, 70, { align: "center" });
335
-
336
- // image
337
- const imgProps = pdf.getImageProperties(imgData);
338
- const imgHeight = (imgProps.height * availableWidth) / imgProps.width;
339
- pdf.addImage(imgData, "PNG", margin, 100, availableWidth, imgHeight);
340
-
341
- // footer
342
- const yFooterStart = 110 + imgHeight;
343
- pdf.setFontSize(10);
344
- const now = new Date();
345
- pdf.text(`Generated on: ${now.toLocaleString()}`, margin, yFooterStart);
346
- pdf.text(`Calculated by: ${window.location.href}`, margin, yFooterStart + 14);
347
-
348
- const blobUrl = pdf.output("bloburl");
349
- window.open(blobUrl, "_blank");
350
- }
 
 
351
  </script>
352
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
353
  </body>
 
16
  --apple-border: #d1d1d6;
17
  --apple-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
18
  }
 
19
  body {
20
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
21
  background: var(--apple-gray);
22
  color: #1c1c1e;
23
  }
 
24
  h1,
25
  h2,
26
  h5 {
27
  font-weight: 600;
28
  }
 
29
  /* thumbnails */
30
  .preset-image-container {
31
  overflow: hidden;
32
  margin-bottom: 12px;
33
  }
 
34
  .preset-image {
35
  width: 100%;
36
  border-radius: 12px;
 
39
  transition: transform 0.3s ease, border-color 0.3s ease;
40
  cursor: pointer;
41
  }
 
42
  .preset-image:hover {
43
  transform: scale(1.05);
44
  }
 
45
  .preset-image.selected {
46
  border-color: var(--apple-blue);
47
  }
 
48
  /* dropzone */
49
  .dropzone {
50
  border: 2px dashed var(--apple-border);
 
54
  text-align: center;
55
  box-shadow: var(--apple-shadow);
56
  }
 
57
  /* preview */
58
  .preview-image {
59
  max-width: 220px;
 
62
  opacity: 0;
63
  transition: opacity 0.4s ease;
64
  }
 
65
  .preview-image.visible {
66
  opacity: 1;
67
  }
 
68
  /* buttons */
69
  .btn-primary {
70
  background: var(--apple-blue);
71
  border: none;
72
  font-weight: 500;
73
  }
 
74
  .btn-primary:hover {
75
  background: #005ecb;
76
  }
 
77
  /* gauge */
78
  .jauge-container {
79
  display: none;
 
81
  gap: 24px;
82
  margin-top: 24px;
83
  }
 
84
  .jauge {
85
  width: 24px;
86
  height: 160px;
 
90
  overflow: hidden;
91
  border: 1px solid var(--apple-border);
92
  }
 
93
  .jauge-level {
94
  position: absolute;
95
  bottom: 0;
 
98
  background: var(--apple-blue);
99
  transition: height 0.6s ease, background 0.3s ease;
100
  }
 
101
  .jauge-labels {
102
  font-size: 0.7rem;
103
  color: #636366;
 
106
  justify-content: space-between;
107
  height: 160px;
108
  }
 
109
  /* icon column */
110
  .icon-buttons {
111
  display: none;
 
115
  align-items: center;
116
  margin-left: 12px;
117
  }
 
118
  .icon-buttons button {
119
  background: none;
120
  border: none;
 
122
  font-size: 24px;
123
  cursor: pointer;
124
  }
 
125
  /* section hidden until first preview shown */
126
  #compareSection {
127
  margin-top: 40px;
 
184
  <span>most certainly</span><span>very probably</span><span>probably</span><span>possibly</span><span>probably not</span><span>definitely not</span>
185
  </div>
186
  </div>
187
+ <!-- boutons de PDF -->
188
  <div class="icon-buttons" id="iconButtons">
189
+ <button title="Print" onclick="generatePDF1()"><i class="fas fa-print"></i></button>
190
+ <button
191
+ title="Certificate"
192
+ aria-label="Certificate PDF"
193
+ onclick="generatePDF2()">
194
+ <i class="fas fa-certificate" aria-hidden="true"></i>
195
+ </button>
196
+
197
  </div>
198
  </div>
199
  </div>
 
207
  <script>
208
  let file1 = null,
209
  file2 = null;
 
210
  function resetSelection(target) {
211
  for (let i = 1; i <= 3; i++) {
212
  const thumb = document.getElementById(`preset-${i}-${target}`);
213
  if (thumb) thumb.classList.remove("selected");
214
  }
215
  }
 
216
  function selectPreset(n, target) {
217
  const imgEl = document.getElementById(`preset-${n}-${target}`);
218
  const src = imgEl.src;
 
231
  checkReady();
232
  });
233
  }
 
234
  function updatePreview(fileOrBlob, target) {
235
  const reader = new FileReader();
236
  reader.onload = (e) => {
 
241
  };
242
  reader.readAsDataURL(fileOrBlob);
243
  }
 
244
  document.getElementById("fileInput1").addEventListener("change", (e) => {
245
  if (e.target.files.length) {
246
  file1 = e.target.files[0];
 
257
  checkReady();
258
  }
259
  });
 
260
  function checkReady() {
261
  const container = document.getElementById("compareButtonContainer");
262
  if (file1 && file2) {
 
266
  container.innerHTML = "";
267
  }
268
  }
 
269
  async function processImages() {
270
  const fd = new FormData();
271
  fd.append("image1", file1);
 
296
  resDiv.innerHTML = '<div class="text-danger">Error processing images.</div>';
297
  }
298
  }
299
+ async function generatePDF1(){const {jsPDF}=window.jspdf;const pdf=new jsPDF({orientation:'portrait',unit:'pt',format:'a4'});
300
+ const pageW=pdf.internal.pageSize.getWidth();const margin=40;const usableW=pageW-margin*2;let y=100;
301
+ pdf.setFont('helvetica','normal');pdf.setFontSize(24);pdf.text('Fraud Score',pageW/2,y,{align:'center'});
302
+ y+=20;pdf.setFontSize(12);pdf.text('Is my work used by generative AI ?',pageW/2,y,{align:'center'});
303
+ y+=100; // six blank lines
304
+ const section=document.querySelector('#compareSection .d-flex');const clone=section.cloneNode(true);
305
+ clone.querySelectorAll('button').forEach(b=>b.style.display='none'); // hide calculate/print
306
+ document.body.appendChild(clone);clone.style.position='absolute';clone.style.left='-9999px';
307
+ const canvas=await html2canvas(clone,{backgroundColor:null});document.body.removeChild(clone);
308
+ const imgData=canvas.toDataURL('image/png');const props=pdf.getImageProperties(imgData);const imgH=(props.height*usableW)/props.width;
309
+ pdf.addImage(imgData,'PNG',margin,y,usableW,imgH);
310
+ y+=imgH+100; // six blank lines before footer
311
+ pdf.setFontSize(10);
312
+ const now=new Date();pdf.text(`Calculated on: ${now.toLocaleString()}`,margin,y);
313
+ const urlText=`by: ${window.location.href}`;
314
+ const wrapped=pdf.splitTextToSize(urlText,usableW);
315
+ pdf.text(wrapped,margin,y+28);
316
+ window.open(pdf.output('bloburl'),'_blank');}
317
+ async function generatePDF2(){const {jsPDF}=window.jspdf;const pdf=new jsPDF({orientation:'portrait',unit:'pt',format:'a4'});
318
+ const pageW=pdf.internal.pageSize.getWidth();const margin=40;const usableW=pageW-margin*2;let y=100;
319
+ pdf.setFont('helvetica','normal');pdf.setFontSize(24);pdf.text('Fraud Score',pageW/2,y,{align:'center'});
320
+ y+=20;pdf.setFontSize(12);pdf.text('Is my work used by generative AI ?',pageW/2,y,{align:'center'});
321
+ y+=100; // six blank lines
322
+ const section=document.querySelector('#compareSection .d-flex');const clone=section.cloneNode(true);
323
+ clone.querySelectorAll('button').forEach(b=>b.style.display='none'); // hide calculate/print
324
+ document.body.appendChild(clone);clone.style.position='absolute';clone.style.left='-9999px';
325
+ const canvas=await html2canvas(clone,{backgroundColor:null});document.body.removeChild(clone);
326
+ const imgData=canvas.toDataURL('image/png');const props=pdf.getImageProperties(imgData);const imgH=(props.height*usableW)/props.width;
327
+ pdf.addImage(imgData,'PNG',margin,y,usableW,imgH);
328
+ y+=imgH+100; // six blank lines before footer
329
+ pdf.setFontSize(10);
330
+ const now=new Date();pdf.text(`Calculated on: ${now.toLocaleString()}`,margin,y);
331
+ const urlText=`by: ${window.location.href}`;
332
+ const wrapped=pdf.splitTextToSize(urlText,usableW);
333
+ pdf.text(wrapped,margin,y+28);
334
+ window.open(pdf.output('bloburl'),'_blank');}
335
+
336
  </script>
337
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
338
  </body>