پی ڈی ایف دستاویزات عام طور پر معاہدوں، فارموں، منظوریوں، رسیدوں، رپورٹس، درخواستوں اور دیگر دستاویزات کے لیے استعمال ہوتی ہیں جن کو شیئر کرنے سے پہلے دستخط یا اضافی متن کی ضرورت پڑ سکتی ہے۔
روایتی ورک فلو میں اکثر کسی دستاویز کو پرنٹ کرنا، ذاتی طور پر اس پر دستخط کرنا، اسے دوبارہ اسکین کرنا اور نئی فائل بھیجنا شامل ہوتا ہے۔ سادہ الیکٹرانک دستخط اس عمل میں غیر ضروری اقدامات کا اضافہ کرتے ہیں۔
اس ٹیوٹوریل میں، آپ جاوا اسکرپٹ کا استعمال کرتے ہوئے براؤزر پر مبنی پی ڈی ایف سائننگ ٹول بنائیں گے۔ صارفین پی ڈی ایف اپ لوڈ کر سکتے ہیں، اس کے صفحات کا جائزہ لے سکتے ہیں اور نیویگیٹ کر سکتے ہیں، اور مواد کو براہ راست دستاویز میں شامل کر سکتے ہیں۔
ایپلی کیشن دو اہم عناصر کی اقسام کو سپورٹ کرتی ہے: دستخط اور ٹیکسٹ/سٹیمپ.
دستخطوں کے لیے، صارف براہ راست براؤزر میں ڈرا کر سکتے ہیں، نام درج کر سکتے ہیں، دستخطی انداز کا انتخاب کر سکتے ہیں، یا موجودہ دستخط کی تصویر اپ لوڈ کر سکتے ہیں۔ متن پر مبنی عناصر کے لیے، آپ حسب ضرورت متن درج کر سکتے ہیں یا پیش سیٹ سٹیمپ استعمال کر سکتے ہیں، جیسے: منظور شدہ, خفیہ, مسودہاور ادا کیا.
عنصر بنانے کے بعد، صارف اسے پی ڈی ایف پیش نظارہ میں رکھ سکتے ہیں اور اسکیل، گردش، دھندلاپن، فونٹ سائز اور رنگ جیسی خصوصیات کو ایڈجسٹ کرسکتے ہیں۔ پھر آپ عنصر کو موجودہ صفحہ، تمام صفحات، یا صفحات کے مخصوص سیٹ پر لاگو کر سکتے ہیں۔
پروسیسنگ مکمل ہونے کے بعد، ایپلیکیشن آپ کے جائزے کے لیے ایک نیا پی ڈی ایف تیار کرے گی۔ صارفین نتائج کا جائزہ لے سکتے ہیں، آؤٹ پٹ فائل کا نام تبدیل کر سکتے ہیں، صفحہ کی گنتی اور فائل کا سائز چیک کر سکتے ہیں، اور براہ راست براؤزر سے ڈاؤن لوڈ کر سکتے ہیں۔
یہ پراجیکٹ PDF.js کو دستاویز کی ترتیب کے لیے اور PDF-lib کو حتمی پی ڈی ایف میں ترمیم اور تخلیق کرنے کے لیے استعمال کرتا ہے۔
اس ٹیوٹوریل کے اختتام تک، آپ سمجھ جائیں گے کہ ایک انٹرایکٹو پی ڈی ایف ایڈیٹنگ ورک فلو کیسے بنایا جائے جو کینوس پر مبنی ان پٹ، امیج ایمبیڈنگ، ٹیکسٹ ریپنگ، کوآرڈینیٹ ٹرانسفارمیشن، پیج سلیکشن، اور کلائنٹ سائڈ فائل تخلیق کو یکجا کرے۔
ہم کیا احاطہ کریں گے:
یہ ایپلیکیشن PDF صفحات میں دستخط، متن، اور عام دستاویز کے ڈاک ٹکٹوں کو شامل کرنے کے لیے ایک واحد ترمیمی ورک فلو فراہم کرتی ہے۔
جب دستخط ایک بار منتخب ہونے کے بعد، صارف اپنے دستخط تین طریقوں سے بنا سکتے ہیں:
-
کہ ڈرا یہ اختیار ایک کینوس فراہم کرتا ہے جس پر صارف ماؤس، ٹریک پیڈ، اسٹائلس، یا ٹچ ان پٹ کا استعمال کرکے اپنے دستخط بناسکتے ہیں۔
-
کہ زمرہ آپشن آپ کے داخل کردہ متن کو دستخطی طرز کے عناصر میں بدل دیتا ہے۔ صارف نام درج کر سکتے ہیں، اس کا سائز تبدیل کر سکتے ہیں، اور دستیاب دستخطی طرزوں میں سے انتخاب کر سکتے ہیں۔
-
کہ اپ لوڈ کریں آپشن ایک موجودہ دستخطی تصویر کو قبول کرتا ہے۔ یہ ان لوگوں کے لیے مفید ہے جن کے پاس پہلے سے ہی اپنے ہاتھ سے لکھے ہوئے دستخط کی شفاف PNG یا دیگر معاون تصویر ہے۔
عنصر کی دوسری قسم ہے: ٹیکسٹ/سٹیمپ. صارف حسب ضرورت متن درج کر سکتے ہیں، جیسے:
Signed on: 08-09-2025
آپ جلدی سے پہلے سے طے شدہ ڈاک ٹکٹ بھی منتخب کر سکتے ہیں۔
APPROVED
CONFIDENTIAL
DRAFT
PAID
ایک عنصر بننے کے بعد، ایپلی کیشن اس کی جگہ اور ظاہری شکل پر کنٹرول فراہم کرتی ہے۔ صارف اسے مطلوبہ مقام پر منتقل کر سکتے ہیں اور اس کے سائز، گردش، دھندلاپن اور پوزیشن کو ایڈجسٹ کر سکتے ہیں۔
ٹیکسٹ اور سٹیمپ عناصر اضافی طور پر قابل ترتیب فونٹ سائز اور رنگ استعمال کر سکتے ہیں۔
صفحہ کے کنٹرول اس بات کا تعین کرتے ہیں کہ منتخب کردہ عنصر کہاں لاگو کیا جائے گا۔ اگرچہ دستخط صرف معاہدے کے آخری صفحے سے تعلق رکھتے ہیں۔ CONFIDENTIAL ڈاک ٹکٹ کو ہر صفحے پر ظاہر کرنے کی ضرورت ہو سکتی ہے۔
لہذا، درخواست کی حمایت کرتا ہے:
Current page only
All pages
Specific pages
مقصد یہ ہے کہ ہر عنصر کی قسم کے لیے الگ الگ ٹولز کی ضرورت کے بغیر پی ڈی ایف ایڈیٹنگ کے بہت سے عام کاموں کے لیے ایک مستقل ورک فلو فراہم کیا جائے۔
الیکٹرانک اور ڈیجیٹل دستخط
ایپلیکیشن بنانے سے پہلے، ان میں فرق کرنا ضروری ہے: الیکٹرانک دستخط اور ڈیجیٹل دستخط.
اس ٹیوٹوریل میں موجود ٹولز ایک الیکٹرانک دستخطی ورک فلو بناتے ہیں۔
آپ کی تیار کردہ، ٹائپ کی گئی یا اپ لوڈ کردہ دستخطی تصویر پی ڈی ایف صفحہ پر بصری طور پر رکھی گئی ہے۔ یہ ہاتھ سے کسی دستاویز پر دستخط کرنے اور فائل میں اس دستخط کی بصری نمائندگی داخل کرنے کے مترادف ہے۔
مثال کے طور پر، صارف کینوس پر دستخط کھینچ سکتا ہے۔
const signatureImage =
signatureCanvas.toDataURL("image/png");
اس کے بعد آپ اپنی پی ڈی ایف میں تیار کردہ تصویر کو شامل کر سکتے ہیں۔
ڈیجیٹل دستخط تکنیکی طور پر مختلف ہیں۔
سرٹیفکیٹ پر مبنی ڈیجیٹل دستخط دستاویز کی سالمیت اور دستخط کرنے والے سرٹیفکیٹ سے وابستہ شناخت کی تصدیق میں مدد کے لیے کرپٹوگرافک طریقے استعمال کرتے ہیں۔ اس میں ڈیجیٹل سرٹیفکیٹ، نجی چابیاں، دستخط کی تصدیق، اور اعتماد کی زنجیریں شامل ہوسکتی ہیں۔
پی ڈی ایف پر صرف ہاتھ سے لکھے ہوئے دستخط کی تصویر رکھنے سے اس قسم کی خفیہ تصدیق نہیں ہوتی۔
یہ فرق اہم ہے کیونکہ اصطلاحات بعض اوقات روزمرہ کی گفتگو میں ایک دوسرے کے ساتھ استعمال ہوتی ہیں، حالانکہ بنیادی تکنیکیں مختلف ہیں۔
ہم جو پروجیکٹ بنا رہے ہیں اس کا فوکس یہ ہے: بصری الیکٹرانک دستخط اور دستاویز کے عناصر. یہ سرٹیفکیٹ پر مبنی کرپٹوگرافک ڈیجیٹل دستخط تیار نہیں کرتا ہے۔
اس فرق کو واضح رکھنے سے یہ سمجھنا آسان ہو جاتا ہے کہ آپ کی درخواست کیا کر رہی ہے اور کس چیز کو ایک جدید دستخطی نظام کی ضرورت ہے۔
براؤزر پر مبنی ورک فلو کیسے کام کرتے ہیں۔
یہ عمل اس وقت شروع ہوتا ہے جب صارف پی ڈی ایف فائل کا انتخاب کرتا ہے۔
PDF.js دستاویز کو لوڈ کرتا ہے اور موجودہ صفحہ کو براؤزر کینوس پر پیش کرتا ہے۔ پچھلے اور اگلے بٹن صارفین کو پی ڈی ایف پر نیویگیٹ کرنے کی اجازت دیتے ہیں اس سے پہلے کہ عناصر کو کہاں رکھنا ہے۔
صارف پھر دو عنصر کی اقسام میں سے ایک کو منتخب کرتا ہے:
Signature
Text/Stamp
اگر دستخط ایک بار منتخب ہونے کے بعد، ایپلی کیشن تخلیق کے تین طریقے پیش کرتی ہے:
Draw
Type
Upload
منتخب دستخط کو ایک عنصر میں تبدیل کر دیا جائے گا جسے پی ڈی ایف پیش نظارہ کے اوپر دکھایا جا سکتا ہے۔
اگر ٹیکسٹ/سٹیمپ اگر آپ منتخب کرتے ہیں، تو ایپلیکیشن اپنی مرضی کے مواد یا پہلے سے طے شدہ سٹیمپ کی قدروں کا استعمال کرتے ہوئے ایک متنی عنصر بنائے گی۔
مکمل ورک فلو مندرجہ ذیل ہے:
Upload PDF
↓
Render and Navigate Pages
↓
Choose Signature or Text/Stamp
↓
Create the Element
↓
Position and Style It
↓
Choose Target Pages
↓
Apply & Finalize
↓
Generate the New PDF
↓
Preview the Result
↓
Rename and Download
ترمیم کے دوران پی ڈی ایف پیش نظارہ کے اوپر ظاہر ہونے والے عناصر صرف براؤزر کی طرف کی نمائندگی کرتے ہیں۔ اس مقام کو بعد میں ان نقاط میں تبدیل کیا جانا چاہیے جو اصل پی ڈی ایف صفحہ سے مماثل ہوں۔
مثال کے طور پر، ایک ایپلیکیشن ایسے عناصر کو اسٹور کر سکتی ہے جیسے:
const element = {
type: "signature",
x: 622,
y: 496,
scale: 1.14,
rotation: 0,
opacity: 1
};
جب صارف کلک کرتا ہے۔ درخواست اور تکمیلاس قدر کو پی ڈی ایف کے اندر حتمی جگہ کا حساب لگانے کے لیے استعمال کیا جاتا ہے۔
انٹرایکٹو پیش نظارہ اور حتمی پی ڈی ایف تخلیق کے درمیان یہ علیحدگی اس منصوبے کی بنیاد ہے۔ یہ صارفین کو پہلے دستاویز کو بصری طور پر تیار کرنے اور بیچ کے تیار ہونے کے بعد ہی ترمیم شدہ پی ڈی ایف بنانے کی اجازت دیتا ہے۔
پروجیکٹ کی ترتیبات
پروجیکٹ کو سمجھنے میں آسان بنانے کے لیے، ہم تین اہم فائلیں استعمال کریں گے:
pdf-signature-tool/
│
├── index.html
├── style.css
└── script.js
ایچ ٹی ایم ایل فائل میں اپ لوڈ انٹرفیس، پی ڈی ایف پیش نظارہ، ترمیم کنٹرول، حتمی پیش نظارہ اور ڈاؤن لوڈ کے حصے شامل ہیں۔
CSS فائلیں ترتیب اور بصری حالت کو سنبھالتی ہیں۔
JavaScript فائلیں پی ڈی ایف لوڈنگ، پیج رینڈرنگ، سگنیچر جنریشن، ٹیکسٹ اور اسٹیمپ عناصر، پوزیشننگ، اور حتمی پی ڈی ایف تخلیق اور ڈاؤن لوڈ کا انتظام کرتی ہیں۔
ایک بنیادی HTML ساخت کے ساتھ شروع کریں:
PDF Signature Tool
Upload your PDF to add your
electronic signature.
ہم PDF.js ورکر کو بھی ترتیب دیتے ہیں۔
pdfjsLib.GlobalWorkerOptions.workerSrc =
"https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js";
پروڈکشن پروجیکٹس کے لیے، تازہ ترین غیر متعینہ ریلیز کو خودکار طور پر لوڈ کرنے کے بجائے درست لائبریری ورژنز کو پن کریں اور ان کی جانچ کریں۔
پی ڈی ایف اپ لوڈ اور پیش نظارہ کریں۔
پہلا انٹرایکٹو مرحلہ آپ کی پی ڈی ایف کو قبول کرنا ہے۔
مطلوبہ عنصر کا حوالہ ملتا ہے۔
const pdfInput =
document.getElementById(
"pdfInput"
);
const selectPdfButton =
document.getElementById(
"selectPdfButton"
);
const dropZone =
document.getElementById(
"dropZone"
);
const uploadSection =
document.getElementById(
"uploadSection"
);
const editorSection =
document.getElementById(
"editorSection"
);
const pdfCanvas =
document.getElementById(
"pdfCanvas"
);
موجودہ دستاویز کی حالت کو ذخیرہ کرنے کے لیے ہمیں کچھ متغیرات کی بھی ضرورت ہے۔
let pdfDocument = null;
let originalPdfBytes = null;
let currentPage = 1;
let totalPages = 0;
حسب ضرورت بٹن پر کلک کرنے سے ایک پوشیدہ فائل ان پٹ کھل جاتا ہے۔
selectPdfButton.addEventListener(
"click",
() => {
pdfInput.click();
}
);
ایک بار فائل منتخب ہونے کے بعد، اسے پی ڈی ایف لوڈنگ فنکشن میں منتقل کر دیا جاتا ہے۔
pdfInput.addEventListener(
"change",
event => {
const file =
event.target.files[0];
if (file) {
loadPdf(file);
}
}
);
اس پر کارروائی کرنے سے پہلے فائل کی شکل چیک کریں۔
async function loadPdf(file) {
if (
file.type !==
"application/pdf"
) {
alert(
"Please select a valid PDF file."
);
return;
}
}
فائل کو اس طرح پڑھیں: ArrayBuffer.
const arrayBuffer =
await file.arrayBuffer();
PDF.js اور PDF-lib مختلف مراحل پر دستاویزات کا استعمال کرتے ہیں، لہذا اصل بائٹس کی ایک کاپی اپنے پاس رکھیں۔
originalPdfBytes =
new Uint8Array(
arrayBuffer
);
اب اپنی دستاویز PDF.js میں لوڈ کریں۔
pdfDocument =
await pdfjsLib
.getDocument({
data:
originalPdfBytes.slice()
})
.promise;
صفحہ کی گنتی کو محفوظ کریں۔
totalPages =
pdfDocument.numPages;
currentPage = 1;
اپ لوڈ انٹرفیس میں ایڈیٹر پر جائیں۔
uploadSection.hidden = true;
editorSection.hidden = false;
آخر میں ہم پہلا صفحہ پیش کرتے ہیں۔
await renderPage(currentPage);
مکمل لوڈنگ فنکشن مندرجہ ذیل ہے:
async function loadPdf(file) {
if (
file.type !==
"application/pdf"
) {
alert(
"Please select a valid PDF file."
);
return;
}
const arrayBuffer =
await file.arrayBuffer();
originalPdfBytes =
new Uint8Array(
arrayBuffer
);
pdfDocument =
await pdfjsLib
.getDocument({
data:
originalPdfBytes.slice()
})
.promise;
totalPages =
pdfDocument.numPages;
currentPage = 1;
uploadSection.hidden = true;
editorSection.hidden = false;
await renderPage(currentPage);
}
ڈریگ اینڈ ڈراپ سپورٹ کے لیے براؤزر کے ڈیفالٹ رویے کو روکتا ہے۔
dropZone.addEventListener(
"dragover",
event => {
event.preventDefault();
dropZone.classList.add(
"drag-active"
);
}
);
جب کوئی فائل ڈراپ ایریا سے نکل جاتی ہے، تو یہ اس کی فعال حیثیت کو ہٹا دیتی ہے۔
dropZone.addEventListener(
"dragleave",
() => {
dropZone.classList.remove(
"drag-active"
);
}
);
حذف شدہ فائلوں کو ہینڈل کریں۔
dropZone.addEventListener(
"drop",
event => {
event.preventDefault();
dropZone.classList.remove(
"drag-active"
);
const file =
event.dataTransfer.files[0];
if (file) {
loadPdf(file);
}
}
);
موجودہ پی ڈی ایف پیج کو رینڈر کریں۔
کہ renderPage() فنکشن پی ڈی ایف سے ایک صفحہ لوڈ کرتا ہے اور اسے کینوس پر دکھاتا ہے۔
async function renderPage(
pageNumber
) {
const page =
await pdfDocument.getPage(
pageNumber
);
const viewport =
page.getViewport({
scale: 1.5
});
const context =
pdfCanvas.getContext("2d");
pdfCanvas.width =
viewport.width;
pdfCanvas.height =
viewport.height;
await page.render({
canvasContext: context,
viewport
}).promise;
updatePageInfo();
}
انٹرایکٹو عنصر کی پرتیں کینوس کے اوپر بیٹھتی ہیں، اس لیے ان کا سائز ایک جیسا ہونا چاہیے۔
const elementLayer =
document.getElementById(
"elementLayer"
);
elementLayer.style.width =
`${viewport.width}px`;
elementLayer.style.height =
`${viewport.height}px`;
اس لائن کو اندر شامل کریں: renderPage() کینوس کا سائز سیٹ کرنے کے بعد
اس کے بعد آپ اپنے صفحہ کی معلومات کو اپ ڈیٹ کر سکتے ہیں۔
function updatePageInfo() {
pageInfo.textContent =
`Page ${currentPage} of ${totalPages}`;
}
اس وقت، اپ لوڈ کردہ پی ڈی ایف صفحات نظر آئیں گے، لیکن صارفین کو پھر بھی کثیر صفحاتی دستاویزات کے درمیان تشریف لانے کے لیے ایک طریقہ کی ضرورت ہوگی۔
پی ڈی ایف صفحہ نیویگیشن شامل کریں۔
نیویگیشن کنٹرولز حاصل کریں۔
const previousPage =
document.getElementById(
"previousPage"
);
const nextPage =
document.getElementById(
"nextPage"
);
const pageInfo =
document.getElementById(
"pageInfo"
);
پچھلے بٹن کو دبانے سے صفحہ نمبر کم ہو جاتا ہے۔
previousPage.addEventListener(
"click",
async () => {
if (currentPage <= 1) {
return;
}
currentPage--;
await renderPage(
currentPage
);
}
);
اگلا بٹن آگے بڑھتا ہے۔
nextPage.addEventListener(
"click",
async () => {
if (
currentPage >=
totalPages
) {
return;
}
currentPage++;
await renderPage(
currentPage
);
}
);
حدود کی جانچ دستاویز کے باہر نیویگیشن کو روکتی ہے۔
12 صفحات پر مشتمل پی ڈی ایف کے لیے، انٹرفیس ظاہر ہو سکتا ہے:
Page 12 of 12
پچھلا بٹن اب بھی دستیاب ہے، لیکن اگلی کارروائی کو غیر فعال کیا جا سکتا ہے کیونکہ صارف پہلے ہی آخری صفحہ پر ہے۔
function updateNavigationState() {
previousPage.disabled =
currentPage === 1;
nextPage.disabled =
currentPage ===
totalPages;
}
جب بھی نیا صفحہ پیش کیا جائے تو اس فنکشن کو کال کریں۔
function updatePageInfo() {
pageInfo.textContent =
`Page ${currentPage} of ${totalPages}`;
updateNavigationState();
}
صارفین اب پی ڈی ایف اپ لوڈ کر سکتے ہیں، ان صفحات کا پیش نظارہ کر سکتے ہیں، اور عین صفحہ پر تشریف لے جا سکتے ہیں جہاں انہیں اپنے دستخط، حسب ضرورت متن، یا دستاویز کی مہر لگانے کی ضرورت ہے۔

