stat2025 commited on
Commit
3f04682
·
verified ·
1 Parent(s): ba467f0

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +22 -39
index.html CHANGED
@@ -2,7 +2,7 @@
2
  <html lang="ar" dir="rtl">
3
  <head>
4
  <meta charset="UTF-8" />
5
- <title>أداة دمج ملفات المجموعة | PDF واحد بسهولة</title>
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
  <link rel="stylesheet" href="style.css" />
8
  <script src="https://unpkg.com/pdf-lib@1.17.1/dist/pdf-lib.min.js"></script>
@@ -10,33 +10,25 @@
10
  <body>
11
  <div class="page">
12
 
13
- <!-- الهيدر العلوي -->
14
  <header class="topbar">
15
- <div class="top-left">
16
- <div class="logo-mark">PDF</div>
17
- <div class="brand-text">
18
- <div class="brand-title">أداة دمج ملفات المجموعة</div>
19
- <div class="brand-sub">دمج احترافي لصور وملفات PDF في ملف واحد بحجم A4</div>
20
- </div>
21
- </div>
22
- <div class="top-right">
23
- <span class="credit">تصميم وإعداد الدعم الفني: نوف الناصر</span>
24
- </div>
25
  </header>
26
 
27
  <!-- المحتوى الرئيسي -->
28
  <main class="main">
29
 
30
- <!-- تعريف بسيط -->
31
  <section class="hero">
 
32
  <h1>ادمج ملفاتك بسهولة في ملف PDF واحد بحجم A4.</h1>
33
  <p>
34
- يمكنك اختيار صور، ملفات PDF، أو مزيج منهما، وسيتم دمجها في ملف PDF واحد،
35
- مع الحفاظ على كامل محتوى الصفحات والصور، وتنسيقها في صفحات A4 دون قص.
36
  </p>
37
  </section>
38
 
39
- <!-- خطوات مختصرة -->
40
  <section class="steps">
41
  <div class="step">
42
  <span class="step-number">1</span>
@@ -44,11 +36,11 @@
44
  </div>
45
  <div class="step">
46
  <span class="step-number">2</span>
47
- <span class="step-text">أعد ترتيب الملفات، احذف ما لا تحتاجه قبل الدمج.</span>
48
  </div>
49
  <div class="step">
50
  <span class="step-number">3</span>
51
- <span class="step-text">اضغط دمج وشاهد نسبة التقدم حتى يكتمل ملف PDF.</span>
52
  </div>
53
  </section>
54
 
@@ -57,14 +49,14 @@
57
 
58
  <!-- اختيار الملفات -->
59
  <div class="card-row">
60
- <h2 class="card-title">اختيار الملفات</h2>
61
  <p class="hint">
62
  يدعم:
63
  <strong>ملفات PDF</strong>،
64
  <strong>صور JPG / PNG</strong>،
65
  أو
66
- <strong>دمج الاثنين معًا</strong> في ملف PDF واحد.
67
- يتم الدمج وفق الترتيب الظاهر في القائمة أدناه، مع وضع الصور في صفحات A4 كاملة دون قص.
68
  </p>
69
 
70
  <label class="file-picker">
@@ -138,7 +130,7 @@
138
  }
139
  }
140
 
