diff --git a/frontend/index.html b/frontend/index.html
index f6bf2d6..dfb2d60 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -83,16 +83,16 @@
字幕容器 (container)
-
+
-
- 85%
+
+ 0%
-
+
@@ -124,7 +124,7 @@
-
+
@@ -165,7 +165,7 @@
-
+
@@ -206,7 +206,7 @@
-
+
@@ -247,7 +247,7 @@
-
+
diff --git a/frontend/scripts/main.js b/frontend/scripts/main.js
index edfea53..b00b1c2 100644
--- a/frontend/scripts/main.js
+++ b/frontend/scripts/main.js
@@ -391,13 +391,14 @@ function applyCaptionStyle() {
return;
}
- captionContainer.style.backgroundColor = hexToRgba(
- elements.containerBgColor.value,
- elements.containerBgOpacity.value / 100
- );
- captionContainer.style.borderColor = elements.containerBorderColor.value;
- captionContainer.style.borderRadius = `${elements.containerBorderRadius.value}px`;
- captionContainer.style.padding = `${elements.containerPadding.value}px`;
+ const containerStyles = {
+ backgroundColor: hexToRgba(elements.containerBgColor.value, elements.containerBgOpacity.value / 100),
+ borderColor: elements.containerBorderColor.value,
+ borderRadius: `${elements.containerBorderRadius.value}px`,
+ padding: `${elements.containerPadding.value}px`
+ };
+
+ Object.assign(captionContainer.style, containerStyles);
const tipEl = captionContainer.querySelector('.layout-hub-tip');
if (tipEl) {
@@ -405,10 +406,7 @@ function applyCaptionStyle() {
tipEl.style.fontWeight = elements.tipFontWeight.value;
tipEl.style.color = elements.tipColor.value;
tipEl.style.lineHeight = elements.tipLineHeight.value;
- tipEl.style.backgroundColor = hexToRgba(
- elements.tipBgColor.value,
- elements.tipBgOpacity.value / 100
- );
+ tipEl.style.backgroundColor = hexToRgba(elements.tipBgColor.value, elements.tipBgOpacity.value / 100);
tipEl.style.borderRadius = `${elements.tipBorderRadius.value}px`;
tipEl.style.padding = `${elements.tipPadding.value}px`;
}
@@ -419,10 +417,7 @@ function applyCaptionStyle() {
item.style.fontWeight = elements.messageFontWeight.value;
item.style.color = elements.messageColor.value;
item.style.lineHeight = elements.messageLineHeight.value;
- item.style.backgroundColor = hexToRgba(
- elements.messageBgColor.value,
- elements.messageBgOpacity.value / 100
- );
+ item.style.backgroundColor = hexToRgba(elements.messageBgColor.value, elements.messageBgOpacity.value / 100);
item.style.borderRadius = `${elements.messageBorderRadius.value}px`;
item.style.padding = `${elements.messagePadding.value}px`;
});
@@ -433,10 +428,7 @@ function applyCaptionStyle() {
hotTitleEl.style.fontWeight = elements.hotTitleFontWeight.value;
hotTitleEl.style.color = elements.hotTitleColor.value;
hotTitleEl.style.lineHeight = elements.hotTitleLineHeight.value;
- hotTitleEl.style.backgroundColor = hexToRgba(
- elements.hotTitleBgColor.value,
- elements.hotTitleBgOpacity.value / 100
- );
+ hotTitleEl.style.backgroundColor = hexToRgba(elements.hotTitleBgColor.value, elements.hotTitleBgOpacity.value / 100);
hotTitleEl.style.borderRadius = `${elements.hotTitleBorderRadius.value}px`;
hotTitleEl.style.padding = `${elements.hotTitlePadding.value}px`;
}
@@ -447,10 +439,7 @@ function applyCaptionStyle() {
hotIssuesEl.style.fontWeight = elements.hotIssuesFontWeight.value;
hotIssuesEl.style.color = elements.hotIssuesColor.value;
hotIssuesEl.style.lineHeight = elements.hotIssuesLineHeight.value;
- hotIssuesEl.style.backgroundColor = hexToRgba(
- elements.hotIssuesBgColor.value,
- elements.hotIssuesBgOpacity.value / 100
- );
+ hotIssuesEl.style.backgroundColor = hexToRgba(elements.hotIssuesBgColor.value, elements.hotIssuesBgOpacity.value / 100);
hotIssuesEl.style.borderRadius = `${elements.hotIssuesBorderRadius.value}px`;
hotIssuesEl.style.padding = `${elements.hotIssuesPadding.value}px`;
}
@@ -458,6 +447,153 @@ function applyCaptionStyle() {
logger.info('字幕样式已应用');
}
+function updateSingleStyle(inputId) {
+ const captionContainer = document.querySelector('.caption-container-hub');
+ if (!captionContainer) return;
+
+ const updateMap = {
+ containerBgColor: () => {
+ captionContainer.style.backgroundColor = hexToRgba(elements.containerBgColor.value, elements.containerBgOpacity.value / 100);
+ },
+ containerBgOpacity: () => {
+ captionContainer.style.backgroundColor = hexToRgba(elements.containerBgColor.value, elements.containerBgOpacity.value / 100);
+ },
+ containerBorderColor: () => {
+ captionContainer.style.borderColor = elements.containerBorderColor.value;
+ },
+ containerBorderRadius: () => {
+ captionContainer.style.borderRadius = `${elements.containerBorderRadius.value}px`;
+ },
+ containerPadding: () => {
+ captionContainer.style.padding = `${elements.containerPadding.value}px`;
+ },
+ tipFontSize: () => {
+ const el = captionContainer.querySelector('.layout-hub-tip');
+ if (el) el.style.fontSize = `${elements.tipFontSize.value}px`;
+ },
+ tipFontWeight: () => {
+ const el = captionContainer.querySelector('.layout-hub-tip');
+ if (el) el.style.fontWeight = elements.tipFontWeight.value;
+ },
+ tipColor: () => {
+ const el = captionContainer.querySelector('.layout-hub-tip');
+ if (el) el.style.color = elements.tipColor.value;
+ },
+ tipLineHeight: () => {
+ const el = captionContainer.querySelector('.layout-hub-tip');
+ if (el) el.style.lineHeight = elements.tipLineHeight.value;
+ },
+ tipBgColor: () => {
+ const el = captionContainer.querySelector('.layout-hub-tip');
+ if (el) el.style.backgroundColor = hexToRgba(elements.tipBgColor.value, elements.tipBgOpacity.value / 100);
+ },
+ tipBgOpacity: () => {
+ const el = captionContainer.querySelector('.layout-hub-tip');
+ if (el) el.style.backgroundColor = hexToRgba(elements.tipBgColor.value, elements.tipBgOpacity.value / 100);
+ },
+ tipBorderRadius: () => {
+ const el = captionContainer.querySelector('.layout-hub-tip');
+ if (el) el.style.borderRadius = `${elements.tipBorderRadius.value}px`;
+ },
+ tipPadding: () => {
+ const el = captionContainer.querySelector('.layout-hub-tip');
+ if (el) el.style.padding = `${elements.tipPadding.value}px`;
+ },
+ messageFontSize: () => {
+ captionContainer.querySelectorAll('.message-item .item-content').forEach(el => el.style.fontSize = `${elements.messageFontSize.value}px`);
+ },
+ messageFontWeight: () => {
+ captionContainer.querySelectorAll('.message-item .item-content').forEach(el => el.style.fontWeight = elements.messageFontWeight.value);
+ },
+ messageColor: () => {
+ captionContainer.querySelectorAll('.message-item .item-content').forEach(el => el.style.color = elements.messageColor.value);
+ },
+ messageLineHeight: () => {
+ captionContainer.querySelectorAll('.message-item .item-content').forEach(el => el.style.lineHeight = elements.messageLineHeight.value);
+ },
+ messageBgColor: () => {
+ captionContainer.querySelectorAll('.message-item .item-content').forEach(el => el.style.backgroundColor = hexToRgba(elements.messageBgColor.value, elements.messageBgOpacity.value / 100));
+ },
+ messageBgOpacity: () => {
+ captionContainer.querySelectorAll('.message-item .item-content').forEach(el => el.style.backgroundColor = hexToRgba(elements.messageBgColor.value, elements.messageBgOpacity.value / 100));
+ },
+ messageBorderRadius: () => {
+ captionContainer.querySelectorAll('.message-item .item-content').forEach(el => el.style.borderRadius = `${elements.messageBorderRadius.value}px`);
+ },
+ messagePadding: () => {
+ captionContainer.querySelectorAll('.message-item .item-content').forEach(el => el.style.padding = `${elements.messagePadding.value}px`);
+ },
+ hotTitleFontSize: () => {
+ const el = captionContainer.querySelector('.layout-hub-hot-title');
+ if (el) el.style.fontSize = `${elements.hotTitleFontSize.value}px`;
+ },
+ hotTitleFontWeight: () => {
+ const el = captionContainer.querySelector('.layout-hub-hot-title');
+ if (el) el.style.fontWeight = elements.hotTitleFontWeight.value;
+ },
+ hotTitleColor: () => {
+ const el = captionContainer.querySelector('.layout-hub-hot-title');
+ if (el) el.style.color = elements.hotTitleColor.value;
+ },
+ hotTitleLineHeight: () => {
+ const el = captionContainer.querySelector('.layout-hub-hot-title');
+ if (el) el.style.lineHeight = elements.hotTitleLineHeight.value;
+ },
+ hotTitleBgColor: () => {
+ const el = captionContainer.querySelector('.layout-hub-hot-title');
+ if (el) el.style.backgroundColor = hexToRgba(elements.hotTitleBgColor.value, elements.hotTitleBgOpacity.value / 100);
+ },
+ hotTitleBgOpacity: () => {
+ const el = captionContainer.querySelector('.layout-hub-hot-title');
+ if (el) el.style.backgroundColor = hexToRgba(elements.hotTitleBgColor.value, elements.hotTitleBgOpacity.value / 100);
+ },
+ hotTitleBorderRadius: () => {
+ const el = captionContainer.querySelector('.layout-hub-hot-title');
+ if (el) el.style.borderRadius = `${elements.hotTitleBorderRadius.value}px`;
+ },
+ hotTitlePadding: () => {
+ const el = captionContainer.querySelector('.layout-hub-hot-title');
+ if (el) el.style.padding = `${elements.hotTitlePadding.value}px`;
+ },
+ hotIssuesFontSize: () => {
+ const el = captionContainer.querySelector('.layout-hub-hot-issues');
+ if (el) el.style.fontSize = `${elements.hotIssuesFontSize.value}px`;
+ },
+ hotIssuesFontWeight: () => {
+ const el = captionContainer.querySelector('.layout-hub-hot-issues');
+ if (el) el.style.fontWeight = elements.hotIssuesFontWeight.value;
+ },
+ hotIssuesColor: () => {
+ const el = captionContainer.querySelector('.layout-hub-hot-issues');
+ if (el) el.style.color = elements.hotIssuesColor.value;
+ },
+ hotIssuesLineHeight: () => {
+ const el = captionContainer.querySelector('.layout-hub-hot-issues');
+ if (el) el.style.lineHeight = elements.hotIssuesLineHeight.value;
+ },
+ hotIssuesBgColor: () => {
+ const el = captionContainer.querySelector('.layout-hub-hot-issues');
+ if (el) el.style.backgroundColor = hexToRgba(elements.hotIssuesBgColor.value, elements.hotIssuesBgOpacity.value / 100);
+ },
+ hotIssuesBgOpacity: () => {
+ const el = captionContainer.querySelector('.layout-hub-hot-issues');
+ if (el) el.style.backgroundColor = hexToRgba(elements.hotIssuesBgColor.value, elements.hotIssuesBgOpacity.value / 100);
+ },
+ hotIssuesBorderRadius: () => {
+ const el = captionContainer.querySelector('.layout-hub-hot-issues');
+ if (el) el.style.borderRadius = `${elements.hotIssuesBorderRadius.value}px`;
+ },
+ hotIssuesPadding: () => {
+ const el = captionContainer.querySelector('.layout-hub-hot-issues');
+ if (el) el.style.padding = `${elements.hotIssuesPadding.value}px`;
+ }
+ };
+
+ if (updateMap[inputId]) {
+ updateMap[inputId]();
+ }
+}
+
function hexToRgba(hex, alpha) {
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
@@ -475,23 +611,32 @@ function loadCaptionStyleFromContainer() {
const containerRadius = containerStyles.borderRadius;
const containerPad = containerStyles.padding;
- if (containerBg && containerBg !== 'transparent') {
+ if (containerBg) {
const rgbaMatch = containerBg.match(/rgba?\((\d+),\s*(\d+),\s*(\d+),?\s*([\d.]*)\)/);
if (rgbaMatch) {
elements.containerBgColor.value = rgbToHex(parseInt(rgbaMatch[1]), parseInt(rgbaMatch[2]), parseInt(rgbaMatch[3]));
- elements.containerBgOpacity.value = rgbaMatch[4] ? Math.round(parseFloat(rgbaMatch[4]) * 100) : 100;
+ if (rgbaMatch[4]) {
+ elements.containerBgOpacity.value = Math.round(parseFloat(rgbaMatch[4]) * 100);
+ }
+ } else if (containerBg === 'transparent' || containerBg === 'rgba(0, 0, 0, 0)') {
+ elements.containerBgColor.value = '#000000';
+ elements.containerBgOpacity.value = 0;
}
}
- if (containerBorder && containerBorder !== 'transparent' && containerBorder !== 'rgba(0, 0, 0, 0)') {
+ if (containerBorder) {
const rgbaMatch = containerBorder.match(/rgba?\((\d+),\s*(\d+),\s*(\d+),?\s*([\d.]*)\)/);
if (rgbaMatch) {
elements.containerBorderColor.value = rgbToHex(parseInt(rgbaMatch[1]), parseInt(rgbaMatch[2]), parseInt(rgbaMatch[3]));
}
}
- elements.containerBorderRadius.value = parseInt(containerRadius) || 8;
- elements.containerPadding.value = parseInt(containerPad) || 10;
+ if (containerRadius) {
+ elements.containerBorderRadius.value = parseInt(containerRadius) || 8;
+ }
+ if (containerPad) {
+ elements.containerPadding.value = parseInt(containerPad) || 10;
+ }
updateRangeValue(elements.containerBgOpacity);
@@ -504,39 +649,66 @@ function loadCaptionStyleFromContainer() {
sections.forEach(section => {
const el = captionContainer.querySelector(section.selector);
- if (!el) return;
+ if (!el) {
+ logger.warn(`loadCaptionStyleFromContainer: 元素 ${section.selector} 未找到`);
+ return;
+ }
const styles = window.getComputedStyle(el);
- section.elements.fontSize.value = parseInt(styles.fontSize) || 14;
- section.elements.fontWeight.value = styles.fontWeight === 'bold' ? 'bold' : 'normal';
- section.elements.color.value = parseColor(styles.color);
- section.elements.lineHeight.value = parseFloat(styles.lineHeight) || 1.5;
- if (styles.backgroundColor && styles.backgroundColor !== 'transparent') {
- const rgbaMatch = styles.backgroundColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+),?\s*([\d.]*)\)/);
- if (rgbaMatch) {
- section.elements.bgColor.value = rgbToHex(parseInt(rgbaMatch[1]), parseInt(rgbaMatch[2]), parseInt(rgbaMatch[3]));
- section.elements.bgOpacity.value = rgbaMatch[4] ? Math.round(parseFloat(rgbaMatch[4]) * 100) : 100;
+ if (styles.fontSize) {
+ section.elements.fontSize.value = parseInt(styles.fontSize) || 14;
+ }
+ if (styles.fontWeight) {
+ section.elements.fontWeight.value = styles.fontWeight === 'bold' || styles.fontWeight === '700' ? 'bold' : 'normal';
+ }
+ if (styles.color) {
+ const parsedColor = parseColor(styles.color);
+ if (parsedColor) {
+ section.elements.color.value = parsedColor;
}
}
- section.elements.borderRadius.value = parseInt(styles.borderRadius) || 4;
- section.elements.padding.value = parseInt(styles.padding) || 6;
+ if (styles.backgroundColor && styles.backgroundColor !== 'transparent' && styles.backgroundColor !== 'rgba(0, 0, 0, 0)') {
+ const rgbaMatch = styles.backgroundColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+),?\s*([\d.]*)\)/);
+ if (rgbaMatch) {
+ section.elements.bgColor.value = rgbToHex(parseInt(rgbaMatch[1]), parseInt(rgbaMatch[2]), parseInt(rgbaMatch[3]));
+ if (rgbaMatch[4]) {
+ section.elements.bgOpacity.value = Math.round(parseFloat(rgbaMatch[4]) * 100);
+ }
+ }
+ }
- updateRangeValue(section.elements.bgOpacity);
+ if (styles.borderRadius) {
+ section.elements.borderRadius.value = parseInt(styles.borderRadius) || 4;
+ }
+ if (styles.padding) {
+ section.elements.padding.value = parseInt(styles.padding) || 6;
+ }
+
+ if (section.elements.bgOpacity) {
+ updateRangeValue(section.elements.bgOpacity);
+ }
});
logger.info('已从字幕容器加载样式');
}
function parseColor(colorStr) {
- if (!colorStr) return '#ffffff';
+ if (!colorStr) return null;
if (colorStr.startsWith('#')) return colorStr;
+
+ const rgbMatch = colorStr.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
+ if (rgbMatch) {
+ return rgbToHex(parseInt(rgbMatch[1]), parseInt(rgbMatch[2]), parseInt(rgbMatch[3]));
+ }
+
const rgbaMatch = colorStr.match(/rgba?\((\d+),\s*(\d+),\s*(\d+),?\s*([\d.]*)\)/);
if (rgbaMatch) {
return rgbToHex(parseInt(rgbaMatch[1]), parseInt(rgbaMatch[2]), parseInt(rgbaMatch[3]));
}
- return '#ffffff';
+
+ return null;
}
function rgbToHex(r, g, b) {
@@ -657,6 +829,9 @@ function initCaptionDragAndResize(container) {
logger.info('字幕容器拖拽和缩放已启用');
}
+let captionStyleObserver = null;
+let captionStyleApplied = false;
+
function watchCaptionContainer() {
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
@@ -670,6 +845,11 @@ function watchCaptionContainer() {
captionContainer.style.zIndex = '9999';
initCaptionDragAndResize(captionContainer);
loadCaptionStyleFromContainer();
+ if (captionStyleApplied) {
+ setTimeout(applyCaptionStyle, 100);
+ }
+ } else if (captionContainer && captionStyleApplied) {
+ setTimeout(applyCaptionStyle, 100);
}
}
}
@@ -687,6 +867,30 @@ function watchCaptionContainer() {
logger.info('已启动字幕容器监听');
}
+function watchCaptionContentChanges() {
+ const captionContainer = document.querySelector('.caption-container-hub');
+ if (!captionContainer) return;
+
+ if (captionStyleObserver) {
+ captionStyleObserver.disconnect();
+ }
+
+ captionStyleObserver = new MutationObserver(() => {
+ if (captionStyleApplied) {
+ setTimeout(applyCaptionStyle, 50);
+ }
+ });
+
+ captionStyleObserver.observe(captionContainer, {
+ childList: true,
+ subtree: true,
+ attributes: true,
+ attributeFilter: ['style', 'class']
+ });
+
+ logger.info('已启动字幕内容变化监听');
+}
+
function calculateScale() {
const container = elements.digitalHumanBox;
const sdkContainer = container.querySelector('.digital-intelligent-interaction');
@@ -741,7 +945,11 @@ function bindEvents() {
elements.initBtn.addEventListener('click', initializeSDK);
elements.destroyBtn.addEventListener('click', destroySDK);
elements.getOnceCodeBtn.addEventListener('click', handleGetOnceCode);
- elements.applyCaptionStyleBtn.addEventListener('click', applyCaptionStyle);
+ elements.applyCaptionStyleBtn.addEventListener('click', () => {
+ applyCaptionStyle();
+ captionStyleApplied = true;
+ watchCaptionContentChanges();
+ });
document.querySelectorAll('input[type="range"]').forEach(slider => {
slider.addEventListener('input', (e) => {
@@ -749,6 +957,22 @@ function bindEvents() {
if (valueSpan && valueSpan.classList.contains('range-value')) {
valueSpan.textContent = `${e.target.value}%`;
}
+ updateSingleStyle(e.target.id);
+ captionStyleApplied = true;
+ watchCaptionContentChanges();
+ });
+ });
+
+ document.querySelectorAll('#captionPanel input[type="number"], #captionPanel input[type="color"], #captionPanel select').forEach(input => {
+ input.addEventListener('input', (e) => {
+ updateSingleStyle(e.target.id);
+ captionStyleApplied = true;
+ watchCaptionContentChanges();
+ });
+ input.addEventListener('change', (e) => {
+ updateSingleStyle(e.target.id);
+ captionStyleApplied = true;
+ watchCaptionContentChanges();
});
});
diff --git a/frontend/styles/main.css b/frontend/styles/main.css
index 822b701..b942449 100644
--- a/frontend/styles/main.css
+++ b/frontend/styles/main.css
@@ -636,36 +636,36 @@ body {
/* ===== 覆盖 SDK 字体大小 ===== */
.digital-intelligent-interaction {
- font-size: 14px !important;
+ font-size: 14px;
}
.digital-intelligent-interaction .ai-chat-btn .ai-chat-btn-content {
- font-size: 16px !important;
+ font-size: 16px;
}
.digital-intelligent-interaction .message-item .rich-text-card .content {
- font-size: 16px !important;
- line-height: 24px !important;
+ font-size: 16px;
+ line-height: 24px;
}
.digital-intelligent-interaction .stop-chat-btn.normal .stop-chat-btn-content {
- font-size: 16px !important;
+ font-size: 16px;
}
.digital-intelligent-interaction .toast-container .toast-content .toast-text {
- font-size: 12px !important;
+ font-size: 12px;
}
.digital-intelligent-interaction .layout-hub-tip {
- font-size: 16px !important;
+ font-size: 16px;
}
.digital-intelligent-interaction .layout-hub-hot-title {
- font-size: 16px !important;
+ font-size: 16px;
}
.digital-intelligent-interaction .layout-hub-hot-issues {
- font-size: 16px !important;
+ font-size: 16px;
}
/* ===== 滚动条样式 ===== */