شامل کرنے کے لیے عناصر کو منتخب کریں۔
پی ڈی ایف لوڈ ہونے اور درست صفحہ ظاہر ہونے کے بعد، صارف ان عناصر کی اقسام کو منتخب کر سکتے ہیں جنہیں وہ دستاویز میں رکھنا چاہتے ہیں۔
ایڈیٹر دو اختیارات پیش کرتا ہے:
Signature
Text/Stamp
ایک عنصر سلیکٹر بنائیں۔
1. Choose Element
جاوا اسکرپٹ کے ساتھ کنٹرول درآمد کریں۔
const elementTypeInputs =
document.querySelectorAll(
'input[name="elementType"]'
);
const signatureControls =
document.getElementById(
"signatureControls"
);
const textControls =
document.getElementById(
"textControls"
);
تبدیلیاں وصول کریں:
elementTypeInputs.forEach(
input => {
input.addEventListener(
"change",
event => {
const type =
event.target.value;
if (
type ===
"signature"
) {
signatureControls.hidden =
false;
textControls.hidden =
true;
} else {
signatureControls.hidden =
true;
textControls.hidden =
false;
}
}
);
}
);
یہ انٹرفیس پر توجہ مرکوز رکھتا ہے۔ دستخط کے لیے مخصوص کنٹرول صرف اس وقت ظاہر ہوتے ہیں جب صارف دستخط بناتا ہے، جب کہ متن اور اسٹیمپ کنٹرول اس وقت ظاہر ہوتے ہیں جب متعلقہ عنصر کی قسم منتخب کی جاتی ہے۔
ایک دستخط بنائیں
دستخطی ورک فلو تین طریقوں کی حمایت کرتا ہے:
Draw
Type
Upload
طریقہ سلیکٹر بنائیں۔
2. Create Signature
فی الحال منتخب کردہ طریقہ کار پر نظر رکھتا ہے۔
let signatureMethod =
"draw";
تین پینلز کے درمیان سوئچ کریں۔
const signatureTabs =
document.querySelectorAll(
".signature-tabs button"
);
signatureTabs.forEach(
button => {
button.addEventListener(
"click",
() => {
signatureMethod =
button.dataset.method;
showSignatureMethod(
signatureMethod
);
}
);
}
);
پینل ٹوگل فنکشن غیر فعال طریقوں کو چھپا سکتا ہے۔
function showSignatureMethod(
method
) {
drawPanel.hidden =
method !== "draw";
typePanel.hidden =
method !== "type";
uploadPanel.hidden =
method !== "upload";
}
ہر طریقہ ایک ہی قسم کا حتمی عنصر (دستخط) تیار کرتا ہے، لیکن اس دستخط کا ماخذ مختلف ہوتا ہے۔
دستخط بنائیں
کہ ڈرا یہ اختیار صارفین کو اپنے براؤزر میں براہ راست ہاتھ سے لکھا ہوا دستخط بنانے کی اجازت دیتا ہے۔
ڈرائنگ پینل میں کینوس شامل کریں۔
ڈرائنگ کا سیاق و سباق حاصل کریں۔
const signatureCanvas =
document.getElementById(
"signatureCanvas"
);
const signatureContext =
signatureCanvas.getContext(
"2d"
);
let isDrawing = false;
جب پوائنٹر کینوس کو چھوتا ہے تو ڈرائنگ شروع کریں:
signatureCanvas.addEventListener(
"pointerdown",
event => {
isDrawing = true;
const rect =
signatureCanvas
.getBoundingClientRect();
signatureContext.beginPath();
signatureContext.moveTo(
event.clientX -
rect.left,
event.clientY -
rect.top
);
}
);
لائن جاری رہتی ہے جیسے ہی پوائنٹر چلتا ہے۔
signatureCanvas.addEventListener(
"pointermove",
event => {
if (!isDrawing) {
return;
}
const rect =
signatureCanvas
.getBoundingClientRect();
signatureContext.lineTo(
event.clientX -
rect.left,
event.clientY -
rect.top
);
signatureContext.stroke();
}
);
جب آپ پوائنٹر جاری کرتے ہیں تو ڈرائنگ بند کریں۔
signatureCanvas.addEventListener(
"pointerup",
() => {
isDrawing = false;
}
);
signatureCanvas.addEventListener(
"pointerleave",
() => {
isDrawing = false;
}
);
کچھ ڈرائنگ خصوصیات مقرر کریں:
signatureContext.lineWidth = 2;
signatureContext.lineCap =
"round";
signatureContext.lineJoin =
"round";
ٹچ ڈیوائسز پر، یہ براؤزر کو ڈرائنگ کے اشاروں کو صفحہ سکرولنگ کے طور پر تشریح کرنے سے روکتا ہے۔
#signatureCanvas {
touch-action: none;
cursor: crosshair;
}
کلیئر بٹن ڈرائنگ کینوس کو ری سیٹ کرتا ہے۔
clearSignature.addEventListener(
"click",
() => {
signatureContext.clearRect(
0,
0,
signatureCanvas.width,
signatureCanvas.height
);
}
);
دستخط تیار ہونے کے بعد، کینوس کو PNG ڈیٹا URL میں تبدیل کریں۔
const drawnSignature =
signatureCanvas.toDataURL(
"image/png"
);
کینوس شفافیت کو برقرار رکھ سکتا ہے، لہذا نتیجے میں دستخط کو پی ڈی ایف کے اوپر ایک غیر مطلوبہ مستطیل پس منظر شامل کیے بغیر رکھا جا سکتا ہے۔
تیار کردہ تصاویر اب انٹرایکٹو عنصر کی تہوں کے اندر دکھائی جا سکتی ہیں۔
function useDrawnSignature() {
const image =
new Image();
image.src =
signatureCanvas.toDataURL(
"image/png"
);
image.onload =
() => {
createSignatureElement(
image.src
);
};
}
یہ صارفین کو ایک بصری دستخطی عنصر فراہم کرتا ہے جسے بعد میں پی ڈی ایف صفحات کے اوپر رکھا جا سکتا ہے۔
اپنے دستخط درج کریں۔
ہر کسی کے پاس ٹچ اسکرین، اسٹائلس، یا روایتی دستخطی تصویر نہیں ہوتی ہے۔
کہ زمرہ اختیارات صارفین کو اپنا نام درج کرنے اور دستخطی طرز کی ظاہری شکل کو منتخب کرنے کی اجازت دیتے ہیں۔
ایک ان پٹ کنٹرول شامل کریں۔
متن کی تبدیلیاں سنیں:
typedSignature.addEventListener(
"input",
updateTypedSignatures
);
متعدد طرز کے مناظر بنائیں۔
const signatureFonts = [
"cursive",
"'Brush Script MT', cursive",
"'Segoe Script', cursive"
];
دستیاب اختیارات پیش کرتا ہے۔
function updateTypedSignatures() {
const value =
typedSignature.value.trim();
signatureStyles.innerHTML = "";
if (!value) {
return;
}
signatureFonts.forEach(
font => {
const option =
document.createElement(
"button"
);
option.textContent =
value;
option.style.fontFamily =
font;
option.style.fontSize =
`${signatureFontSize.value}px`;
option.addEventListener(
"click",
() => {
createTypedSignature(
value,
font
);
}
);
signatureStyles.appendChild(
option
);
}
);
}
درج کردہ دستخط کو دوسرے کینوس کا استعمال کرتے ہوئے تصویر میں تبدیل کیا جا سکتا ہے۔
function createTypedSignature(
text,
fontFamily
) {
const canvas =
document.createElement(
"canvas"
);
const context =
canvas.getContext("2d");
const fontSize =
Number(
signatureFontSize.value
);
context.font =
`${fontSize}px ${fontFamily}`;
const width =
context.measureText(
text
).width;
canvas.width =
Math.ceil(width + 40);
canvas.height =
Math.ceil(fontSize * 2);
context.font =
`${fontSize}px ${fontFamily}`;
context.textBaseline =
"middle";
context.fillText(
text,
20,
canvas.height / 2
);
const imageUrl =
canvas.toDataURL(
"image/png"
);
createSignatureElement(
imageUrl
);
}
ٹائپ شدہ دستخطوں کو اب تیار کردہ دستخطوں کی طرح سمجھا جاتا ہے۔ اس کا مطلب ہے کہ یہ ایک تصویری عنصر بن جاتا ہے جسے آپ اپنی پی ڈی ایف میں پوزیشن اور بعد میں شامل کر سکتے ہیں۔

