diff --git a/js/script.js b/js/script.js index 3ce160b..c743362 100644 --- a/js/script.js +++ b/js/script.js @@ -1972,24 +1972,56 @@ } } - // 生成画布(固定分辨率 1080×1920 高清无损) + // 生成画布(高清无损,根据背景图分辨率自适应) async function generateCanvas() { const canvas = exportCanvas; const ctx = canvas.getContext('2d'); const container = imageContainer; - // 高清分辨率 1080×1920 - const TARGET_WIDTH = 1080; - const TARGET_HEIGHT = 1920; + // 基础分辨率 1080×1920 + const BASE_WIDTH = 1080; + const BASE_HEIGHT = 1920; + + // 根据背景图原始分辨率调整目标分辨率 + let TARGET_WIDTH = BASE_WIDTH; + let TARGET_HEIGHT = BASE_HEIGHT; + + if (currentImage) { + const imgWidth = currentImage.naturalWidth; + const imgHeight = currentImage.naturalHeight; + console.log('背景图原始尺寸:', imgWidth, 'x', imgHeight); + + // 如果背景图分辨率高于基础分辨率,使用背景图分辨率 + // 但不超过 4K (2160×3840) 以避免文件过大 + const MAX_WIDTH = 2160; + const MAX_HEIGHT = 3840; + + if (imgWidth >= BASE_WIDTH && imgHeight >= BASE_HEIGHT) { + // 使用背景图分辨率,但保持 9:16 比例 + const imgRatio = imgWidth / imgHeight; + const targetRatio = BASE_WIDTH / BASE_HEIGHT; + + if (imgRatio > targetRatio) { + // 图片更宽,以高度为基准 + TARGET_HEIGHT = Math.min(imgHeight, MAX_HEIGHT); + TARGET_WIDTH = Math.round(TARGET_HEIGHT * targetRatio); + } else { + // 图片更高或比例相同,以宽度为基准 + TARGET_WIDTH = Math.min(imgWidth, MAX_WIDTH); + TARGET_HEIGHT = Math.round(TARGET_WIDTH / targetRatio); + } + } + } + + console.log('最终画布尺寸:', TARGET_WIDTH, 'x', TARGET_HEIGHT); // 显示尺寸(用于计算缩放比例) const displayWidth = container.clientWidth; const displayHeight = container.clientHeight; - // 设置画布为固定高清分辨率 + // 设置画布为高清分辨率 canvas.width = TARGET_WIDTH; canvas.height = TARGET_HEIGHT; - console.log('设置画布尺寸:', canvas.width, 'x', canvas.height); // 启用最高质量渲染 ctx.imageSmoothingEnabled = true; @@ -2056,7 +2088,7 @@ const containerHeight = canvasHeight; const imgRatio = img.naturalWidth / img.naturalHeight; const containerRatio = containerWidth / containerHeight; - + let imgWidth, imgHeight; if (imgRatio > containerRatio) { @@ -2162,18 +2194,23 @@ ctx.globalAlpha = overlayEl.style.opacity || 1; - const img = new Image(); - img.crossOrigin = 'anonymous'; - img.onload = () => { - ctx.drawImage(img, left, top, width, height); + // 直接使用已加载的图片元素,避免重新加载导致质量下降 + if (imgEl.complete && imgEl.naturalWidth > 0) { + ctx.drawImage(imgEl, left, top, width, height); ctx.globalAlpha = 1; checkComplete(); - }; - img.onerror = () => { - ctx.globalAlpha = 1; - checkComplete(); - }; - img.src = imgEl.src; + } else { + // 如果图片未加载完成,等待加载 + imgEl.onload = () => { + ctx.drawImage(imgEl, left, top, width, height); + ctx.globalAlpha = 1; + checkComplete(); + }; + imgEl.onerror = () => { + ctx.globalAlpha = 1; + checkComplete(); + }; + } }); }); }