feat: 模版标题字号根据文字长度动态计算

This commit is contained in:
li
2025-11-14 11:31:46 +08:00
parent 9c57af9aff
commit 4a558170ad

View File

@@ -59,13 +59,13 @@
top: calc(50% - 607px / 2 - 130px);
left: 50%;
transform: translateX(-50%);
max-width: 900px;
width: 900px;
text-align: center;
z-index: 2;
}
.video-title {
width: 900px;
text-align: center;
/* 初始字体大小JavaScript 会根据文本长度自动调整 */
font-size: 72px;
font-weight: 700;
color: #ffffff;
@@ -73,6 +73,10 @@
letter-spacing: 3px;
text-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
margin-bottom: 20px;
/* 确保文本不会溢出 */
word-wrap: break-word;
overflow-wrap: break-word;
white-space: nowrap;
}
/* 字幕区域 - 对齐视频底部 */
@@ -181,5 +185,144 @@
</div>
</div>
</div>
<script>
/**
* 根据文本宽度自动调整字体大小
* @param {HTMLElement} element - 要调整的元素
* @param {number} maxWidth - 最大宽度px
* @param {number} minFontSize - 最小字体大小px
* @param {number} maxFontSize - 最大字体大小px
*/
function autoFitFontSize(element, maxWidth, minFontSize, maxFontSize) {
try {
if (!element || !element.textContent || !element.textContent.trim()) {
return;
}
if (!document.body) {
return;
}
// 创建一个临时的测量元素
const measure = document.createElement('span');
measure.style.visibility = 'hidden';
measure.style.position = 'absolute';
measure.style.top = '-9999px';
measure.style.left = '-9999px';
measure.style.whiteSpace = 'nowrap';
// 复制元素的样式
const computedStyle = window.getComputedStyle(element);
measure.style.fontFamily = computedStyle.fontFamily;
measure.style.fontSize = computedStyle.fontSize;
measure.style.fontWeight = computedStyle.fontWeight;
measure.style.letterSpacing = computedStyle.letterSpacing;
measure.textContent = element.textContent;
document.body.appendChild(measure);
// 二分查找合适的字体大小
let low = minFontSize;
let high = maxFontSize;
let bestSize = maxFontSize;
// 先检查最大字体是否合适
measure.style.fontSize = maxFontSize + 'px';
if (measure.offsetWidth <= maxWidth) {
bestSize = maxFontSize;
} else {
// 使用二分查找
while (high - low > 0.5) {
const mid = (low + high) / 2;
measure.style.fontSize = mid + 'px';
if (measure.offsetWidth <= maxWidth) {
bestSize = mid;
low = mid;
} else {
high = mid;
}
}
}
// 应用找到的字体大小
element.style.fontSize = bestSize + 'px';
// 清理临时元素
if (measure.parentNode) {
document.body.removeChild(measure);
}
} catch (error) {
console.error('自动调整字体大小出错:', error);
}
}
// 页面加载完成后自动调整字体大小
function initAutoFit() {
try {
const titleElement = document.querySelector('.video-title');
if (titleElement) {
// 获取容器的实际宽度
const wrapper = document.querySelector('.video-title-wrapper');
const maxWidth = wrapper ? wrapper.offsetWidth : 900;
// 自动调整字体大小最小12px最大72px
autoFitFontSize(titleElement, maxWidth, 12, 72);
}
} catch (error) {
console.error('初始化自动调整字体大小出错:', error);
}
}
// 等待 DOM 加载完成
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initAutoFit);
} else {
// DOM 已经加载完成
initAutoFit();
}
// 如果内容是通过模板引擎动态插入的,可以监听内容变化
// 使用 MutationObserver 监听文本变化
if (typeof MutationObserver !== 'undefined') {
try {
const observer = new MutationObserver(function(mutations) {
let shouldUpdate = false;
mutations.forEach(function(mutation) {
if (mutation.type === 'childList' || mutation.type === 'characterData') {
shouldUpdate = true;
}
});
if (shouldUpdate) {
// 延迟执行,避免频繁调用
setTimeout(initAutoFit, 100);
}
});
// 等待 body 元素存在后再观察
if (document.body) {
observer.observe(document.body, {
childList: true,
subtree: true,
characterData: true
});
} else {
document.addEventListener('DOMContentLoaded', function() {
if (document.body) {
observer.observe(document.body, {
childList: true,
subtree: true,
characterData: true
});
}
});
}
} catch (error) {
console.error('设置 MutationObserver 出错:', error);
}
}
</script>
</body>
</html>