mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
fix(producer): fetch missing font weights from Google Fonts at render time
The deterministic font system now supplements its embedded font bundle with Google Fonts fetches for any weights not in the pre-bundled set. This fixes compositions that request font weights (e.g. Montserrat 300) not included in the CANONICAL_FONTS faces array — previously those weights were silently dropped, causing invisible text in renders. Also replaces caption-glitch-rgb and caption-weight-shift with improved versions from avatar preview compositions, adapted to 1920x1080 with standard demo transcript.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@200;300;400;500;600;700;800;900&display=swap"
|
||||
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
@@ -59,7 +59,7 @@
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 1400px;
|
||||
height: 260px;
|
||||
height: 278px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -70,7 +70,7 @@
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 1400px;
|
||||
height: 260px;
|
||||
height: 278px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -100,7 +100,7 @@
|
||||
white-space: nowrap;
|
||||
color: #ffffff;
|
||||
font-family: "Montserrat", Arial, sans-serif;
|
||||
font-weight: 200;
|
||||
font-weight: 300;
|
||||
font-size: 72px;
|
||||
letter-spacing: -0.03em;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||
@@ -142,10 +142,10 @@
|
||||
var WORD_SPACING = 12;
|
||||
var PAUSE_THRESHOLD = 0.1;
|
||||
var ENTRY_DURATION = 100 / 1000;
|
||||
var WEIGHT_TRANSITION = 250 / 1000;
|
||||
var WEIGHT_TRANSITION = 100 / 1000;
|
||||
var FONT_WIDTH_SAFETY = 1.14;
|
||||
var FONT_WEIGHT_LIGHT = 200;
|
||||
var FONT_WEIGHT_BOLD = 900;
|
||||
var FONT_WEIGHT_LIGHT = 300;
|
||||
var FONT_WEIGHT_BOLD = 700;
|
||||
|
||||
var TRANSCRIPT = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
@@ -224,7 +224,7 @@
|
||||
}
|
||||
|
||||
function splitLines(words) {
|
||||
if (measureLineWidth(words) <= MAX_LINE_WIDTH) {
|
||||
if (words.length < 2) {
|
||||
return [{ words: words, startIndex: 0 }];
|
||||
}
|
||||
var bestSplit = Math.ceil(words.length / 2);
|
||||
@@ -248,6 +248,35 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
function avoidSingleWordGroups(groups) {
|
||||
var out = [];
|
||||
groups.forEach(function (group) {
|
||||
if (
|
||||
group.words.length === 1 &&
|
||||
out.length > 0 &&
|
||||
out[out.length - 1].words.length < MAX_WORDS_PER_GROUP
|
||||
) {
|
||||
out[out.length - 1] = makeGroup(out[out.length - 1].words.concat(group.words));
|
||||
} else {
|
||||
out.push(group);
|
||||
}
|
||||
});
|
||||
|
||||
for (var i = 0; i < out.length; i++) {
|
||||
if (out[i].words.length !== 1) continue;
|
||||
if (i + 1 < out.length && out[i + 1].words.length < MAX_WORDS_PER_GROUP) {
|
||||
out[i] = makeGroup(out[i].words.concat(out[i + 1].words));
|
||||
out.splice(i + 1, 1);
|
||||
} else if (i > 0 && out[i - 1].words.length < MAX_WORDS_PER_GROUP) {
|
||||
out[i - 1] = makeGroup(out[i - 1].words.concat(out[i].words));
|
||||
out.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
function makeGroups(words) {
|
||||
var groups = [];
|
||||
var current = [];
|
||||
@@ -273,7 +302,7 @@
|
||||
}
|
||||
});
|
||||
if (current.length) groups.push(makeGroup(current));
|
||||
return groups;
|
||||
return avoidSingleWordGroups(groups);
|
||||
}
|
||||
|
||||
function makeGroup(words) {
|
||||
@@ -309,17 +338,12 @@
|
||||
var lineEl = document.createElement("div");
|
||||
lineEl.className = "caption-line";
|
||||
lineEl.id = "caption-group-" + groupIndex + "-line-" + lineIndex;
|
||||
lineEl.style.fontWeight = FONT_WEIGHT_LIGHT;
|
||||
lineEl.style.fontWeight = lineIndex === 0 ? FONT_WEIGHT_BOLD : FONT_WEIGHT_LIGHT;
|
||||
lineEl.style.fontSize = computedSize + "px";
|
||||
line.words.forEach(function (word, wordIndex) {
|
||||
var wordEl = document.createElement("span");
|
||||
wordEl.id = "cw-" + groupIndex + "-" + lineIndex + "-" + wordIndex;
|
||||
wordEl.textContent = word.text.toLowerCase();
|
||||
wordEl.style.fontWeight = FONT_WEIGHT_LIGHT;
|
||||
wordEl.style.display = "inline-block";
|
||||
wordEl.style.transition = "none";
|
||||
wordEl.dataset.start = word.start;
|
||||
wordEl.dataset.end = word.end;
|
||||
lineEl.appendChild(wordEl);
|
||||
});
|
||||
copyEl.appendChild(lineEl);
|
||||
@@ -363,24 +387,23 @@
|
||||
visibleStart,
|
||||
);
|
||||
|
||||
group.lines.forEach(function (line, lineIndex) {
|
||||
line.words.forEach(function (word, wordIndex) {
|
||||
var wEl = document.getElementById(
|
||||
"cw-" + groupIndex + "-" + lineIndex + "-" + wordIndex,
|
||||
);
|
||||
if (!wEl) return;
|
||||
tl.to(
|
||||
wEl,
|
||||
{ fontWeight: FONT_WEIGHT_BOLD, duration: WEIGHT_TRANSITION, ease: "power2.out" },
|
||||
word.start,
|
||||
);
|
||||
tl.to(
|
||||
wEl,
|
||||
{ fontWeight: FONT_WEIGHT_LIGHT, duration: WEIGHT_TRANSITION, ease: "power2.in" },
|
||||
word.end,
|
||||
);
|
||||
});
|
||||
});
|
||||
if (group.lines.length === 2) {
|
||||
var line1El = document.getElementById("caption-group-" + groupIndex + "-line-0");
|
||||
var line2El = document.getElementById("caption-group-" + groupIndex + "-line-1");
|
||||
var line2FirstWord = group.lines[1].words[0];
|
||||
var switchTime = line2FirstWord.start;
|
||||
|
||||
tl.to(
|
||||
line1El,
|
||||
{ fontWeight: FONT_WEIGHT_LIGHT, duration: WEIGHT_TRANSITION, ease: "power2.out" },
|
||||
switchTime,
|
||||
);
|
||||
tl.to(
|
||||
line2El,
|
||||
{ fontWeight: FONT_WEIGHT_BOLD, duration: WEIGHT_TRANSITION, ease: "power2.out" },
|
||||
switchTime,
|
||||
);
|
||||
}
|
||||
|
||||
tl.set(groupEl, { opacity: 0 }, visibleEnd);
|
||||
});
|
||||
|
||||
+56
-33
@@ -7,7 +7,7 @@
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@200;300;400;500;600;700;800;900&display=swap"
|
||||
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
@@ -59,7 +59,7 @@
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 1400px;
|
||||
height: 260px;
|
||||
height: 278px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -70,7 +70,7 @@
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 1400px;
|
||||
height: 260px;
|
||||
height: 278px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -100,7 +100,7 @@
|
||||
white-space: nowrap;
|
||||
color: #ffffff;
|
||||
font-family: "Montserrat", Arial, sans-serif;
|
||||
font-weight: 200;
|
||||
font-weight: 300;
|
||||
font-size: 72px;
|
||||
letter-spacing: -0.03em;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||
@@ -142,10 +142,10 @@
|
||||
var WORD_SPACING = 12;
|
||||
var PAUSE_THRESHOLD = 0.1;
|
||||
var ENTRY_DURATION = 100 / 1000;
|
||||
var WEIGHT_TRANSITION = 250 / 1000;
|
||||
var WEIGHT_TRANSITION = 100 / 1000;
|
||||
var FONT_WIDTH_SAFETY = 1.14;
|
||||
var FONT_WEIGHT_LIGHT = 200;
|
||||
var FONT_WEIGHT_BOLD = 900;
|
||||
var FONT_WEIGHT_LIGHT = 300;
|
||||
var FONT_WEIGHT_BOLD = 700;
|
||||
|
||||
var TRANSCRIPT = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
@@ -224,7 +224,7 @@
|
||||
}
|
||||
|
||||
function splitLines(words) {
|
||||
if (measureLineWidth(words) <= MAX_LINE_WIDTH) {
|
||||
if (words.length < 2) {
|
||||
return [{ words: words, startIndex: 0 }];
|
||||
}
|
||||
var bestSplit = Math.ceil(words.length / 2);
|
||||
@@ -248,6 +248,35 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
function avoidSingleWordGroups(groups) {
|
||||
var out = [];
|
||||
groups.forEach(function (group) {
|
||||
if (
|
||||
group.words.length === 1 &&
|
||||
out.length > 0 &&
|
||||
out[out.length - 1].words.length < MAX_WORDS_PER_GROUP
|
||||
) {
|
||||
out[out.length - 1] = makeGroup(out[out.length - 1].words.concat(group.words));
|
||||
} else {
|
||||
out.push(group);
|
||||
}
|
||||
});
|
||||
|
||||
for (var i = 0; i < out.length; i++) {
|
||||
if (out[i].words.length !== 1) continue;
|
||||
if (i + 1 < out.length && out[i + 1].words.length < MAX_WORDS_PER_GROUP) {
|
||||
out[i] = makeGroup(out[i].words.concat(out[i + 1].words));
|
||||
out.splice(i + 1, 1);
|
||||
} else if (i > 0 && out[i - 1].words.length < MAX_WORDS_PER_GROUP) {
|
||||
out[i - 1] = makeGroup(out[i - 1].words.concat(out[i].words));
|
||||
out.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
function makeGroups(words) {
|
||||
var groups = [];
|
||||
var current = [];
|
||||
@@ -273,7 +302,7 @@
|
||||
}
|
||||
});
|
||||
if (current.length) groups.push(makeGroup(current));
|
||||
return groups;
|
||||
return avoidSingleWordGroups(groups);
|
||||
}
|
||||
|
||||
function makeGroup(words) {
|
||||
@@ -309,17 +338,12 @@
|
||||
var lineEl = document.createElement("div");
|
||||
lineEl.className = "caption-line";
|
||||
lineEl.id = "caption-group-" + groupIndex + "-line-" + lineIndex;
|
||||
lineEl.style.fontWeight = FONT_WEIGHT_LIGHT;
|
||||
lineEl.style.fontWeight = lineIndex === 0 ? FONT_WEIGHT_BOLD : FONT_WEIGHT_LIGHT;
|
||||
lineEl.style.fontSize = computedSize + "px";
|
||||
line.words.forEach(function (word, wordIndex) {
|
||||
var wordEl = document.createElement("span");
|
||||
wordEl.id = "cw-" + groupIndex + "-" + lineIndex + "-" + wordIndex;
|
||||
wordEl.textContent = word.text.toLowerCase();
|
||||
wordEl.style.fontWeight = FONT_WEIGHT_LIGHT;
|
||||
wordEl.style.display = "inline-block";
|
||||
wordEl.style.transition = "none";
|
||||
wordEl.dataset.start = word.start;
|
||||
wordEl.dataset.end = word.end;
|
||||
lineEl.appendChild(wordEl);
|
||||
});
|
||||
copyEl.appendChild(lineEl);
|
||||
@@ -363,24 +387,23 @@
|
||||
visibleStart,
|
||||
);
|
||||
|
||||
group.lines.forEach(function (line, lineIndex) {
|
||||
line.words.forEach(function (word, wordIndex) {
|
||||
var wEl = document.getElementById(
|
||||
"cw-" + groupIndex + "-" + lineIndex + "-" + wordIndex,
|
||||
);
|
||||
if (!wEl) return;
|
||||
tl.to(
|
||||
wEl,
|
||||
{ fontWeight: FONT_WEIGHT_BOLD, duration: WEIGHT_TRANSITION, ease: "power2.out" },
|
||||
word.start,
|
||||
);
|
||||
tl.to(
|
||||
wEl,
|
||||
{ fontWeight: FONT_WEIGHT_LIGHT, duration: WEIGHT_TRANSITION, ease: "power2.in" },
|
||||
word.end,
|
||||
);
|
||||
});
|
||||
});
|
||||
if (group.lines.length === 2) {
|
||||
var line1El = document.getElementById("caption-group-" + groupIndex + "-line-0");
|
||||
var line2El = document.getElementById("caption-group-" + groupIndex + "-line-1");
|
||||
var line2FirstWord = group.lines[1].words[0];
|
||||
var switchTime = line2FirstWord.start;
|
||||
|
||||
tl.to(
|
||||
line1El,
|
||||
{ fontWeight: FONT_WEIGHT_LIGHT, duration: WEIGHT_TRANSITION, ease: "power2.out" },
|
||||
switchTime,
|
||||
);
|
||||
tl.to(
|
||||
line2El,
|
||||
{ fontWeight: FONT_WEIGHT_BOLD, duration: WEIGHT_TRANSITION, ease: "power2.out" },
|
||||
switchTime,
|
||||
);
|
||||
}
|
||||
|
||||
tl.set(groupEl, { opacity: 0 }, visibleEnd);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user