141
- function setProgress(current, total, label = "جاري المعالجة") {
142
  if (!total || total < 1) total = 1;
143
  const percent = Math.floor((current / total) * 100);
144
  progressFill.style.width = percent + "%";
@@ -184,7 +176,7 @@
184
  const { hasImages, hasPDFs } = getFilesInfo(files);
185
  let modeText = "";
186
  if (hasImages && hasPDFs) {
187
- modeText = "الوضع الحالي: دمج صور + ملفات PDF في ملف واحد بحجم A4 لكل صفحة.";
188
  } else if (hasPDFs) {
189
  modeText = "الوضع الحالي: دمج ملفات PDF في ملف واحد (بدون تغيير محتوى الصفحات).";
190
  } else if (hasImages) {
@@ -218,7 +210,6 @@
218
  </ul>
219
  `;
220
 
221
- // تحذير عدد كبير
222
  if (files.length > MAX_RECOMMENDED_FILES) {
223
  setStatus(
224
  "تنبيه: عدد الملفات كبير، قد تستغرق عملية الدمج وقتًا أطول على بعض الأجهزة.",
@@ -226,7 +217,7 @@
226
  );
227
  }
228
 
229
- // أزرار الحذف
230
  fileListDiv.querySelectorAll(".delete-btn").forEach((btn) => {
231
  btn.addEventListener("click", (e) => {
232
  const index = parseInt(e.currentTarget.dataset.index, 10);
@@ -241,7 +232,7 @@
241
  });
242
  });
243
 
244
- // أزرار إعادة الترتيب
245
  fileListDiv.querySelectorAll(".move-btn").forEach((btn) => {
246
  btn.addEventListener("click", (e) => {
247
  const index = parseInt(e.currentTarget.dataset.index, 10);
@@ -249,13 +240,9 @@
249
  if (isNaN(index)) return;
250
 
251
  if (dir === "up" && index > 0) {
252
- const tmp = selectedFiles[index - 1];
253
- selectedFiles[index - 1] = selectedFiles[index];
254
- selectedFiles[index] = tmp;
255
  } else if (dir === "down" && index < selectedFiles.length - 1) {
256
- const tmp = selectedFiles[index + 1];
257
- selectedFiles[index + 1] = selectedFiles[index];
258
- selectedFiles[index] = tmp;
259
  }
260
  renderFileList(selectedFiles);
261
  });
@@ -279,10 +266,9 @@
279
  const newFilesRaw = Array.from(filesInput.files || []);
280
  if (!newFilesRaw.length) return;
281
 
282
- // نسمح فقط بالصور و PDF
283
  const newFiles = newFilesRaw.filter((f) => isImage(f) || isPDF(f));
284
-
285
  const map = new Map();
 
286
  [...selectedFiles, ...newFiles].forEach((f) => {
287
  const key = `${f.name}|${f.size}|${f.lastModified}`;
288
  if (!map.has(key)) map.set(key, f);
@@ -291,7 +277,6 @@
291
  selectedFiles = Array.from(map.values());
292
  renderFileList(selectedFiles);
293
  setStatus("");
294
-
295
  filesInput.value = "";
296
  });
297
 
@@ -305,7 +290,7 @@
305
  showProgress(false);
306
  });
307
 
308
- // عملية الدمج مع شريط التقدم
309
  mergeBtn.addEventListener("click", async () => {
310
  const files = [...selectedFiles];
311
 
@@ -314,7 +299,6 @@
314
  return;
315
  }
316
 
317
- // التحقق من الملفات المدعومة
318
  const unsupported = files.filter((f) => !isImage(f) && !isPDF(f));
319
  if (unsupported.length) {
320
  setStatus("يوجد ملفات غير مدعومة. يرجى حذفها من القائمة.", "error");
@@ -370,7 +354,6 @@
370
  const imgWidth = image.width;
371
  const imgHeight = image.height;
372
 
373
- // تصغير ملائم: إدراج الصورة كاملة داخل A4 دون قص
374
  const scale = Math.min(pageWidth / imgWidth, pageHeight / imgHeight);
375
  const drawWidth = imgWidth * scale;
376
  const drawHeight = imgHeight * scale;
@@ -382,7 +365,7 @@
382
  }
383
 
384
  currentStep += 1;
385
- setProgress(currentStep, totalSteps, "معالجة الملفات");
386
  }
387
 
388
  const pdfBytes = await pdfDoc.save();
 
2
  <html lang="ar" dir="rtl">
3
  <head>
4
  <meta charset="UTF-8" />
5
+ <title>دمج ملفات PDF وصور بحجم A4 | أداة المجموعة</title>
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
  <link rel="stylesheet" href="style.css" />
8
  <script src="https://unpkg.com/pdf-lib@1.17.1/dist/pdf-lib.min.js"></script>
 
10
  <body>
11
  <div class="page">
12
 
13
+ <!-- الهيدر العلوي: اعتماد فقط -->
14
  <header class="topbar">
15
+ <span class="credit">تصميم وإعداد الدعم الفني: نوف الناصر</span>
 
 
 
 
 
 
 
 
 
16
  </header>
17
 
18
  <!-- المحتوى الرئيسي -->
19
  <main class="main">
20
 
21
+ <!-- هيرو -->
22
  <section class="hero">
23
+ <div class="logo-mark">PDF</div>
24
  <h1>ادمج ملفاتك بسهولة في ملف PDF واحد بحجم A4.</h1>
25
  <p>
26
+ حمّل صورك وملفات الـ PDF، رتّبها كما تشاء، واحصل على ملف PDF واحد منسّق،
27
+ مع الحفاظ على كامل المحتوى، ووضع الصور في صفحات A4 كاملة دون قص.
28
  </p>
29
  </section>
30
 
31
+ <!-- خطوات -->
32
  <section class="steps">
33
  <div class="step">
34
  <span class="step-number">1</span>
 
36
  </div>
37
  <div class="step">
38
  <span class="step-number">2</span>
39
+ <span class="step-text">رتّب الملفات، واحذف أي ملف لا ترغب بوجوده.</span>
40
  </div>
41
  <div class="step">
42
  <span class="step-number">3</span>
43
+ <span class="step-text">اضغط دمج وتابع شريط التقدم حتى يتم إنشاء ملف PDF.</span>
44
  </div>
45
  </section>
46
 
 
49
 
50
  <!-- اختيار الملفات -->
51
  <div class="card-row">
52
+ <h2 class="card-title">اختر الملفات المراد دمجها</h2>
53
  <p class="hint">
54
  يدعم:
55
  <strong>ملفات PDF</strong>،
56
  <strong>صور JPG / PNG</strong>،
57
  أو
58
+ <strong>الدمج بينهما</strong> في ملف واحد.
59
+ يتم الدمج وفق الترتيب الظاهر في القائمة، مع استخدام صفحات A4 ثابتة.
60
  </p>
61
 
62
  <label class="file-picker">
 
130
  }
131
  }
132
 
133
+ function setProgress(current, total, label = "معالجة الملفات") {
134
  if (!total || total < 1) total = 1;
135
  const percent = Math.floor((current / total) * 100);
136
  progressFill.style.width = percent + "%";
 
176
  const { hasImages, hasPDFs } = getFilesInfo(files);
177
  let modeText = "";
178
  if (hasImages && hasPDFs) {
179
+ modeText = "الوضع الحالي: دمج صور + ملفات PDF في ملف واحد، مع صفحات A4 ثابتة.";
180
  } else if (hasPDFs) {
181
  modeText = "الوضع الحالي: دمج ملفات PDF في ملف واحد (بدون تغيير محتوى الصفحات).";
182
  } else if (hasImages) {
 
210
  </ul>
211
  `;
212
 
 
213
  if (files.length > MAX_RECOMMENDED_FILES) {
214
  setStatus(
215
  "تنبيه: عدد الملفات كبير، قد تستغرق عملية الدمج وقتًا أطول على بعض الأجهزة.",
 
217
  );
218
  }
219
 
220
+ // حذف ملف
221
  fileListDiv.querySelectorAll(".delete-btn").forEach((btn) => {
222
  btn.addEventListener("click", (e) => {
223
  const index = parseInt(e.currentTarget.dataset.index, 10);
 
232
  });
233
  });
234
 
235
+ // إعادة الترتيب
236
  fileListDiv.querySelectorAll(".move-btn").forEach((btn) => {
237
  btn.addEventListener("click", (e) => {
238
  const index = parseInt(e.currentTarget.dataset.index, 10);
 
240
  if (isNaN(index)) return;
241
 
242
  if (dir === "up" && index > 0) {
243
+ [selectedFiles[index - 1], selectedFiles[index]] = [selectedFiles[index], selectedFiles[index - 1]];
 
 
244
  } else if (dir === "down" && index < selectedFiles.length - 1) {
245
+ [selectedFiles[index + 1], selectedFiles[index]] = [selectedFiles[index], selectedFiles[index + 1]];
 
 
246
  }
247
  renderFileList(selectedFiles);
248
  });
 
266
  const newFilesRaw = Array.from(filesInput.files || []);
267
  if (!newFilesRaw.length) return;
268
 
 
269
  const newFiles = newFilesRaw.filter((f) => isImage(f) || isPDF(f));
 
270
  const map = new Map();
271
+
272
  [...selectedFiles, ...newFiles].forEach((f) => {
273
  const key = `${f.name}|${f.size}|${f.lastModified}`;
274
  if (!map.has(key)) map.set(key, f);
 
277
  selectedFiles = Array.from(map.values());
278
  renderFileList(selectedFiles);
279
  setStatus("");
 
280
  filesInput.value = "";
281
  });
282
 
 
290
  showProgress(false);
291
  });
292
 
293
+ // الدمج مع A4 + شريط تقدم
294
  mergeBtn.addEventListener("click", async () => {
295
  const files = [...selectedFiles];
296
 
 
299
  return;
300
  }
301
 
 
302
  const unsupported = files.filter((f) => !isImage(f) && !isPDF(f));
303
  if (unsupported.length) {
304
  setStatus("يوجد ملفات غير مدعومة. يرجى حذفها من القائمة.", "error");
 
354
  const imgWidth = image.width;
355
  const imgHeight = image.height;
356
 
 
357
  const scale = Math.min(pageWidth / imgWidth, pageHeight / imgHeight);
358
  const drawWidth = imgWidth * scale;
359
  const drawHeight = imgHeight * scale;
 
365
  }
366
 
367
  currentStep += 1;
368
+ setProgress(currentStep, totalSteps);
369
  }
370
 
371
  const pdfBytes = await pdfDoc.save();