دستخطی تصویر اپ لوڈ کریں۔
تیسرا آپشن صارفین کو موجودہ دستخطی تصویر اپ لوڈ کرنے کی اجازت دیتا ہے۔
فائل ان پٹ شامل کریں۔
فائل کا انتخاب وصول کریں۔
signatureUpload.addEventListener(
"change",
event => {
const file =
event.target.files[0];
if (!file) {
return;
}
loadSignatureImage(file);
}
);
تصویر کی تصدیق کریں:
function loadSignatureImage(
file
) {
const allowedTypes = [
"image/png",
"image/jpeg"
];
if (
!allowedTypes.includes(
file.type
)
) {
alert(
"Please upload a PNG or JPEG image."
);
return;
}
}
منتخب تصویر پڑھیں:
const reader =
new FileReader();
reader.onload =
event => {
createSignatureElement(
event.target.result
);
};
reader.readAsDataURL(file);
منتخب فائل کا نام دکھاتا ہے:
selectedSignatureFile.textContent =
`Selected: ${file.name}`;
مکمل خصوصیات میں شامل ہیں:
function loadSignatureImage(
file
) {
const allowedTypes = [
"image/png",
"image/jpeg"
];
if (
!allowedTypes.includes(
file.type
)
) {
alert(
"Please upload a PNG or JPEG image."
);
return;
}
selectedSignatureFile.textContent =
`Selected: ${file.name}`;
const reader =
new FileReader();
reader.onload =
event => {
createSignatureElement(
event.target.result
);
};
reader.readAsDataURL(file);
}
شفاف PNGs عام طور پر خاص طور پر اچھی طرح سے کام کرتے ہیں کیونکہ دستاویز پر صرف دستخطی اسٹروک نظر آتا ہے۔

