-
Notifications
You must be signed in to change notification settings - Fork 3
Scale certificate name to fit within available space #2687
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| - Scaling factor of 0.8 emulates browser print scaling and better reflect the screen design | ||
| */ | ||
| export const pxToPt = (px: number): number => { | ||
| return px * (72 / 96) * 0.8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can clarify the intent of the scaling factor 0.8 (which is fine) by naming it:
const PRINT_SCALING_FACTOR = 0.8;
return px * (72 / 96) * PRINT_SCALING_FACTOR;That way, future devs instantly know what it represents without reading the comment block.
| // For Neue Haas Grotesk at 52px, approximate average char width is ~60% of font size | ||
| const avgCharWidth = baseFontSize * 0.6 | ||
|
|
||
| const estimatedWidth = name.length * avgCharWidth |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If name is an empty string, estimatedWidth is 0, and scaleFactor stays 1.0. That’s fine — but you could explicitly handle it for clarity:
if (!name.trim()) return { fontSize: baseFontSize, top: baselineTop };right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll always have a name - not much point in setting a font size for printing nothing in any case.
| const estimatedWidth = name.length * avgCharWidth | ||
|
|
||
| let scaleFactor = 1.0 | ||
| if (estimatedWidth > maxWidth) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion:
Sometimes names are right at the edge of the maxWidth, so a tiny buffer (e.g. 95% of max width) ensures better visual balance: (I will reproduce it in local testing)
const effectiveMaxWidth = maxWidth * 0.95;
if (estimatedWidth > effectiveMaxWidth) {
scaleFactor = Math.max(0.35, effectiveMaxWidth / estimatedWidth);
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The max width already leaves some whitespace before the text overlays the badge, so we can render right up to it.
What are the relevant tickets?
Closes https://github.com/mitodl/hq/issues/8971
Description (What does it do?)
Certificate PDF page layouts are constrained by height and elements are positions absolute.
We can not wrap longer names to multiple lines without changing the layout to accommodate.
This change makes an estimation on the width of the rendered name based on character count and scales the font size to ensure it fits on one line.
Screenshots (if appropriate):
Normal case:

Scaling starts around 30+ characters:

Failure point around 98 characters (max scale down is 35%). The name below has 107 chars:

The MIT IS&T Data Warehouse FULL_NAME field can hold up to 90 characters: https://web.mit.edu/warehouse/metadata/fields/student_directory_full.html
From Sonnet 4.5:
Available data points
General population:
MIT context:
Realistic estimates for MIT
Given MIT's international population, a reasonable estimate:
How can this be tested?
If you have mitxonline running locally and certificates set up, navigate to http://open.odl.local:8062/certificate/<"course"|"program">/<certificate_id>/pdf
If not, grab a response from e.g. https://api.rc.mitxonline.mit.edu/api/v2/course_certificates/8a2ebafe-40b3-4178-8860-ea9bd063f3cd/ and return it in the certificateQueries.courseCertificatesRetrieve() hook queryFn and load http://open.odl.local:8062/certificate/course/8a2ebafe-40b3-4178-8860-ea9bd063f3cd/pdf.
Override the username with various value lengths and confirm the certificate displays as expected.