- 在 index.html:47-51 给 main 和左侧面板增加 min-h-0,允许网格子项在父级 flex 容器中释放高度,确保

#chat-history 的 overflow-y-auto 生效;右侧展示区同样设置 min-h-0,防止 SVG 区域被异常拉伸。
  - 调整后,长对话会保持面板固定高度,滚动条承载多余内容,不再把整个页面撑出视窗。
This commit is contained in:
史悦
2025-10-27 09:42:16 +08:00
parent b0c487a4ef
commit 4b14bb26dd
3 changed files with 39 additions and 12 deletions

View File

@@ -2,6 +2,15 @@ body {
font-family: 'Inter', sans-serif; font-family: 'Inter', sans-serif;
} }
/* 统一处理 Iconify 图标的对齐方式,避免在按钮与文字中出现垂直偏移 */
iconify-icon {
display: inline-flex;
align-items: center;
justify-content: center;
vertical-align: middle;
line-height: 1;
}
/* 狂野线条效果 */ /* 狂野线条效果 */
.wild-border { .wild-border {
border: 3px solid; border: 3px solid;
@@ -223,9 +232,22 @@ body {
transition: color 0.2s ease; transition: color 0.2s ease;
} }
.svg-placeholder-block {
position: relative;
}
@keyframes svg-active-pulse {
0% { box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.35), 0 6px 12px rgba(15, 23, 42, 0.15); }
50% { box-shadow: 0 0 0 6px rgba(37, 99, 235, 0.15), 0 10px 18px rgba(15, 23, 42, 0.2); }
100% { box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.35), 0 6px 12px rgba(15, 23, 42, 0.15); }
}
.svg-placeholder-active { .svg-placeholder-active {
border-color: #2563eb; border-color: #1d4ed8;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2); background: linear-gradient(135deg, #e0f2fe 0%, #dbeafe 100%);
color: #1e3a8a;
transform: translateY(-2px);
/* animation: svg-active-pulse 1.6s ease-in-out infinite; */
} }
.svg-content-wrapper { .svg-content-wrapper {

View File

@@ -25,6 +25,7 @@
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<!-- API配置按钮 --> <!-- API配置按钮 -->
<button id="settings-btn" class="settings-btn bg-white/20 text-white p-2 border-2 border-white hover:bg-white/30 transition-all" title="API配置"> <button id="settings-btn" class="settings-btn bg-white/20 text-white p-2 border-2 border-white hover:bg-white/30 transition-all" title="API配置">
API配置
<iconify-icon icon="ph:gear-six-fill" class="text-2xl"></iconify-icon> <iconify-icon icon="ph:gear-six-fill" class="text-2xl"></iconify-icon>
</button> </button>
@@ -43,10 +44,10 @@
</header> </header>
<!-- 主内容区 --> <!-- 主内容区 -->
<main class="flex-1 grid grid-cols-1 md:grid-cols-3 gap-4 p-4 overflow-hidden"> <main class="flex-1 min-h-0 grid grid-cols-1 md:grid-cols-3 gap-4 p-4 overflow-hidden">
<!-- 左侧对话面板 --> <!-- 左侧对话面板 -->
<div class="md:col-span-1 bg-white wild-border border-cyan-500 flex flex-col"> <div class="md:col-span-1 bg-white wild-border border-cyan-500 flex flex-col min-h-0">
<!-- 对话历史顶部栏 --> <!-- 对话历史顶部栏 -->
<div class="p-3 border-b-3 border-gray-300 bg-gradient-to-r from-cyan-500 to-blue-500 flex items-center justify-between"> <div class="p-3 border-b-3 border-gray-300 bg-gradient-to-r from-cyan-500 to-blue-500 flex items-center justify-between">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
@@ -85,7 +86,7 @@
</div> </div>
<!-- 右侧显示面板 --> <!-- 右侧显示面板 -->
<div class="md:col-span-2 bg-white wild-border border-purple-600 flex flex-col"> <div class="md:col-span-2 bg-white wild-border border-purple-600 flex flex-col min-h-0">
<div id="svg-viewer" class="flex-1 flex items-center justify-center p-4 bg-gradient-to-br from-purple-50 to-pink-50 overflow-auto"> <div id="svg-viewer" class="flex-1 flex items-center justify-center p-4 bg-gradient-to-br from-purple-50 to-pink-50 overflow-auto">
<div id="svg-placeholder" class="text-center text-gray-400"> <div id="svg-placeholder" class="text-center text-gray-400">
<iconify-icon icon="ph:image-square" class="text-6xl mx-auto text-purple-400"></iconify-icon> <iconify-icon icon="ph:image-square" class="text-6xl mx-auto text-purple-400"></iconify-icon>

View File

@@ -26,6 +26,8 @@ class ProductCanvasApp {
this.pendingSvgId = null; this.pendingSvgId = null;
this.pendingCancel = false; this.pendingCancel = false;
this.copyClipboardSupported = typeof ClipboardItem !== 'undefined' && !!navigator.clipboard; this.copyClipboardSupported = typeof ClipboardItem !== 'undefined' && !!navigator.clipboard;
const deviceScale = typeof window !== 'undefined' ? (window.devicePixelRatio || 1) : 1;
this.imageExportScale = Math.min(4, Math.max(2, deviceScale));
this.initElements(); this.initElements();
this.initEventListeners(); this.initEventListeners();
@@ -1214,7 +1216,7 @@ class ProductCanvasApp {
}); });
} }
async convertSvgToPngBlob(svgContent) { async convertSvgToPngBlob(svgContent, options = {}) {
const { width, height } = this.parseSvgDimensions(svgContent); const { width, height } = this.parseSvgDimensions(svgContent);
const svgBlob = new Blob([svgContent], { type: 'image/svg+xml' }); const svgBlob = new Blob([svgContent], { type: 'image/svg+xml' });
const url = URL.createObjectURL(svgBlob); const url = URL.createObjectURL(svgBlob);
@@ -1222,14 +1224,16 @@ class ProductCanvasApp {
try { try {
const img = await this.loadImageFromUrl(url); const img = await this.loadImageFromUrl(url);
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
const canvasWidth = Math.max(1, img.naturalWidth || width || 1024); const baseWidth = Math.max(1, img.naturalWidth || width || 1024);
const canvasHeight = Math.max(1, img.naturalHeight || height || 768); const baseHeight = Math.max(1, img.naturalHeight || height || 768);
canvas.width = canvasWidth; const preferredScale = options.scale || this.imageExportScale || 1;
canvas.height = canvasHeight; const exportScale = Math.min(4, Math.max(1, preferredScale));
canvas.width = Math.round(baseWidth * exportScale);
canvas.height = Math.round(baseHeight * exportScale);
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvasWidth, canvasHeight); ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0, canvasWidth, canvasHeight); ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
return await new Promise((resolve, reject) => { return await new Promise((resolve, reject) => {
canvas.toBlob((blob) => { canvas.toBlob((blob) => {