ایک دستخطی پیش نظارہ عنصر بنائیں
دستخط کے تینوں طریقے ایک ہی فنکشن کو کال کرتے ہیں۔
createSignatureElement(imageUrl);
اس کا مطلب یہ ہے کہ باقی ایڈیٹر کو دستخطوں، ان پٹ اور اپ لوڈ کردہ دستخطوں کے لیے کسی الگ پوزیشننگ منطق کی ضرورت نہیں ہے۔
پیش نظارہ عنصر بنائیں۔
let activeElement = null;
function createSignatureElement(
imageUrl
) {
elementLayer.innerHTML = "";
const image =
document.createElement(
"img"
);
image.src =
imageUrl;
image.className =
"pdf-element signature-element";
image.style.left =
"100px";
image.style.top =
"100px";
image.style.width =
"180px";
elementLayer.appendChild(
image
);
activeElement = {
type: "signature",
source: imageUrl,
element: image,
x: 100,
y: 100,
scale: 1,
rotation: 0,
opacity: 1
};
}
پیش نظارہ اب دستخط کی نمائندگی کرتا ہے جو بالآخر پی ڈی ایف میں لکھا جائے گا۔
اسی اسٹیٹ آبجیکٹ کو بعد میں اپ ڈیٹ کیا جا سکتا ہے جب صارف پوزیشن، سائز، گردش، یا دستخط کی دھندلاپن کو تبدیل کرتا ہے۔
متن اور پیش سیٹ ڈاک ٹکٹ شامل کریں۔
دوسری اہم عنصر کی قسم ہے: ٹیکسٹ/سٹیمپ.
یہ موڈ مفید ہے جب آپ کی دستاویز کو ہاتھ سے لکھے ہوئے دستخط کے بجائے مختصر لیبل، حیثیت، تاریخ، یا دوسرے متن کی ضرورت ہو۔
ایک کنٹرول بنائیں۔
اپنی مرضی کے متن کو صارف کی اقسام کے طور پر دکھایا جا سکتا ہے۔
customText.addEventListener(
"input",
() => {
createTextElement(
customText.value
);
}
);
پیش سیٹ ڈاک ٹکٹ ایک ہی ٹیکسٹ ان پٹ کو اپ ڈیٹ کر سکتے ہیں۔
const stampButtons =
document.querySelectorAll(
"[data-stamp]"
);
stampButtons.forEach(
button => {
button.addEventListener(
"click",
() => {
const stamp =
button.dataset.stamp;
customText.value =
stamp;
createTextElement(
stamp
);
}
);
}
);
متن کا پیش نظارہ بنائیں۔
function createTextElement(
text
) {
if (!text.trim()) {
elementLayer.innerHTML = "";
activeElement = null;
return;
}
elementLayer.innerHTML = "";
const textElement =
document.createElement(
"div"
);
textElement.className =
"pdf-element text-element";
textElement.textContent =
text;
textElement.style.left =
"100px";
textElement.style.top =
"100px";
textElement.style.fontSize =
`${textSize.value}px`;
textElement.style.color =
textColor.value;
elementLayer.appendChild(
textElement
);
activeElement = {
type: "text",
text,
element:
textElement,
x: 100,
y: 100,
fontSize:
Number(
textSize.value
),
color:
textColor.value,
rotation: 0,
opacity: 1
};
}
موجودہ عنصر کو اپ ڈیٹ کرتا ہے جب اس کا سائز تبدیل ہوتا ہے۔
textSize.addEventListener(
"input",
() => {
if (
activeElement?.type !==
"text"
) {
return;
}
activeElement.fontSize =
Number(
textSize.value
);
activeElement
.element
.style
.fontSize =
`${textSize.value}px`;
}
);
رنگوں کے ساتھ بھی ایسا ہی کریں۔
textColor.addEventListener(
"input",
() => {
if (
activeElement?.type !==
"text"
) {
return;
}
activeElement.color =
textColor.value;
activeElement
.element
.style
.color =
textColor.value;
}
);
صارفین اب حسب ضرورت مواد درج کر سکتے ہیں جیسے:
Signed on: 08-09-2025
یا فوری طور پر پہلے سے طے شدہ دستاویز کا ڈاک ٹکٹ منتخب کریں۔

