diff --git a/public/static/css/phone-image-templates.css b/public/static/css/phone-image-templates.css index c38047a..249016e 100644 --- a/public/static/css/phone-image-templates.css +++ b/public/static/css/phone-image-templates.css @@ -112,6 +112,7 @@ /* --- 封面页/首页 --- */ .page-cover { + --pi-font-scale: 1 !important; display: flex; flex-direction: column; justify-content: center; @@ -335,6 +336,7 @@ /* --- 总结页/尾页 --- */ .page-summary { + --pi-font-scale: 1 !important; display: flex; flex-direction: column; justify-content: center; @@ -417,6 +419,12 @@ justify-content: center; } +.page-body.valign-bottom .page-content { + display: flex; + flex-direction: column; + justify-content: flex-end; +} + /* ============================================ Content Flow (中间栏内容流) 所有元素按实际尺寸纵向排列 diff --git a/public/static/js/phone-image.js b/public/static/js/phone-image.js index 92fc3a7..514b149 100644 --- a/public/static/js/phone-image.js +++ b/public/static/js/phone-image.js @@ -897,7 +897,12 @@ var PhoneImageEngine = (function () { function generateContentPage(blocks, pageNum, sizeConfig, isLast) { // 读取逐页对齐配置 var alignment = (config.pageAlignments && config.pageAlignments[pageNum]) || 'top'; - var valignClass = alignment === 'center' ? ' valign-center' : ''; + var valignClass = ''; + if (alignment === 'center') { + valignClass = ' valign-center'; + } else if (alignment === 'bottom') { + valignClass = ' valign-bottom'; + } var html = '
'; @@ -1230,8 +1235,11 @@ var PhoneImageEngine = (function () { var pageNum = pages[i].pageNum || (i); var currentAlign = (config.pageAlignments && config.pageAlignments[pageNum]) || 'top'; var isActiveCenter = currentAlign === 'center'; - var $toggle = $(''); $item.append($toggle); } @@ -1580,6 +1588,26 @@ var PhoneImageEngine = (function () { return div.innerHTML; } + // ===== 对齐按钮事件委托 ===== + $(document).on('click', '.thumb-alignment-toggle', function () { + var $btn = $(this); + var pageNum = parseInt($btn.attr('data-page-num'), 10); + var currentAlign = (config.pageAlignments && config.pageAlignments[pageNum]) || 'top'; + + // 三态循环: top -> center -> bottom -> top + var nextAlign; + if (currentAlign === 'top') { + nextAlign = 'center'; + } else if (currentAlign === 'center') { + nextAlign = 'bottom'; + } else { + nextAlign = 'top'; + } + + setPageAlignment(pageNum, nextAlign); + render(); + }); + // ===== 公开API ===== return { init: init, diff --git a/view/admin/post/phone_image.html b/view/admin/post/phone_image.html index 1842f6c..5af8887 100644 --- a/view/admin/post/phone_image.html +++ b/view/admin/post/phone_image.html @@ -238,8 +238,17 @@ 渲染预览
字号 - + + 1.0x
@@ -420,27 +429,39 @@ // 初始同步预览区 PhoneImageEngine.syncPreview(); - // 字号倍数 Slider - var $slider = $('#font-scale-slider'); + // 字号倍数 Dropdown + 自定义输入 + var $scaleSelect = $('#font-scale-select'); + var $scaleCustom = $('#font-scale-custom'); var $scaleValue = $('#font-scale-value'); + var fontScalePresets = [0.5, 0.8, 1.0, 1.2, 1.5, 2.0]; - // 拖动中: 仅更新CSS变量和显示值,不触发html2canvas - $slider.on('input', function() { - var val = parseFloat($(this).val()); + function setFontScaleUI(val) { + var $select = $('#font-scale-select'); + var $custom = $('#font-scale-custom'); + if (fontScalePresets.indexOf(val) >= 0) { + $select.val(String(val)); + $custom.hide(); + } else { + $select.val('custom'); + $custom.val(val).show(); + } + $('#font-scale-value').text(parseFloat(val).toFixed(1) + 'x'); + } + + function applyFontScaleValue(val) { + val = Math.max(0.5, Math.min(2.0, parseFloat(val) || 1.0)); $scaleValue.text(val.toFixed(1) + 'x'); currentConfig.fontScale = val; document.getElementById('render-preview').style.setProperty('--pi-font-scale', val); var staging = document.getElementById('render-staging'); if (staging) staging.style.setProperty('--pi-font-scale', val); PhoneImageEngine.updateConfig({ fontScale: val }); - }); + } - // 松手后: 触发完整渲染(重新分页 + html2canvas截图) - $slider.on('change', function() { - var val = parseFloat($(this).val()); + function triggerFontScaleSave(val) { + val = parseFloat(val); PhoneImageLogPanel.log('字号调整为 ' + val.toFixed(1) + 'x', 'info'); doRender({ fontScale: val }); - // 触发保存,确保字号倍数持久化 updateSaveState('saving'); PhoneImageEngine.saveConfig(postData.postId, { size: currentConfig.size, @@ -455,12 +476,42 @@ PhoneImageLogPanel.log('字号保存失败: ' + err, 'error'); updateSaveState('error'); }); + } + + // 下拉选择: 预设值直接应用,自定义则显示输入框 + $scaleSelect.on('change', function() { + var selected = $(this).val(); + if (selected === 'custom') { + $scaleCustom.show().focus(); + } else { + $scaleCustom.hide(); + var val = parseFloat(selected); + applyFontScaleValue(val); + triggerFontScaleSave(val); + } }); - // 初始化时更新 Slider 显示值 + // 自定义输入: 实时预览 + $scaleCustom.on('input', function() { + var val = parseFloat($(this).val()); + if (!isNaN(val) && val >= 0.5 && val <= 2.0) { + applyFontScaleValue(val); + } + }); + + // 自定义输入: 失焦时触发保存 + $scaleCustom.on('change', function() { + var val = parseFloat($(this).val()); + if (isNaN(val) || val < 0.5) val = 0.5; + if (val > 2.0) val = 2.0; + $(this).val(val); + applyFontScaleValue(val); + triggerFontScaleSave(val); + }); + + // 初始化时更新字号显示值 if (initConfig.fontScale && initConfig.fontScale !== 1) { - $slider.val(initConfig.fontScale); - $scaleValue.text(parseFloat(initConfig.fontScale).toFixed(1) + 'x'); + setFontScaleUI(initConfig.fontScale); } // ========== 设置弹框 ========== @@ -734,8 +785,7 @@ if (cfg.watermark !== undefined) currentConfig.watermark = cfg.watermark; if (cfg.fontScale !== undefined) { currentConfig.fontScale = cfg.fontScale; - $slider.val(cfg.fontScale); - $scaleValue.text(parseFloat(cfg.fontScale).toFixed(1) + 'x'); + setFontScaleUI(cfg.fontScale); } lastOutputId = outputId;