Use our free professional certificate design tool is optimized for both desktop and mobile devices, ensuring a smooth experience regardless of your device.
🎓 Certificate Maker
Professional Certificate Design System, Print Quality
✖
0 / 130
Long press to save the image
Or copy the image and paste it into any application
`); } finally { hideLoading(); } }, 500); }// --- Other Functions (Unchanged) --- document.getElementById('inpLogo').addEventListener('change', function(e) { const file = e.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = function(event) { const img = new Image(); img.onload = function() { logoImage = img; document.querySelector('.upload-btn').textContent = "✅ Logo Selected"; document.getElementById('btnRemoveLogo').style.display = "inline"; drawCert(); } img.src = event.target.result; } reader.readAsDataURL(file); } });document.getElementById('btnRemoveLogo').addEventListener('click', function() { logoImage = null; document.getElementById('inpLogo').value = ""; document.querySelector('.upload-btn').textContent = "📂 Choose Logo Image"; this.style.display = "none"; drawCert(); });// --- Other Drawing Functions (Unchanged) --- function drawCert() { // ... (Same drawing code as before) ... const w = canvas.width; const h = canvas.height; const theme = state.colors[state.colorTheme];// Background const grad = ctx.createLinearGradient(0, 0, w, h); grad.addColorStop(0, theme.main); grad.addColorStop(1, theme.grad); ctx.fillStyle = grad; ctx.fillRect(0, 0, w, h);// Frame ctx.strokeStyle = theme.accent; ctx.lineWidth = 25; ctx.strokeRect(40, 40, w - 80, h - 80);ctx.strokeStyle = "#fff"; ctx.lineWidth = 5; ctx.strokeRect(75, 75, w - 150, h - 150);// Corners drawCorner(80, 80, 0); drawCorner(w - 80, 80, Math.PI / 2); drawCorner(w - 80, h - 80, Math.PI); drawCorner(80, h - 80, -Math.PI / 2);// Content ctx.textAlign = 'center';// Draw logo let titleY = 320; if (logoImage) { const logoSize = 180; ctx.save(); ctx.beginPath(); ctx.arc(w/2, 170, logoSize/2, 0, Math.PI*2); ctx.closePath(); ctx.clip(); ctx.drawImage(logoImage, w/2 - logoSize/2, 170 - logoSize/2, logoSize, logoSize); ctx.restore(); titleY = 380; }// Title ctx.fillStyle = theme.accent; ctx.font = '900 120px "Cairo"'; let titleText = 'Certificate of Excellence'; if(state.template === 'thanks') titleText = 'Certificate of Appreciation'; if(state.template === 'training') titleText = 'Certificate of Completion';ctx.shadowColor = "rgba(0,0,0,0.3)"; ctx.shadowBlur = 15; ctx.fillText(titleText, w/2, titleY); ctx.shadowBlur = 0;// Divider line ctx.beginPath(); ctx.moveTo(w/2 - 200, titleY + 40); ctx.lineTo(w/2 + 200, titleY + 40); ctx.lineWidth = 5; ctx.strokeStyle = theme.accent; ctx.stroke();// "This certificate is awarded to" ctx.fillStyle = '#fff'; ctx.font = '400 55px "Amiri"'; ctx.fillText('This certificate is awarded to', w/2, titleY + 140);// Name const name = document.getElementById('inpName').value || 'Name will appear here'; ctx.fillStyle = theme.accent; ctx.font = '700 100px "Amiri"'; ctx.fillText(name, w/2, titleY + 260);// Reason const reason = document.getElementById('inpReason').value; ctx.fillStyle = '#f1f5f9'; ctx.font = '400 50px "Amiri"'; wrapText(ctx, reason, w/2, titleY + 380, w - 400, 75);// Bottom part const bottomY = 1150;// Draw seal drawSeal(w/2, bottomY - 50, theme.accent);const dateVal = new Date(document.getElementById('inpDate').value); const dateStr = formatDateWithLatinNumbers(dateVal);ctx.fillStyle = '#fff';// Date ctx.font = 'bold 35px "Cairo"'; ctx.fillText('Date', w/4, bottomY + 20); ctx.font = '35px "Amiri"'; ctx.fillText(dateStr, w/4, bottomY + 80);// Signature const manager = document.getElementById('inpManager').value || 'Manager'; ctx.font = 'bold 35px "Cairo"'; ctx.fillText('Manager Signature', 3*w/4, bottomY + 20);ctx.font = 'bold 45px "Amiri"'; ctx.fillStyle = theme.accent; ctx.fillText(manager, 3*w/4, bottomY + 90);// Signature line ctx.beginPath(); ctx.moveTo(3*w/4 - 120, bottomY + 110); ctx.lineTo(3*w/4 + 120, bottomY + 110); ctx.lineWidth = 3; ctx.strokeStyle = "#fff"; ctx.stroke(); }function drawCorner(x, y, rotation) { ctx.save(); ctx.translate(x, y); ctx.rotate(rotation); ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(100, 0); ctx.lineTo(100, 20); ctx.lineTo(20, 20); ctx.lineTo(20, 100); ctx.lineTo(0, 100); ctx.closePath(); ctx.fillStyle = state.colors[state.colorTheme].accent; ctx.fill(); ctx.restore(); }function drawSeal(x, y, color) { ctx.save(); ctx.translate(x, y);ctx.beginPath(); for(let i = 0; i < 30; i++) { const angle = (i / 30) * Math.PI * 2; const r = i % 2 === 0 ? 85 : 75; ctx.lineTo(Math.cos(angle) * r, Math.sin(angle) * r); } ctx.closePath(); ctx.fillStyle = color; ctx.fill();ctx.beginPath(); ctx.arc(0, 0, 65, 0, Math.PI*2); ctx.strokeStyle = state.colors[state.colorTheme].main; ctx.lineWidth = 3; ctx.stroke();ctx.fillStyle = state.colors[state.colorTheme].main; const org = document.getElementById('inpOrg').value || 'Certified';let fontSize = 22; ctx.font = `bold ${fontSize}px "Cairo"`; while (ctx.measureText(org).width > 100 && fontSize > 10) { fontSize--; ctx.font = `bold ${fontSize}px "Cairo"`; }ctx.fillText(org, 0, 8); ctx.restore(); }function wrapText(context, text, x, y, maxWidth, lineHeight) { const words = text.split(' '); let line = ''; if(words.length === 1 && words[0] === '') return;for(let n = 0; n < words.length; n++) { const testLine = line + words[n] + ' '; const metrics = context.measureText(testLine); const testWidth = metrics.width; if (testWidth > maxWidth && n > 0) { context.fillText(line, x, y); line = words[n] + ' '; y += lineHeight; } else { line = testLine; } } context.fillText(line, x, y); }function formatDateWithLatinNumbers(date) { const months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ];const day = date.getDate(); const month = months[date.getMonth()]; const year = date.getFullYear();const latinDay = convertToLatinNumbers(day.toString()); const latinYear = convertToLatinNumbers(year.toString());return `${latinDay} ${month} ${latinYear}`; }function convertToLatinNumbers(arabicNumber) { const arabicDigits = '٠١٢٣٤٥٥٦٧٨٩'; const latinDigits = '0123456789'; let result = '';for (let i = 0; i < arabicNumber.length; i++) { const arabicDigit = arabicNumber[i]; const index = arabicDigits.indexOf(arabicDigit); if (index !== -1) { result += latinDigits[index]; } else { result += arabicDigit; } }return result; }