اس مقام پر، ایپلیکیشن دستیاب ان پٹ طریقوں میں سے کسی کا استعمال کرتے ہوئے مواد تیار کر سکتی ہے، بشمول تیار کردہ دستخط، ٹائپ شدہ دستخط، اپ لوڈ کردہ دستخطی تصاویر، حسب ضرورت متن، یا پیش سیٹ دستاویز کے ڈاک ٹکٹ۔
پوزیشن اور طرز کے عناصر
اپنے دستخط، ٹیکسٹ لیبل، یا پہلے سے سیٹ اسٹیمپ بنانے کے بعد، اگلا مرحلہ یہ ہے کہ اسے اپنے پی ڈی ایف صفحہ پر درست طریقے سے رکھیں۔
پیش نظارہ عنصر ہے elementLayer پہلے بنایا گیا تھا۔ یہ پرت پی ڈی ایف کینوس کے سائز سے میل کھاتی ہے، جس سے صارفین کو حتمی پی ڈی ایف میں لکھے جانے سے پہلے عناصر کو بصری طور پر منتقل کرنے کی اجازت ملتی ہے۔
ایڈیٹر اس کے لیے کنٹرول بھی فراہم کرتا ہے:
-
پیمانہ
-
گردش
-
دھندلاپن
-
ایکس پوزیشن
-
Y پوزیشن
فعال عنصر کے لحاظ سے درست کنٹرول مختلف ہو سکتے ہیں۔ مثال کے طور پر، سائز خاص طور پر دستخطوں کے لیے مفید ہے، جبکہ ٹیکسٹ کے سائز اور رنگ کو پچھلے حصے کے ٹیکسٹ/سٹیمپ کنٹرولز کے ذریعے سنبھالا جاتا ہے۔
ایک بیچ کنٹرول بنائیں۔
3. Placement & Style
دستخطی عناصر کے لیے، اسکیل کنٹرول شامل کریں۔
جاوا اسکرپٹ کے ساتھ کنٹرول درآمد کریں۔
const scaleInput =
document.getElementById(
"scaleInput"
);
const scaleValue =
document.getElementById(
"scaleValue"
);
const rotationInput =
document.getElementById(
"rotationInput"
);
const opacityInput =
document.getElementById(
"opacityInput"
);
const xPosition =
document.getElementById(
"xPosition"
);
const yPosition =
document.getElementById(
"yPosition"
);
آئیے ایک فنکشن کا استعمال کرتے ہوئے بصری تبدیلی کو اپ ڈیٹ کریں۔
function updateElementTransform() {
if (!activeElement) {
return;
}
activeElement.element.style.transform =
`
scale(${activeElement.scale})
rotate(${activeElement.rotation}deg)
`;
activeElement.element.style.opacity =
activeElement.opacity;
}
متن کے عناصر کے لیے، شروع کریں۔ scale پسند 1 لہذا آپ تبادلوں کی وہی خصوصیات استعمال کرنا جاری رکھ سکتے ہیں۔
activeElement = {
type: "text",
text,
element: textElement,
x: 100,
y: 100,
scale: 1,
rotation: 0,
opacity: 1
};
عنصر کا پیمانہ تبدیل کریں۔
جب صارف اسکیل سلائیڈر کو حرکت دیتا ہے تو فیصد کو اعشاریہ کی قدروں میں تبدیل کریں۔
scaleInput.addEventListener(
"input",
() => {
if (!activeElement) {
return;
}
const percentage =
Number(
scaleInput.value
);
activeElement.scale =
percentage / 100;
scaleValue.textContent =
`${percentage}%`;
updateElementTransform();
}
);
قدر 100% اصل پیش نظارہ سائز کی نشاندہی کرتا ہے۔
50% → 0.5
100% → 1
114% → 1.14
200% → 2
یہ آپ کو نئی تصویر بنائے بغیر اپنے اپ لوڈ کردہ، تیار کردہ یا ٹائپ شدہ دستخط کو آسانی سے بڑا یا کم کرنے کی اجازت دیتا ہے۔
عنصر کی گردش
گردش ان پٹ زاویوں کو ڈگری کے طور پر اسٹور کرتا ہے۔
rotationInput.addEventListener(
"input",
() => {
if (!activeElement) {
return;
}
activeElement.rotation =
Number(
rotationInput.value
);
updateElementTransform();
}
);
گردش 0 عنصر کو افقی رکھتا ہے، جبکہ مثبت یا منفی قدریں عنصر کو گھومتی ہیں۔
دھندلاپن ایڈجسٹمنٹ
دھندلاپن ڈاک ٹکٹوں، واٹر مارکس اور دیگر دستاویز کے لیبلز کے لیے مفید ہو سکتا ہے۔
فیصد سلائیڈر ان کے درمیان اقدار کو تبدیل کرتا ہے: 0 اور 1.
opacityInput.addEventListener(
"input",
() => {
if (!activeElement) {
return;
}
activeElement.opacity =
Number(
opacityInput.value
) / 100;
updateElementTransform();
}
);
مثال کے طور پر:
100% → 1
75% → 0.75
50% → 0.5
آخری پی ڈی ایف تیار کرتے وقت وہی اوپیسٹی ویلیو بعد میں استعمال کی جائے گی۔
پی ڈی ایف پیش نظارہ میں عناصر کو گھسیٹیں۔
X اور Y نقاط کو دستی طور پر داخل کرنا درست ایڈجسٹمنٹ کے لیے مفید ہے، لیکن زیادہ تر صارفین عناصر کو براہ راست مطلوبہ پوزیشن پر گھسیٹنے کو ترجیح دیتے ہیں۔
ڈریگ اسٹیٹ کو ٹریک کرتا ہے۔
let isDragging = false;
let dragOffsetX = 0;
let dragOffsetY = 0;
ایک بار جب دستخط یا متن کا عنصر بن جائے تو اس کے ساتھ ڈریگ ایکشن منسلک کریں۔
function enableDragging(
element
) {
element.addEventListener(
"pointerdown",
event => {
isDragging = true;
const elementRect =
element
.getBoundingClientRect();
dragOffsetX =
event.clientX -
elementRect.left;
dragOffsetY =
event.clientY -
elementRect.top;
element.setPointerCapture(
event.pointerId
);
}
);
}
عنصر بناتے وقت اس فنکشن کو کال کریں۔
enableDragging(image);
یا:
enableDragging(textElement);
اگلا، پوائنٹر تحریک کو سنیں.
elementLayer.addEventListener(
"pointermove",
event => {
if (
!isDragging ||
!activeElement
) {
return;
}
const layerRect =
elementLayer
.getBoundingClientRect();
const x =
event.clientX -
layerRect.left -
dragOffsetX;
const y =
event.clientY -
layerRect.top -
dragOffsetY;
moveActiveElement(
x,
y
);
}
);
دوبارہ قابل استعمال حرکت کے افعال بنائیں۔
function moveActiveElement(
x,
y
) {
if (!activeElement) {
return;
}
activeElement.x = x;
activeElement.y = y;
activeElement.element.style.left =
`${x}px`;
activeElement.element.style.top =
`${y}px`;
xPosition.value =
Math.round(x);
yPosition.value =
Math.round(y);
}
جب آپ پوائنٹر جاری کرتے ہیں تو گھسیٹنا بند کریں۔
elementLayer.addEventListener(
"pointerup",
() => {
isDragging = false;
}
);
elementLayer.addEventListener(
"pointercancel",
() => {
isDragging = false;
}
);
اب آپ اپنے دستخط یا متن کے عنصر کو براہ راست اپنے دستاویز پر منتقل کر سکتے ہیں۔
مثال کے طور پر، آپ کا اپ لوڈ کردہ دستخط آخری صفحہ کے نیچے دائیں کونے کے قریب رکھا جا سکتا ہے۔

