mirror of
https://gitee.com/ulthon/ulthon_information.git
synced 2026-07-09 03:32:48 +08:00
feat(typesetting): Wave 2 - 流式渲染、表格字号独立控制、作者声明
- 缩略图改为流式渲染,截图一页即显示一页 - 新增tableFontScale独立控制表格字号,含后端持久化 - 内容页顶部添加作者声明(文/作者名),空值隐藏
This commit is contained in:
@@ -99,7 +99,8 @@ var PhoneImageEngine = (function () {
|
||||
douyin: { width: 540, height: 960 }
|
||||
},
|
||||
contentPadding: 20,
|
||||
fontScale: 1
|
||||
fontScale: 1,
|
||||
tableFontScale: 1
|
||||
};
|
||||
|
||||
// ===== 文章数据 =====
|
||||
@@ -159,10 +160,17 @@ var PhoneImageEngine = (function () {
|
||||
*/
|
||||
function applyFontScale() {
|
||||
var scale = config.fontScale || 1;
|
||||
var tableScale = config.tableFontScale || 1;
|
||||
var preview = document.getElementById('render-preview');
|
||||
if (preview) preview.style.setProperty('--pi-font-scale', scale);
|
||||
if (preview) {
|
||||
preview.style.setProperty('--pi-font-scale', scale);
|
||||
preview.style.setProperty('--pi-table-font-scale', tableScale);
|
||||
}
|
||||
var staging = document.getElementById('render-staging');
|
||||
if (staging) staging.style.setProperty('--pi-font-scale', scale);
|
||||
if (staging) {
|
||||
staging.style.setProperty('--pi-font-scale', scale);
|
||||
staging.style.setProperty('--pi-table-font-scale', tableScale);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -914,6 +922,11 @@ var PhoneImageEngine = (function () {
|
||||
html += '</div>';
|
||||
}
|
||||
|
||||
// 作者声明(所有内容页)
|
||||
if (postData.author_name) {
|
||||
html += '<div class="author-credit">文/' + escapeHtml(postData.author_name) + '</div>';
|
||||
}
|
||||
|
||||
// 正文内容区
|
||||
html += '<div class="page-content">';
|
||||
for (var i = 0; i < blocks.length; i++) {
|
||||
@@ -1125,17 +1138,19 @@ var PhoneImageEngine = (function () {
|
||||
// 保存模式: 高质量绘制原图到canvas
|
||||
renderPureImageToCanvas(pureSrc, opts.sizeConfig.width, opts.sizeConfig.height).then(function (canvas) {
|
||||
results.push(canvas);
|
||||
if (opts.streaming && opts.onPageReady) opts.onPageReady(canvas, idx);
|
||||
if (pageProgressCallback) pageProgressCallback(idx + 1, total);
|
||||
idx++;
|
||||
captureNext();
|
||||
}).catch(function () {
|
||||
// 加载失败,回退到html2canvas
|
||||
capturePageViaHtml2Canvas($elem, $staging, opts, results, deferred, function () { if (pageProgressCallback) pageProgressCallback(idx + 1, total); idx++; captureNext(); });
|
||||
capturePageViaHtml2Canvas($elem, $staging, opts, results, deferred, function () { if (opts.streaming && opts.onPageReady) opts.onPageReady(results[results.length - 1], idx); if (pageProgressCallback) pageProgressCallback(idx + 1, total); idx++; captureNext(); });
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
// 缩略图模式: 直接用src
|
||||
results.push(pureSrc);
|
||||
if (opts.streaming && opts.onPageReady) opts.onPageReady(pureSrc, idx);
|
||||
if (pageProgressCallback) pageProgressCallback(idx + 1, total);
|
||||
idx++;
|
||||
captureNext();
|
||||
@@ -1144,7 +1159,7 @@ var PhoneImageEngine = (function () {
|
||||
}
|
||||
}
|
||||
|
||||
capturePageViaHtml2Canvas($elem, $staging, opts, results, deferred, function () { idx++; captureNext(); });
|
||||
capturePageViaHtml2Canvas($elem, $staging, opts, results, deferred, function () { if (opts.streaming && opts.onPageReady) opts.onPageReady(results[results.length - 1], idx); idx++; captureNext(); });
|
||||
}
|
||||
|
||||
captureNext();
|
||||
@@ -1183,15 +1198,22 @@ var PhoneImageEngine = (function () {
|
||||
function renderThumbnails(sizeConfig) {
|
||||
var deferred = $.Deferred();
|
||||
|
||||
// 流式渲染:先清空容器,再逐页追加缩略图
|
||||
initThumbnails(sizeConfig);
|
||||
|
||||
doCapturePages({
|
||||
scale: 1,
|
||||
outputCanvas: false,
|
||||
quality: 0.85,
|
||||
sizeConfig: sizeConfig
|
||||
sizeConfig: sizeConfig,
|
||||
streaming: true,
|
||||
onPageReady: function (dataUrl, pageIndex) {
|
||||
appendThumbnail(dataUrl, pageIndex, sizeConfig, pages[pageIndex]);
|
||||
}
|
||||
}, function (current, total) {
|
||||
PhoneImageLogPanel.log('截图: 第 ' + current + '/' + total + ' 页', 'info');
|
||||
}).then(function (dataUrls) {
|
||||
displayThumbnails(dataUrls, sizeConfig);
|
||||
updateThumbnailPageNumbers(dataUrls.length);
|
||||
deferred.resolve(pages);
|
||||
}).catch(function (err) {
|
||||
deferred.reject(err);
|
||||
@@ -1201,51 +1223,69 @@ var PhoneImageEngine = (function () {
|
||||
}
|
||||
|
||||
/**
|
||||
* 在右侧显示缩略图
|
||||
* @param {Array} dataUrls - base64 图片数据
|
||||
* 初始化缩略图容器(流式渲染第一步:清空容器)
|
||||
* @param {Object} sizeConfig
|
||||
*/
|
||||
function displayThumbnails(dataUrls, sizeConfig) {
|
||||
function initThumbnails(sizeConfig) {
|
||||
var $preview = $('#paginated-preview');
|
||||
if (!$preview.length) return;
|
||||
|
||||
$preview.empty();
|
||||
if (dataUrls.length === 0) return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 追加单个缩略图到预览区(流式渲染:每页截图完成后立即追加)
|
||||
* @param {string} dataUrl - base64 图片数据或图片src
|
||||
* @param {number} pageIndex - 页面索引(0-based)
|
||||
* @param {Object} sizeConfig
|
||||
* @param {Object} pageData - 页面对象 { type, pageNum, ... }
|
||||
*/
|
||||
function appendThumbnail(dataUrl, pageIndex, sizeConfig, pageData) {
|
||||
var $preview = $('#paginated-preview');
|
||||
if (!$preview.length) return;
|
||||
|
||||
// 计算缩放比例:缩略图高度 = 容器高度 - 40(页码标签) - 40(上下padding)
|
||||
var containerHeight = $preview.parent().height() || 700;
|
||||
var scaleRatio = (containerHeight - 80) / sizeConfig.height;
|
||||
var thumbWidth = Math.round(sizeConfig.width * scaleRatio);
|
||||
|
||||
for (var i = 0; i < dataUrls.length; i++) {
|
||||
var $item = $('<div class="preview-thumb-item" data-page-index="' + i + '">');
|
||||
$item.css('width', thumbWidth + 'px');
|
||||
var $item = $('<div class="preview-thumb-item" data-page-index="' + pageIndex + '">');
|
||||
$item.css('width', thumbWidth + 'px');
|
||||
|
||||
var $img = $('<img>');
|
||||
$img.attr('src', dataUrls[i]);
|
||||
$img.css('width', thumbWidth + 'px');
|
||||
$item.append($img);
|
||||
var $img = $('<img>');
|
||||
$img.attr('src', dataUrl);
|
||||
$img.css('width', thumbWidth + 'px');
|
||||
$item.append($img);
|
||||
|
||||
// 页码
|
||||
var $pageNum = $('<span class="preview-thumb-page-num">' + (i + 1) + '/' + dataUrls.length + '</span>');
|
||||
$item.append($pageNum);
|
||||
// 页码(初始只显示序号,全部完成后更新为 N/M)
|
||||
var $pageNum = $('<span class="preview-thumb-page-num">' + (pageIndex + 1) + '</span>');
|
||||
$item.append($pageNum);
|
||||
|
||||
// 对齐按钮(仅内容页)
|
||||
if (pages[i] && pages[i].type === 'content') {
|
||||
var pageNum = pages[i].pageNum || (i);
|
||||
var currentAlign = (config.pageAlignments && config.pageAlignments[pageNum]) || 'top';
|
||||
var isActiveCenter = currentAlign === 'center';
|
||||
var isActiveBottom = currentAlign === 'bottom';
|
||||
var activeClass = isActiveCenter ? ' active-center' : (isActiveBottom ? ' active-bottom' : '');
|
||||
var symbol = isActiveCenter ? '\u2195' : (isActiveBottom ? '\u2193' : '\u2191');
|
||||
var $toggle = $('<button class="thumb-alignment-toggle' + activeClass + '" data-page-index="' + i + '" data-page-num="' + pageNum + '">' +
|
||||
symbol +
|
||||
'</button>');
|
||||
$item.append($toggle);
|
||||
}
|
||||
|
||||
$preview.append($item);
|
||||
// 对齐按钮(仅内容页)
|
||||
if (pageData && pageData.type === 'content') {
|
||||
var pageNum = pageData.pageNum || (pageIndex);
|
||||
var currentAlign = (config.pageAlignments && config.pageAlignments[pageNum]) || 'top';
|
||||
var isActiveCenter = currentAlign === 'center';
|
||||
var isActiveBottom = currentAlign === 'bottom';
|
||||
var activeClass = isActiveCenter ? ' active-center' : (isActiveBottom ? ' active-bottom' : '');
|
||||
var symbol = isActiveCenter ? '\u2195' : (isActiveBottom ? '\u2193' : '\u2191');
|
||||
var $toggle = $('<button class="thumb-alignment-toggle' + activeClass + '" data-page-index="' + pageIndex + '" data-page-num="' + pageNum + '">' +
|
||||
symbol +
|
||||
'</button>');
|
||||
$item.append($toggle);
|
||||
}
|
||||
|
||||
$preview.append($item);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新所有缩略图页码为 N/M 格式(流式渲染全部完成后调用)
|
||||
* @param {number} totalPages
|
||||
*/
|
||||
function updateThumbnailPageNumbers(totalPages) {
|
||||
var $items = $('#paginated-preview .preview-thumb-item');
|
||||
$items.each(function (i) {
|
||||
$(this).find('.preview-thumb-page-num').text((i + 1) + '/' + totalPages);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user