()
| 92 | } |
| 93 | |
| 94 | const generateCertificateImage = async (): Promise<void> => { |
| 95 | try { |
| 96 | const offscreenCanvas = document.createElement('canvas'); |
| 97 | const ctx = offscreenCanvas.getContext('2d'); |
| 98 | |
| 99 | const certificateImage = new Image(); |
| 100 | certificateImage.src = '/certificate.png'; |
| 101 | |
| 102 | await new Promise((resolve, reject) => { |
| 103 | certificateImage.onload = resolve; |
| 104 | certificateImage.onerror = reject; |
| 105 | }); |
| 106 | |
| 107 | offscreenCanvas.width = certificateImage.width; |
| 108 | offscreenCanvas.height = certificateImage.height; |
| 109 | |
| 110 | const recipientName = capitalizeFirstLetter(userName); |
| 111 | |
| 112 | if (!ctx) { |
| 113 | throw new Error('Error creating off-screen canvas context'); |
| 114 | } |
| 115 | |
| 116 | ctx.drawImage(certificateImage, 0, 0); |
| 117 | |
| 118 | ctx.font = '85px "Brush Script MT", cursive '; // Changed to font |
| 119 | ctx.fillStyle = 'black'; |
| 120 | const textWidth = ctx.measureText(recipientName).width; |
| 121 | const xRecipient = (offscreenCanvas.width - textWidth) / 2; |
| 122 | const yRecipient = offscreenCanvas.height * 0.54; |
| 123 | ctx.fillText(recipientName, xRecipient, yRecipient); |
| 124 | |
| 125 | const certificatDescription = 35; |
| 126 | ctx.font = `${certificatDescription}px Helvetica`; |
| 127 | const certificatDescriptionText = `has successfully completed ${certificateDetails.course.title} Full Stack Web Development Course`; |
| 128 | |
| 129 | const descriptionWidth = ctx.measureText(certificatDescriptionText).width; |
| 130 | const xDescription = (offscreenCanvas.width - descriptionWidth) / 2; |
| 131 | const yDescription = offscreenCanvas.height * 0.62; |
| 132 | |
| 133 | ctx.fillText(certificatDescriptionText, xDescription, yDescription); |
| 134 | |
| 135 | const certificateNumberFontSize = 35; |
| 136 | ctx.font = `${certificateNumberFontSize}px Helvetica`; |
| 137 | const certificateNumberText = `Certificate No: ${certificateDetails.certificateSlug}`; |
| 138 | ctx.fillText( |
| 139 | certificateNumberText, |
| 140 | offscreenCanvas.width * 0.35 + 510, |
| 141 | offscreenCanvas.height * 0.77, |
| 142 | ); |
| 143 | |
| 144 | // Add download date |
| 145 | const downloadDateText = ` ${new Date().toLocaleDateString()}`; |
| 146 | ctx.font = `${certificateNumberFontSize / 1}px Helvetica`; |
| 147 | ctx.fillText( |
| 148 | downloadDateText, |
| 149 | offscreenCanvas.width * 0.18 + 20, |
| 150 | offscreenCanvas.height * 0.94, |
| 151 | ); |
no test coverage detected