اپنی پوزیشن کو دستی طور پر اپ ڈیٹ کریں۔
X اور Y فیلڈز عناصر کی پوزیشن کا ایک اور طریقہ فراہم کرتے ہیں۔
ایکس کوآرڈینیٹ تبدیلیوں کو سنیں۔
xPosition.addEventListener(
"input",
() => {
if (!activeElement) {
return;
}
const x =
Number(
xPosition.value
);
moveActiveElement(
x,
activeElement.y
);
}
);
Y کے لیے بھی ایسا ہی کریں۔
yPosition.addEventListener(
"input",
() => {
if (!activeElement) {
return;
}
const y =
Number(
yPosition.value
);
moveActiveElement(
activeElement.x,
y
);
}
);
گھسیٹنا اور دستی کوآرڈینیٹ ان پٹ مطابقت پذیر رہتے ہیں۔ کسی عنصر کو منتقل کرنا فیلڈ کو اپ ڈیٹ کرتا ہے، اور فیلڈ کو تبدیل کرنے سے پیش نظارہ عنصر منتقل ہوتا ہے۔
عناصر کو صفحہ کے اندر رکھیں
سرحدوں کے بغیر، صارف غلطی سے عناصر کو مکمل طور پر پی ڈی ایف پیش نظارہ سے باہر گھسیٹ سکتے ہیں۔
آپ محفوظ کرنے سے پہلے مقامات کو محدود کر سکتے ہیں۔
function clampPosition(
x,
y
) {
const element =
activeElement.element;
const maxX =
elementLayer.clientWidth -
element.offsetWidth;
const maxY =
elementLayer.clientHeight -
element.offsetHeight;
return {
x:
Math.max(
0,
Math.min(x, maxX)
),
y:
Math.max(
0,
Math.min(y, maxY)
)
};
}
اسے اندر استعمال کریں۔ moveActiveElement():
const position =
clampPosition(
x,
y
);
activeElement.x =
position.x;
activeElement.y =
position.y;
جب اسکیلنگ یا گردش کا اطلاق ہوتا ہے تو، کسی عنصر کی تبدیل شدہ بصری حدیں اس کے اصل خانے سے آگے بڑھ سکتی ہیں۔ پروڈکشن ایڈیٹرز استعمال کر سکتے ہیں: getBoundingClientRect() زیادہ درست تبدیلی کی حد کے حساب کتاب کے لیے۔
یہاں دکھایا گیا بنیادی کلیمپ پوزیشننگ ورک فلو کو ظاہر کرنے کے لیے کافی ہے۔
منتخب صفحات پر عناصر کا اطلاق کریں۔
عنصر رکھنے کے بعد، صارف فیصلہ کرتا ہے کہ کون سا پی ڈی ایف صفحہ عنصر وصول کرے گا۔
انٹرفیس تین اختیارات پیش کرتا ہے:
Current page only
All pages
Specific pages
ایک کنٹرول بنائیں۔
4. Apply to Pages
منتخب موڈ پڑھیں:
function getTargetPages() {
const mode =
document.querySelector(
'input[name="applyMode"]:checked'
).value;
if (
mode ===
"current"
) {
return [
currentPage
];
}
if (
mode ===
"all"
) {
return Array.from(
{
length:
totalPages
},
(_, index) =>
index + 1
);
}
return parsePageRange(
specificPages.value
);
}
یہ حسب ضرورت اقدار کو اس طرح پارس کرتا ہے:
1, 3-5, 10
کے ساتھ:
function parsePageRange(
value
) {
const pages =
new Set();
value
.split(",")
.forEach(part => {
const item =
part.trim();
if (!item) {
return;
}
if (
item.includes("-")
) {
const [
start,
end
] =
item
.split("-")
.map(Number);
for (
let page = start;
page <= end;
page++
) {
if (
page >= 1 &&
page <= totalPages
) {
pages.add(page);
}
}
} else {
const page =
Number(item);
if (
page >= 1 &&
page <= totalPages
) {
pages.add(page);
}
}
});
return [...pages];
}
نتائج درج ذیل ہیں:
[
1,
3,
4,
5,
10
]
یہ آپ کو ایک بار اپنے دستخط یا مہر لگانے کی اجازت دیتا ہے اور پھر اسے متعدد ہدف والے صفحات پر لاگو کر سکتا ہے۔
ذہن میں رکھیں کہ صفحہ کے سائز ایک ہی پی ڈی ایف میں بھی مختلف ہو سکتے ہیں۔ صفحات پر ایک جیسے نقاط کو لاگو کرنا اس وقت بہترین کام کرتا ہے جب وہ صفحات ایک مستقل سائز اور ترتیب کا استعمال کرتے ہیں۔
پی ڈی ایف کا اطلاق اور اسے حتمی شکل دینا
ایک بار جب کوئی عنصر بنایا جاتا ہے، رکھا جاتا ہے، اسٹائل کیا جاتا ہے، اور صحیح صفحہ پر تفویض کیا جاتا ہے، صارف کر سکتا ہے۔ درخواست اور تکمیل.
ایک ایکشن بٹن بنائیں۔
بٹن حاصل کریں:
const applyButton =
document.getElementById(
"applyButton"
);
const startOverButton =
document.getElementById(
"startOverButton"
);
حتمی پی ڈی ایف بنانے سے پہلے چیک کریں کہ آیا عنصر موجود ہے۔
applyButton.addEventListener(
"click",
async () => {
if (!activeElement) {
alert(
"Please add a signature, text, or stamp first."
);
return;
}
const targetPages =
getTargetPages();
if (
targetPages.length === 0
) {
alert(
"Please select at least one valid page."
);
return;
}
await generateFinalPdf(
targetPages
);
}
);
کہ generateFinalPdf() فنکشن اگلے حصے میں اصل پی ڈی ایف ترمیم کو ہینڈل کرتا ہے۔
کہ دوبارہ شروع کریں بٹن دبانے سے موجودہ دستاویز مٹ جائے گی اور ایپلیکیشن ری سیٹ ہو جائے گی۔
startOverButton.addEventListener(
"click",
resetTool
);
ایک ری سیٹ فنکشن بنائیں۔
function resetTool() {
pdfDocument = null;
originalPdfBytes = null;
currentPage = 1;
totalPages = 0;
activeElement = null;
pdfInput.value = "";
elementLayer.innerHTML = "";
editorSection.hidden = true;
resultSection.hidden = true;
uploadSection.hidden = false;
}
یہ آپ کی درخواست کو اس کی اصل اپ لوڈ حالت میں واپس کر دے گا۔

