mirror of
https://gitee.com/ulthon/ulthon_information.git
synced 2026-07-01 18: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
|
* @returns {jQuery Deferred} resolves with canvas array
|
||||||
*/
|
*/
|
||||||
function capturePagesFromStaging() {
|
function capturePagesFromStaging() {
|
||||||
@@ -1695,15 +1807,32 @@ var PhoneImageEngine = (function () {
|
|||||||
var deferred = $.Deferred();
|
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);
|
if (onProgress) onProgress(canvases.length, canvases.length, null);
|
||||||
var pagesData = [];
|
var pagesData = [];
|
||||||
for (var i = 0; i < canvases.length; i++) {
|
for (var i = 0; i < canvases.length; i++) {
|
||||||
pagesData.push(canvases[i].toDataURL('image/jpeg', 0.92));
|
pagesData.push(canvases[i].toDataURL('image/jpeg', 0.92));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 第二步:生成长图
|
// 第二步:生成长图(DOM模式用canvas拼接,旧模式用编辑器DOM截图)
|
||||||
return generateLongImageBase64().then(function(longBase64) {
|
var longImagePromise;
|
||||||
|
if (config.useDomPreview) {
|
||||||
|
longImagePromise = generateLongImageFromCanvases(canvases);
|
||||||
|
} else {
|
||||||
|
longImagePromise = generateLongImageBase64();
|
||||||
|
}
|
||||||
|
|
||||||
|
return longImagePromise.then(function(longBase64) {
|
||||||
return { pages: pagesData, longImage: longBase64 };
|
return { pages: pagesData, longImage: longBase64 };
|
||||||
});
|
});
|
||||||
}).then(function(result) {
|
}).then(function(result) {
|
||||||
|
|||||||
Reference in New Issue
Block a user