mirror of
https://gitee.com/ulthon/ulthon_information.git
synced 2026-07-01 16:32:48 +08:00
feat(phone-image): 生成圖片SnapDOM截圖流程改造
- 新增captureDomPages(): 從右側DOM容器串行截圖 - 新增generateLongImageFromCanvases(): canvas拼接長圖 - saveImages()條件分支: useDomPreview走DOM截圖, 否則走舊路徑 - 截圖參數scale=2, backgroundColor=#ffffff - 保留doCapturePages/capturePagesFromStaging作為備用
This commit is contained in:
@@ -1644,7 +1644,119 @@ var PhoneImageEngine = (function () {
|
||||
}
|
||||
|
||||
/**
|
||||
* 将页面渲染到隐藏区域并高质量截图(用于保存)
|
||||
* 从右侧DOM分页容器截图(DOM预览模式)
|
||||
* 串行截图每个 .dom-page-container,避免并行导致内存溢出
|
||||
* @param {Function} [onProgress] 进度回调 function(current, total)
|
||||
* @returns {jQuery Deferred} resolves with canvas array
|
||||
*/
|
||||
function captureDomPages(onProgress) {
|
||||
var deferred = $.Deferred();
|
||||
|
||||
var containers = document.querySelectorAll('#paginated-preview .dom-page-container');
|
||||
if (!containers || containers.length === 0) {
|
||||
deferred.reject('未找到DOM分页容器');
|
||||
return deferred.promise();
|
||||
}
|
||||
|
||||
var sizeConfig = config.sizes[config.size] || config.sizes.xiaohongshu;
|
||||
var outputWidth = sizeConfig.width * 2; // scale=2
|
||||
var outputHeight = sizeConfig.height * 2;
|
||||
var totalPages = containers.length;
|
||||
var canvases = [];
|
||||
|
||||
console.log('[PhoneImage] DOM截图开始,共' + totalPages + '页');
|
||||
PhoneImageLogPanel.log('DOM截图开始,共' + totalPages + '页', 'info');
|
||||
|
||||
var idx = 0;
|
||||
|
||||
function captureNext() {
|
||||
if (idx >= totalPages) {
|
||||
console.log('[PhoneImage] DOM截图完成,成功' + canvases.length + '/' + totalPages + '页');
|
||||
PhoneImageLogPanel.log('DOM截图完成,成功' + canvases.length + '/' + totalPages + '页', 'success');
|
||||
deferred.resolve(canvases);
|
||||
return;
|
||||
}
|
||||
|
||||
// 进度显示
|
||||
if (onProgress) onProgress(idx + 1, totalPages);
|
||||
PhoneImageLogPanel.log('截图中 ' + (idx + 1) + '/' + totalPages, 'info');
|
||||
|
||||
try {
|
||||
snapdom.toCanvas(containers[idx], {
|
||||
scale: 2,
|
||||
backgroundColor: '#ffffff'
|
||||
}).then(function (canvas) {
|
||||
// 确保尺寸正确
|
||||
if (canvas.width !== outputWidth || canvas.height !== outputHeight) {
|
||||
var resizedCanvas = document.createElement('canvas');
|
||||
resizedCanvas.width = outputWidth;
|
||||
resizedCanvas.height = outputHeight;
|
||||
var ctx = resizedCanvas.getContext('2d');
|
||||
ctx.drawImage(canvas, 0, 0, outputWidth, outputHeight);
|
||||
canvas = resizedCanvas;
|
||||
}
|
||||
|
||||
canvases.push(canvas);
|
||||
idx++;
|
||||
captureNext();
|
||||
}).catch(function (err) {
|
||||
console.error('[PhoneImage] 第' + (idx + 1) + '页截图失败:', err);
|
||||
PhoneImageLogPanel.log('第' + (idx + 1) + '页截图失败: ' + err, 'error');
|
||||
// 继续下一页
|
||||
idx++;
|
||||
captureNext();
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('[PhoneImage] 第' + (idx + 1) + '页截图异常:', e);
|
||||
PhoneImageLogPanel.log('第' + (idx + 1) + '页截图异常: ' + e, 'error');
|
||||
idx++;
|
||||
captureNext();
|
||||
}
|
||||
}
|
||||
|
||||
captureNext();
|
||||
return deferred.promise();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将canvas数组拼接为长图base64
|
||||
* @param {Array} canvases - canvas对象数组
|
||||
* @returns {jQuery Deferred} resolves with base64 string or null
|
||||
*/
|
||||
function generateLongImageFromCanvases(canvases) {
|
||||
var deferred = $.Deferred();
|
||||
|
||||
if (!canvases || canvases.length === 0) {
|
||||
deferred.resolve(null);
|
||||
return deferred.promise();
|
||||
}
|
||||
|
||||
var maxWidth = 0;
|
||||
var totalHeight = 0;
|
||||
for (var i = 0; i < canvases.length; i++) {
|
||||
totalHeight += canvases[i].height;
|
||||
if (canvases[i].width > maxWidth) {
|
||||
maxWidth = canvases[i].width;
|
||||
}
|
||||
}
|
||||
|
||||
var longCanvas = document.createElement('canvas');
|
||||
longCanvas.width = maxWidth;
|
||||
longCanvas.height = totalHeight;
|
||||
var ctx = longCanvas.getContext('2d');
|
||||
|
||||
var y = 0;
|
||||
for (var j = 0; j < canvases.length; j++) {
|
||||
ctx.drawImage(canvases[j], 0, y);
|
||||
y += canvases[j].height;
|
||||
}
|
||||
|
||||
deferred.resolve(longCanvas.toDataURL('image/jpeg', 0.85));
|
||||
return deferred.promise();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将页面渲染到隐藏区域并高质量截图(用于保存,旧流程备用)
|
||||
* @returns {jQuery Deferred} resolves with canvas array
|
||||
*/
|
||||
function capturePagesFromStaging() {
|
||||
@@ -1695,15 +1807,32 @@ var PhoneImageEngine = (function () {
|
||||
var deferred = $.Deferred();
|
||||
|
||||
// 第一步:生成分页图片和长图
|
||||
capturePagesFromStaging().then(function (canvases) {
|
||||
// DOM预览模式:直接从右侧DOM容器截图;旧模式:从隐藏渲染区截图
|
||||
var capturePromise;
|
||||
if (config.useDomPreview) {
|
||||
capturePromise = captureDomPages(function (current, total) {
|
||||
if (onProgress) onProgress(current, total, null);
|
||||
});
|
||||
} else {
|
||||
capturePromise = capturePagesFromStaging();
|
||||
}
|
||||
|
||||
capturePromise.then(function (canvases) {
|
||||
if (onProgress) onProgress(canvases.length, canvases.length, null);
|
||||
var pagesData = [];
|
||||
for (var i = 0; i < canvases.length; i++) {
|
||||
pagesData.push(canvases[i].toDataURL('image/jpeg', 0.92));
|
||||
}
|
||||
|
||||
// 第二步:生成长图
|
||||
return generateLongImageBase64().then(function(longBase64) {
|
||||
// 第二步:生成长图(DOM模式用canvas拼接,旧模式用编辑器DOM截图)
|
||||
var longImagePromise;
|
||||
if (config.useDomPreview) {
|
||||
longImagePromise = generateLongImageFromCanvases(canvases);
|
||||
} else {
|
||||
longImagePromise = generateLongImageBase64();
|
||||
}
|
||||
|
||||
return longImagePromise.then(function(longBase64) {
|
||||
return { pages: pagesData, longImage: longBase64 };
|
||||
});
|
||||
}).then(function(result) {
|
||||
|
||||
Reference in New Issue
Block a user