انٹرایکٹو ایڈیٹنگ مرحلہ اب مکمل ہو گیا ہے۔ صارف دستخط یا متن کا عنصر بنا سکتے ہیں اور اسے براہ راست پی ڈی ایف کے اوپر رکھ سکتے ہیں، اس کی ظاہری شکل کو ایڈجسٹ کر سکتے ہیں، ہدف کا صفحہ منتخب کر سکتے ہیں، اور دستاویز کو حتمی کارروائی کے لیے تیار کر سکتے ہیں۔
دستخط شدہ پی ڈی ایف بنائیں
براؤزر کے پیش نظارہ میں دکھائے گئے عناصر کو ابھی تک اصل پی ڈی ایف میں شامل نہیں کیا گیا ہے۔ جب صارف کلک کرتا ہے۔ درخواست اور تکمیلایپلیکیشن اصل دستاویز کو PDF-lib میں لوڈ کرتی ہے اور منتخب دستخط، متن یا ڈاک ٹکٹ کو ہدف والے صفحہ پر لکھتی ہے۔
اصل پی ڈی ایف بائٹس لوڈ کرکے شروع کریں۔
async function generateFinalPdf(
targetPages
) {
const pdfDoc =
await PDFLib.PDFDocument.load(
originalPdfBytes.slice()
);
const pages =
pdfDoc.getPages();
}
عناصر رکھنے سے پہلے آپ کو براؤزر کے نقاط کو پی ڈی ایف کوآرڈینیٹ میں تبدیل کرنا ہوگا۔
پیش نظارہ کینوس اصل PDF صفحہ سے مختلف سائز میں ظاہر ہو سکتا ہے۔ کوآرڈینیٹ سسٹم بھی ایک مختلف Y-axis اصل کا استعمال کرتا ہے۔
ہر ہدف والے صفحے کے لیے پیمانے کا حساب لگائیں۔
const {
width: pdfWidth,
height: pdfHeight
} = page.getSize();
const scaleX =
pdfWidth /
pdfCanvas.width;
const scaleY =
pdfHeight /
pdfCanvas.height;
پیش منظر کی پوزیشن کو تبدیل کریں:
const pdfX =
activeElement.x *
scaleX;
const pdfY =
pdfHeight -
(
activeElement.y +
activeElement.element.offsetHeight
) * scaleY;
یہ تبدیلی براؤزر کے اوپری بائیں کوآرڈینیٹ سسٹم سے پی ڈی ایف پیج کے کوآرڈینیٹ سسٹم تک عناصر کا نقشہ بناتی ہے۔
دستخط پر مشتمل ہے۔
آپ کے کھینچے ہوئے، ٹائپ کیے گئے اور اپ لوڈ کیے گئے دستخط تمام تصاویر کے طور پر دکھائے جائیں گے جب تک کہ وہ پروسیسنگ کے آخری مرحلے تک نہ پہنچ جائیں۔
دستخطی ڈیٹا URL کو بائٹس میں تبدیل کریں۔
async function dataUrlToBytes(
dataUrl
) {
const response =
await fetch(dataUrl);
return await response.arrayBuffer();
}
اپنی دستخطی تصویر داخل کریں۔
const signatureBytes =
await dataUrlToBytes(
activeElement.source
);
const signatureImage =
await pdfDoc.embedPng(
signatureBytes
);
اگر اپ لوڈ کردہ JPEG دستخط معاون ہیں، تو ایپلیکیشنز کو اصل تصویری فارمیٹ کو محفوظ اور استعمال کرنا چاہیے۔ embedJpg() اگر مناسب ہو۔
حتمی طول و عرض کا حساب لگائیں۔
const previewWidth =
activeElement
.element
.offsetWidth *
activeElement.scale;
const previewHeight =
activeElement
.element
.offsetHeight *
activeElement.scale;
const finalWidth =
previewWidth *
scaleX;
const finalHeight =
previewHeight *
scaleY;
پھر اپنے دستخط کھینچیں۔
page.drawImage(
signatureImage,
{
x: pdfX,
y:
pdfHeight -
(
activeElement.y *
scaleY
) -
finalHeight,
width:
finalWidth,
height:
finalHeight,
rotate:
PDFLib.degrees(
activeElement.rotation
),
opacity:
activeElement.opacity
}
);
تینوں طریقے تصویری عناصر کو حتمی شکل دینے سے پہلے تیار کرتے ہیں، اس لیے ایک ہی پروسیسنگ منطق کام کرتی ہے اس سے قطع نظر کہ دستخط کھینچا گیا ہے، ٹائپ کیا گیا ہے یا اپ لوڈ کیا گیا ہے۔
متن یا ڈاک ٹکٹ شامل کریں۔
متن اور پیش سیٹ ڈاک ٹکٹ براہ راست پی ڈی ایف صفحات پر لکھے جاتے ہیں۔
سب سے پہلے، منتخب کردہ رنگ کو ہیکساڈیسیمل سے آرجیبی اقدار میں تبدیل کریں۔
function hexToRgb(
hex
) {
const value =
hex.replace(
"#",
""
);
return {
r:
parseInt(
value.substring(0, 2),
16
) / 255,
g:
parseInt(
value.substring(2, 4),
16
) / 255,
b:
parseInt(
value.substring(4, 6),
16
) / 255
};
}
متن کا اطلاق کریں:
const color =
hexToRgb(
activeElement.color
);
page.drawText(
activeElement.text,
{
x:
activeElement.x *
scaleX,
y:
pdfHeight -
(
activeElement.y *
scaleY
) -
activeElement.fontSize,
size:
activeElement.fontSize *
scaleY,
color:
PDFLib.rgb(
color.r,
color.g,
color.b
),
rotate:
PDFLib.degrees(
activeElement.rotation
),
opacity:
activeElement.opacity
}
);
تمام ہدف والے صفحات پر کارروائی کرنے کے بعد، ترمیم شدہ دستاویز کو محفوظ کریں۔
const finalPdfBytes =
await pdfDoc.save();
const finalPdfBlob =
new Blob(
[finalPdfBytes],
{
type:
"application/pdf"
}
);
await showFinalPreview(
finalPdfBlob
);
اس وقت، آپ کے منتخب کردہ دستخط، متن، یا ڈاک ٹکٹ تیار کردہ پی ڈی ایف میں شامل کر دیے گئے ہیں۔
حتمی پی ڈی ایف پیش نظارہ
کسی دستاویز کو ڈاؤن لوڈ کرنے سے پہلے، ایپلیکیشن مکمل شدہ پی ڈی ایف کو ایک علیحدہ پیش نظارہ علاقے میں دکھاتی ہے۔
اس سے صارفین کو یہ یقینی بنانے میں مدد ملتی ہے کہ عناصر صحیح صفحہ اور متوقع مقام پر ظاہر ہوں۔
PDF.js کا استعمال کرتے ہوئے تیار کردہ فائل لوڈ کریں۔
let finalPdfDocument = null;
let finalPage = 1;
async function showFinalPreview(
blob
) {
const bytes =
await blob.arrayBuffer();
finalPdfDocument =
await pdfjsLib
.getDocument({
data: bytes
})
.promise;
finalPage = 1;
editorSection.hidden =
true;
resultSection.hidden =
false;
await renderFinalPage(
finalPage
);
}
موجودہ نتائج کا صفحہ پیش کرتا ہے۔
async function renderFinalPage(
pageNumber
) {
const page =
await finalPdfDocument
.getPage(
pageNumber
);
const viewport =
page.getViewport({
scale: 1.4
});
finalCanvas.width =
viewport.width;
finalCanvas.height =
viewport.height;
await page.render({
canvasContext:
finalCanvas
.getContext("2d"),
viewport
}).promise;
finalPageInfo.textContent =
`Page ${pageNumber} of ${finalPdfDocument.numPages}`;
}
پچھلے اور اگلے کنٹرولز وہی نیویگیشن پیٹرن استعمال کر سکتے ہیں جیسا کہ اصل PDF پیش نظارہ ہے۔

نام تبدیل کریں اور فائنل PDF ڈاؤن لوڈ کریں۔
پروسیس شدہ دستاویز کا جائزہ لینے کے بعد، صارف اسے ڈاؤن لوڈ کرنے سے پہلے فائل کا نام بدل سکتے ہیں۔
مثال کے طور پر:
document_signed.pdf
فائل کا نام ان پٹ بنائیں۔
یقینی بنائیں کہ فائل کا نام درست ایکسٹینشن ہے۔
function getOutputFilename() {
let filename =
outputFilename
.value
.trim();
if (!filename) {
filename =
"document_signed.pdf";
}
if (
!filename
.toLowerCase()
.endsWith(".pdf")
) {
filename += ".pdf";
}
return filename;
}
نتائج کا سیکشن صفحات کی کل تعداد اور تیار کردہ فائل کا سائز بھی دکھا سکتا ہے۔
function formatFileSize(
bytes
) {
if (
bytes <
1024 * 1024
) {
return (
bytes / 1024
).toFixed(2) + " KB";
}
return (
bytes /
1024 /
1024
).toFixed(2) + " MB";
}
فائل کی معلومات کو اپ ڈیٹ کریں۔
filePageCount.textContent =
`Total Pages: ${finalPdfDocument.numPages}`;
fileSize.textContent =
`File Size: ${
formatFileSize(
finalPdfBlob.size
)
}`;
عارضی آبجیکٹ URL کا استعمال کرتے ہوئے فائل ڈاؤن لوڈ کریں۔
downloadButton.addEventListener(
"click",
() => {
const url =
URL.createObjectURL(
finalPdfBlob
);
const link =
document.createElement(
"a"
);
link.href =
url;
link.download =
getOutputFilename();
link.click();
URL.revokeObjectURL(
url
);
}
);

ڈاؤن لوڈ کرنے کے بعد، دوبارہ شروع کریں بٹن دبانے سے ایپلیکیشن ری سیٹ ہو جاتی ہے تاکہ یہ دوسری پی ڈی ایف پر کارروائی کر سکے۔

آئیے اپ لوڈ سے ڈاؤن لوڈ تک پورے ورک فلو پر ایک نظر ڈالتے ہیں۔
مرحلہ 1: پی ڈی ایف اپ لوڈ کریں۔
صارفین پی ڈی ایف کو اپ لوڈ ایریا میں گھسیٹ سکتے ہیں یا پی ڈی ایف منتخب کریں۔.
براؤزر دستاویز کو پڑھتا ہے اور اسے مقامی پروسیسنگ کے لیے تیار کرتا ہے۔

مرحلہ 2: دستاویز کا پیش نظارہ اور دریافت کریں۔
اپ لوڈ کرنے کے بعد، موجودہ صفحہ PDF پیش نظارہ میں ظاہر ہوگا۔
پچھلے اور اگلے کنٹرولز صارفین کو متعدد صفحات پر مشتمل دستاویزات کو نیویگیٹ کرنے اور وہ صفحہ تلاش کرنے کی اجازت دیتے ہیں جہاں انہیں عناصر شامل کرنے کی ضرورت ہے۔

مرحلہ 3: منتخب کریں کہ کیا شامل کرنا ہے۔
صارفین مندرجہ ذیل میں سے ایک کو منتخب کرتے ہیں: دستخط اور ٹیکسٹ/سٹیمپ.
اس سے یہ طے ہوتا ہے کہ ایڈیٹر میں کون سے تخلیق کنٹرولز ظاہر ہوتے ہیں۔

مرحلہ 4: ایک دستخط بنائیں
اگر آپ دستخط کو منتخب کرتے ہیں، تو صارف منتخب کر سکتے ہیں: ڈرا, زمرہیا اپ لوڈ کریں.
ڈرائنگ براہ راست دستخطی کینوس میں کام کرتی ہے۔ ٹائپ آپشن آپ کے داخل کردہ متن سے دستخطی طرز کا عنصر بناتا ہے، جبکہ اپ لوڈ ایک موجودہ دستخطی تصویر کو قبول کرتا ہے۔

مرحلہ 5: حسب ضرورت متن یا پہلے سے سیٹ اسٹامپ شامل کریں۔
دستخط کرنے کے بجائے، صارف منتخب کر سکتے ہیں: ٹیکسٹ/سٹیمپ.
آپ حسب ضرورت مواد درج کر سکتے ہیں یا ایک پیش سیٹ منتخب کر سکتے ہیں، جیسے: منظور شدہ, خفیہ, مسودہیا ادا کیا.

مرحلہ 6: جگہ اور طرز کے عناصر
تیار کردہ عناصر پی ڈی ایف پیش نظارہ کے اوپر ظاہر ہوں گے۔
صارف اسے مطلوبہ پوزیشن پر گھسیٹ کر سائز، گردش، دھندلاپن، X پوزیشن، Y پوزیشن وغیرہ جیسی خصوصیات کو ایڈجسٹ کر سکتے ہیں۔
متن کے عناصر قابل ترتیب فونٹ سائز اور رنگوں کی بھی حمایت کرتے ہیں۔

مرحلہ 7: ہدف کا صفحہ منتخب کریں۔
عناصر کو موجودہ صفحہ، تمام صفحات، یا صفحات کے مخصوص انتخاب پر لاگو کیا جا سکتا ہے۔
مثال کے طور پر:
1, 3-5, 10

جب آپ کو ایک سے زیادہ صفحات پر ایک ہی ڈاک ٹکٹ یا دستاویز کا لیبل ظاہر کرنے کی ضرورت ہو تو یہ مفید ہے۔
مرحلہ 8: لاگو کریں اور ختم کریں۔
عنصر اور ہدف کا صفحہ چیک کریں اور پھر کلک کریں۔ درخواست اور تکمیل.
براؤزر پیش نظارہ مقام کو پی ڈی ایف کوآرڈینیٹ میں تبدیل کرتا ہے اور ایک ترمیم شدہ دستاویز تیار کرتا ہے۔

مرحلہ 9: مکمل شدہ پی ڈی ایف کا جائزہ لیں۔
تیار کردہ دستاویز حتمی پیش نظارہ میں ظاہر ہوگی۔
صارف صفحہ کو براؤز کر سکتے ہیں اور تصدیق کر سکتے ہیں کہ دستخط، متن، یا ڈاک ٹکٹ ڈاؤن لوڈ کرنے سے پہلے صحیح طور پر ظاہر ہو رہے ہیں۔

مرحلہ 10: نام تبدیل کریں اور ڈاؤن لوڈ کریں۔
فائنل سیکشن صارفین کو آؤٹ پٹ فائل کا نام تبدیل کرنے اور صفحات کی کل تعداد اور فائل کے سائز کا جائزہ لینے کی اجازت دیتا ہے۔
کلک کریں ڈاؤن لوڈ تیار کردہ پی ڈی ایف کو مقامی طور پر محفوظ کریں۔

آب و ہوا، دوبارہ شروع کریں سیشن کو صاف کریں اور اپ لوڈ انٹرفیس پر واپس جائیں۔
دستخط کی شفافیت کو سنبھالنا
اپ لوڈ کردہ دستخط اکثر اس وقت بہترین دیکھے جاتے ہیں جب پس منظر شفاف ہو۔
شفاف PNGs میں دستخط کے صرف نظر آنے والے اسٹروک ہوتے ہیں، لہذا اصل PDF مواد دستخط کے ارد گرد نظر آتا ہے۔
اس کے مقابلے میں، JPEG تصاویر میں عام طور پر ٹھوس رنگ کا پس منظر ہوتا ہے۔ اگر آپ کی تصویر کو سفید کاغذ سے اسکین کیا گیا تھا، تو اسے رنگین پی ڈی ایف ایریا پر رکھنے سے ایک نمایاں سفید مستطیل بن سکتا ہے۔
لہذا، اپ لوڈ کردہ دستخطوں کے لیے، شفاف PNG فائلیں عام طور پر ایک بہتر آپشن ہوتی ہیں۔
تیار کردہ یا ٹائپ شدہ دستخطوں پر بھی یہی اصول لاگو ہوتے ہیں۔ کینوس کو PNG میں تبدیل کرتے وقت، کینوس کو پس منظر کے رنگ سے نہ بھریں جب تک کہ آپ کو جان بوجھ کر پس منظر کی ضرورت نہ ہو۔
const signatureImage =
signatureCanvas.toDataURL(
"image/png"
);
اس کے بعد آپ شفاف کینوس کو براہ راست اپنے پی ڈی ایف میں ایمبیڈ کر سکتے ہیں۔
اہم نوٹس اور عام غلطیاں
ایک عام غلطی یہ سمجھنا ہے کہ براؤزر کا پیش نظارہ اور اصل پی ڈی ایف ایک ہی نقاط کا استعمال کرتے ہیں۔
حتمی عنصر رکھنے سے پہلے ہمیشہ کینوس کے سائز اور ہدف کے پی ڈی ایف صفحہ کے درمیان تعلق کا حساب لگائیں۔
const scaleX =
pdfWidth /
pdfCanvas.width;
const scaleY =
pdfHeight /
pdfCanvas.height;
مختلف سائز کے صفحات پر ایک ہی عنصر کو لاگو کرتے وقت ایک اور مسئلہ پیدا ہوتا ہے۔ A4 صفحہ پر درست نظر آنے والی پوزیشن زمین کی تزئین کے صفحے پر یا مختلف سائز کے صفحات پر ایک ہی بصری پوزیشن میں ظاہر نہیں ہوسکتی ہے۔
پروسیسنگ سے پہلے اپ لوڈ کردہ دستخطی تصاویر کی بھی تصدیق ہونی چاہیے۔
const allowedTypes = [
"image/png",
"image/jpeg"
];
if (
!allowedTypes.includes(
file.type
)
) {
alert(
"Please upload a PNG or JPEG image."
);
return;
}
حتمی پی ڈی ایف سائز کو غیر ضروری طور پر بڑھانے سے بچنے کے لیے، آپ کو بہت بڑی تصویری فائلوں کو شامل کرنے سے پہلے ان کا سائز تبدیل کرنا چاہیے۔
صارفین کو ڈاؤن لوڈ کرنے سے پہلے مکمل شدہ دستاویز کا بھی جائزہ لینا چاہیے۔ گھماؤ، اسکیلنگ، یا کوآرڈینیٹ ترجمے کی غلطیوں کو حتمی پیش نظارہ میں شناخت کرنا اس سے کہیں زیادہ آسان ہوتا ہے جب فائل پہلے ہی شیئر کر دی گئی ہو۔
آخر میں، اس منصوبے بصری الیکٹرانک دستخط پی ڈی ایف میں۔ ہم سرٹیفکیٹ پر مبنی کرپٹوگرافک ڈیجیٹل دستخط تیار نہیں کرتے ہیں یا خودکار شناخت کی تصدیق فراہم نہیں کرتے ہیں۔
نتیجہ
اس ٹیوٹوریل میں، آپ نے جاوا اسکرپٹ کا استعمال کرتے ہوئے براؤزر پر مبنی پی ڈی ایف سائننگ ٹول بنایا ہے۔
آپ نے پی ڈی ایف دستاویز کو اپ لوڈ اور پیش نظارہ کرنے کا طریقہ سیکھا، صفحات کے درمیان نیویگیٹ کرنا، تصویر کھینچنا، ٹائپ یا اپ لوڈ کرکے دستخط بنانا، حسب ضرورت ٹیکسٹ اور پیش سیٹ اسٹامپ شامل کرنا، پی ڈی ایف پیش نظارہ کے اوپر براہ راست عناصر کی پوزیشن، ظاہری شکل کو ایڈجسٹ کرنا، ہدف کا صفحہ منتخب کرنا، اور PDF-lib کا استعمال کرتے ہوئے ایک مکمل دستاویز بنانا۔
آپ نے یہ بھی سیکھا کہ براؤزر کے نقاط کو پی ڈی ایف کوآرڈینیٹ میں کیسے تبدیل کیا جاتا ہے اور دستاویزات میں تصاویر کو شامل کرتے وقت دستخط کی شفافیت کیوں ضروری ہے۔
حتمی ورک فلو صارفین کو تیار شدہ پی ڈی ایف کا جائزہ لینے، آؤٹ پٹ فائل کا نام تبدیل کرنے، صفحہ کی گنتی اور سائز کا جائزہ لینے اور اسے براہ راست براؤزر سے ڈاؤن لوڈ کرنے کی اجازت دیتا ہے۔
آپ ہمارے پی ڈی ایف سائننگ ٹول کا استعمال کرتے ہوئے پورے ورک فلو کو دریافت کر سکتے ہیں۔
آپ اپنے پراجیکٹس کو فی صفحہ متعدد عناصر، دوبارہ قابل استعمال دستخطی پروفائلز، تاریخ کے قطعات، ابتدائیہ، حسب ضرورت فونٹس، حتمی شکل دینے سے پہلے دستخطوں کو ہٹانے، یا سرٹیفکیٹ پر مبنی ڈیجیٹل دستخطوں کے ساتھ ایک سرشار دستخطی انفراسٹرکچر کے ساتھ مزید بڑھا سکتے ہیں۔