Web 端本地缓存、首页与会员弹窗体验优化

新增 IndexedDB 与最近文件 L1 缓存、云保存/打开链路;首页支持下载与清空本地缓存;修复清空 storage 后语言初始化报错;优化 design2 背景加载与侧栏标签样式;完善会员激活/支付弹层样式;后端补充文件缩略图字段与 thumb 接口。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
24kycj
2026-06-11 11:05:44 +08:00
parent 877fd278c2
commit 4ce4486b26
33 changed files with 3190 additions and 1143 deletions
+186 -77
View File
@@ -9,12 +9,27 @@ function soonDesign2MainHeight() {
return Math.max(480, window.innerHeight - (tb ? tb.offsetHeight : 0));
}
function soonDesign2SidebarWidth() {
var colRight = document.querySelector('body.soon-design-page .col-right');
if (colRight && colRight.offsetWidth > 0) return colRight.offsetWidth;
return 320;
}
function soonDesign2ToolboxWidth() {
var toolbox = document.querySelector('body.soon-design-page .container .left');
if (toolbox && toolbox.offsetWidth > 0) return toolbox.offsetWidth;
return 50;
}
function soonDesign2CanvasWidth() {
var w = $('#canvas-div').width();
if (w > 0) return w;
w = $('.col-left').width();
if (w > 0) return Math.max(320, w - 70);
return Math.max(320, window.innerWidth - 390);
var canvasDiv = document.getElementById('canvas-div');
if (canvasDiv && canvasDiv.clientWidth > 0) return canvasDiv.clientWidth;
var colLeft = document.querySelector('body.soon-design-page .col-left');
if (colLeft && colLeft.clientWidth > 0) {
return Math.max(320, colLeft.clientWidth - soonDesign2ToolboxWidth());
}
var docW = document.documentElement.clientWidth || window.innerWidth;
return Math.max(320, docW - soonDesign2SidebarWidth() - soonDesign2ToolboxWidth());
}
function layoutDesign2Shell() {
@@ -80,6 +95,7 @@ zoom = (function () {
var z = divW / 1200 > 1 ? 1 : divW / 1200;
return z > 0 ? z : 0.5;
})()
window.zoom = zoom;
// 初始化标尺
function initRulers() {
@@ -518,29 +534,110 @@ function initRulers() {
}
}
initRulers();
if (window.SOON_DEPLOY_CONFIG && ($('#canvas-div').width() || 0) < 100) {
requestAnimationFrame(function () {
requestAnimationFrame(function () {
var layout = layoutDesign2Shell();
var divW = layout.canvasW;
zoom = divW / 1200 > 1 ? 1 : divW / 1200;
if (zoom <= 0) zoom = 0.5;
canvas1.setWidth(layout.canvasW);
canvas1.setHeight(layout.canvasH);
canvas2.setWidth(layout.canvasW);
canvas2.setHeight(layout.canvasH);
canvas1.zoomToPoint(new fabric.Point(canvas1.width / 2, canvas1.height / 2), zoom);
canvas2.zoomToPoint(new fabric.Point(canvas2.width / 2, canvas2.height / 2), zoom);
window.zoom = zoom;
canvas1.renderAll();
canvas2.renderAll();
initRulers();
});
});
function relayoutDesign2Canvas() {
var layout = layoutDesign2Shell();
var divW = layout.canvasW;
zoom = divW / 1200 > 1 ? 1 : divW / 1200;
if (zoom <= 0) zoom = 0.5;
window.zoom = zoom;
canvas1.setWidth(layout.canvasW);
canvas1.setHeight(layout.canvasH);
canvas2.setWidth(layout.canvasW);
canvas2.setHeight(layout.canvasH);
canvas1.zoomToPoint(new fabric.Point(canvas1.width / 2, canvas1.height / 2), zoom);
canvas2.zoomToPoint(new fabric.Point(canvas2.width / 2, canvas2.height / 2), zoom);
canvas1.renderAll();
canvas2.renderAll();
initRulers();
if (typeof window.soonDesign2ScaleBgSources === 'function') {
window.soonDesign2ScaleBgSources();
}
if (window.is_bgi_add) {
canvas1.requestRenderAll();
canvas2.requestRenderAll();
}
}
$('#source_front').width(zoom * $('#source_front').width())
$('#source_back').width(zoom * $('#source_back').width())
function soonDesign2ScaleBgSources() {
var z = zoom || window.zoom || 0.5;
var sf = document.getElementById('source_front');
var sb = document.getElementById('source_back');
if (sf && sf.naturalWidth > 0) {
sf.style.width = (sf.naturalWidth * z) + 'px';
sf.style.height = (sf.naturalHeight * z) + 'px';
}
if (sb && sb.naturalWidth > 0) {
sb.style.width = (sb.naturalWidth * z) + 'px';
sb.style.height = (sb.naturalHeight * z) + 'px';
}
}
function soonDesign2BgOverlayMetrics(imgEl) {
if (!imgEl || !imgEl.complete || imgEl.naturalWidth <= 0) return null;
var z = zoom || window.zoom || 0.5;
var w = parseFloat(imgEl.style.width);
if (!w || w <= 0) w = imgEl.naturalWidth * z;
var h = parseFloat(imgEl.style.height);
if (!h || h <= 0) h = imgEl.naturalHeight * z;
return { w: w, h: h };
}
function soonDesign2PrepareBgSources(done) {
var sf = document.getElementById('source_front');
var sb = document.getElementById('source_back');
if (!sf || !sb) {
is_bgi_add = true;
window.is_bgi_add = true;
if (typeof done === 'function') done();
return;
}
var ver = typeof bg_version !== 'undefined' ? bg_version : 1;
var frontName = 'front_bg' + ver + '_2.png';
if (!(sf.complete && sf.naturalWidth > 0 && (sf.src || '').indexOf(frontName) !== -1)) {
sf.src = soonAsset(frontName);
}
var pending = 2;
function finishOne() {
pending--;
if (pending > 0) return;
soonDesign2ScaleBgSources();
is_bgi_add = true;
window.is_bgi_add = true;
canvas1.requestRenderAll();
canvas2.requestRenderAll();
if (typeof done === 'function') done();
}
function watch(img) {
if (img.complete && img.naturalWidth > 0) {
finishOne();
return;
}
img.onload = finishOne;
img.onerror = finishOne;
}
watch(sf);
watch(sb);
}
function soonDesign2StartBackground() {
soonDesign2PrepareBgSources(addBackground);
}
function soonDesign2Kickoff() {
if (window._soonDesign2KickoffDone) return;
window._soonDesign2KickoffDone = true;
if (window.SOON_DEPLOY_CONFIG && ($('#canvas-div').width() || 0) < 100) {
relayoutDesign2Canvas();
}
soonDesign2StartBackground();
}
window.soonDesign2ScaleBgSources = soonDesign2ScaleBgSources;
window.soonDesign2PrepareBgSources = soonDesign2PrepareBgSources;
window.soonDesign2BgOverlayMetrics = soonDesign2BgOverlayMetrics;
window.soonDesign2Kickoff = soonDesign2Kickoff;
initRulers();
$('.canvas-container:eq(1)').hide()
canvas = canvas1
window.canvas = canvas
@@ -1643,58 +1740,71 @@ function getCoordsMaxY(acoords) {
return y;
}
function soonPlaceBgOnCanvas(image, canvasSelector) {
var cw = $(canvasSelector).width() || (document.querySelector(canvasSelector) && document.querySelector(canvasSelector).clientWidth) || 800
var ch = $(canvasSelector).height() || (document.querySelector(canvasSelector) && document.querySelector(canvasSelector).clientHeight) || 600
image.left = (cw - image.width * image.get('scaleX')) / 2
image.top = (ch - image.height * image.get('scaleY')) / 2
image.selectable = false
image.hoverable = false
image.hoverCursor = 'default'
}
function soonOpenPendingDesignFile() {
var file = typeof window.soonResolveOpenFileKey === 'function'
? window.soonResolveOpenFileKey(GetFile)
: (GetFile().get('file') || '');
if (file && file != 'empty') {
if (typeof window.soonConsumeOpenMeta === 'function') {
window.soonConsumeOpenMeta(file);
}
window.openFile(file);
}
}
function addBackground() {
// 类型改变
fabric.Image.fromURL(soonAsset('bg_front_2.png'), function (image) {
image.left = ($('#canvas1').width() - image.width * image.get('scaleX')) / 2
image.top = ($('#canvas1').height() - image.height * image.get('scaleY')) / 2
if (background_image1 && background_image2) return;
var loadBg = typeof window.soonFabricImageFromAsset === 'function'
? window.soonFabricImageFromAsset
: null;
var whenReady = typeof window.soonRunWhenCanvasReady === 'function'
? window.soonRunWhenCanvasReady
: function (_sel, fn) { fn(); };
var props = window.TO_JSON_PROPERTIES || ['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline', 'evented', 'linethrough', 'textBackgroundColor', 'diameter', 'flipped'];
image.selectable = false
image.hoverable = false
image.hoverCursor = 'default'
image.setSrc(image.toDataURL(), function (image) {
background_image1 = image
background_image = background_image1
window.background_image1 = background_image1;
window.background_image = background_image;
canvas1.add(image)
canvas1.renderAll()
function finishBack(backImg) {
if (backImg) {
soonPlaceBgOnCanvas(backImg, '#canvas2');
background_image2 = backImg;
window.background_image2 = backImg;
canvas2.add(backImg);
canvas2.renderAll();
recordObjs2.push(JSON.stringify(objs2));
recordJson2.push(canvas2.toJSON(TO_JSON_PROPERTIES));
}
soonOpenPendingDesignFile();
}
recordObjs1.push(JSON.stringify(objs1))
const props = window.TO_JSON_PROPERTIES || ['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline', 'evented', 'linethrough', 'textBackgroundColor', 'diameter', 'flipped'];
recordJson1.push(canvas1.toJSON(props))
})
// 类型改变
fabric.Image.fromURL(soonAsset('bg_back_2.png'), function (image) {
image.left = ($('#canvas2').width() - image.width) / 2
image.top = ($('#canvas2').height() - image.height) / 2
function startLoad() {
if (!loadBg) return;
loadBg('bg_front_2.png', function (frontImg) {
if (!frontImg) return;
soonPlaceBgOnCanvas(frontImg, '#canvas1');
background_image1 = frontImg;
background_image = frontImg;
window.background_image1 = frontImg;
window.background_image = frontImg;
canvas1.add(frontImg);
canvas1.renderAll();
recordObjs1.push(JSON.stringify(objs1));
recordJson1.push(canvas1.toJSON(props));
loadBg('bg_back_2.png', finishBack, function () { loadBg('bg_back_2.png', finishBack, null, true); }, true);
}, function () {
setTimeout(startLoad, 200);
}, null, true);
}
image.selectable = false
image.hoverable = false
image.hoverCursor = 'default'
image.setSrc(image.toDataURL(), function (image) {
background_image2 = image
window.background_image2 = background_image2;
canvas2.add(image)
canvas2.renderAll()
recordObjs2.push(JSON.stringify(objs2))
recordJson2.push(canvas2.toJSON(TO_JSON_PROPERTIES))
var file = typeof window.soonResolveOpenFileKey === 'function'
? window.soonResolveOpenFileKey(GetFile)
: (GetFile().get('file') || '');
if (file && file != 'empty') {
if (typeof window.soonConsumeOpenMeta === 'function') {
window.soonConsumeOpenMeta(file);
}
window.openFile(file);
}
})
})
is_bgi_add = true
})
whenReady('#canvas1', startLoad);
}
function addPic(pointer) {
@@ -1975,6 +2085,7 @@ function applySysLan(data) {
localStorage.setItem('lang', 'zh')
break
case 'zh-TW':
case 'ozh':
s_lan = 'ozh'
// 同步到全局作用域(用于 .jsc 文件加载)
if (typeof window !== 'undefined') {
@@ -2112,8 +2223,6 @@ if (typeof ipcRenderer !== 'undefined' && ipcRenderer) {
window.platformBridge.onClose(onCloseConfirm)
}
addBackground() //添加背景 白色卡片
initAligningGuidelines(canvas1)
initAligningGuidelines(canvas2)
+64 -42
View File
@@ -1086,11 +1086,23 @@ function cloudSaveSuccessLabel(res, fallback) {
return fallback || '';
}
function soonPageDesignType() {
try {
var p = new URLSearchParams(location.search);
return Number(p.get('type')) || 2;
} catch (e) {
return 2;
}
}
function onCloudWriteDone(res, fallback, callback) {
applyCloudWriteResult(res, fallback);
if (res && res.fileKey && typeof window.soonClearPendingImport === 'function') {
window.soonClearPendingImport();
}
if (typeof window.soonRecentOnCloudSave === 'function') {
window.soonRecentOnCloudSave(res, fallback, soonPageDesignType());
}
layer.msg(language_str('saveSucc') + cloudSaveSuccessLabel(res, fallback));
if (callback && typeof callback === 'function') callback();
}
@@ -1099,15 +1111,6 @@ function guardWebSave() {
return typeof window.soonGuardCloudSave === 'function' ? window.soonGuardCloudSave() : true;
}
function reportSaveError(err) {
if (err && err.status) return;
if (typeof window.soonShowApiError === 'function') {
window.soonShowApiError({ status: err && err.status, message: (err && err.message) || '保存失败' });
} else if (typeof window.soonToast === 'function') {
window.soonToast('保存失败', 'error');
}
}
function saveAs(op1, callback) {
// 临时移除辅助线,保存后再恢复
let guideLines1 = []
@@ -1142,23 +1145,23 @@ function saveAs(op1, callback) {
let o = { f: j, b: b, fo: objs1, bo: objs2 }
let con_o = Object.assign(o, op1)
if (!guardWebSave()) return;
var prevOpenKey = openAs.name || '';
if (typeof window.soonApplySavePreview === 'function') window.soonApplySavePreview(con_o, canvas1);
con_o.soonType = 2;
var dialogApi = (typeof dialog !== 'undefined' && dialog) ? dialog : (window.platformBridge && window.platformBridge.showSaveDialog ? { showSaveDialog: function(opts) { return window.platformBridge.showSaveDialog(opts); } } : null);
if (!dialogApi) return;
dialogApi.showSaveDialog({ title: language_str('saveFile'), filters: [{ name: 'Soon File Type', extensions: ['soon'] }], defaultPath: openAs.name || undefined })
dialogApi.showSaveDialog({ title: language_str('saveFile'), filters: [{ name: 'Soon File Type', extensions: ['soon'] }], defaultPath: typeof window.soonSaveDialogDefaultPath === 'function' ? window.soonSaveDialogDefaultPath(openAs.name) : openAs.name })
.then(function(result) {
if (result.canceled) return;
var fp = result.filePath || (result.fileHandle && result.fileHandle.name);
var fp = typeof window.soonEnsureSaveFileName === 'function'
? window.soonEnsureSaveFileName(result.filePath || (result.fileHandle && result.fileHandle.name))
: (result.filePath || (result.fileHandle && result.fileHandle.name));
if (!fp) return;
var ext = (typeof path !== 'undefined' && path && path.extname) ? path.extname(fp) : (fp.indexOf('.') >= 0 ? fp.slice(fp.lastIndexOf('.')) : '');
if (ext !== '.soon') fp = (fp || 'design').replace(/\.soon$/i, '') + '.soon';
con_o.soonType = 2;
var content = JSON.stringify(con_o);
if (window.platformBridge && window.platformBridge.writeFile) {
window.platformBridge.writeFile(fp, content).then(function (res) {
onCloudWriteDone(res, fp, callback);
}).catch(reportSaveError);
return;
}
if (typeof window.soonWriteSoonContentWeb === 'function' &&
window.soonWriteSoonContentWeb(fp, content, prevOpenKey, function (res, pk) {
onCloudWriteDone(res, pk, callback);
})) return;
var fs = typeof require !== 'undefined' ? require('fs') : null;
if (fs) {
fs.writeFileSync(fp, content, 'utf8');
@@ -1168,7 +1171,9 @@ function saveAs(op1, callback) {
if (callback && typeof callback === 'function') callback();
}
})
.catch(reportSaveError);
.catch(function (err) {
if (typeof window.soonReportSaveError === 'function') window.soonReportSaveError(err);
});
}
function save(op1, callback) {
@@ -1204,16 +1209,19 @@ function save(op1, callback) {
let o = { f: j, b: b, fo: objs1, bo: objs2 }
let con_o = Object.assign(o, op1)
con_o.soonType = 2
var content = JSON.stringify(con_o)
if (!guardWebSave()) return;
if (openAs.name != '') {
if (window.platformBridge && window.platformBridge.writeFile) {
window.platformBridge.writeFile(openAs.name, content).then(function (res) {
onCloudWriteDone(res, openAs.name, callback);
}).catch(reportSaveError);
return;
}
var prevOpenKey = openAs.name || '';
if (typeof window.soonApplySavePreview === 'function') window.soonApplySavePreview(con_o, canvas1);
con_o.soonType = 2;
var content = JSON.stringify(con_o);
var needsDialog = typeof window.soonNeedsSaveDialog === 'function'
? window.soonNeedsSaveDialog(openAs.name)
: !openAs.name;
if (openAs.name && !needsDialog) {
if (typeof window.soonWriteSoonContentWeb === 'function' &&
window.soonWriteSoonContentWeb(openAs.name, content, prevOpenKey, function (res, pk) {
onCloudWriteDone(res, pk, callback);
})) return;
var fs = typeof require !== 'undefined' ? require('fs') : null;
if (fs) {
fs.writeFileSync(openAs.name, content, 'utf8');
@@ -1225,19 +1233,17 @@ function save(op1, callback) {
}
var dialogApi = (typeof dialog !== 'undefined' && dialog) ? dialog : (window.platformBridge && window.platformBridge.showSaveDialog ? { showSaveDialog: function(opts) { return window.platformBridge.showSaveDialog(opts); } } : null);
if (!dialogApi) return;
dialogApi.showSaveDialog({ title: language_str('saveFile'), filters: [{ name: 'Soon File Type', extensions: ['soon'] }], defaultPath: openAs.name || undefined })
dialogApi.showSaveDialog({ title: language_str('saveFile'), filters: [{ name: 'Soon File Type', extensions: ['soon'] }], defaultPath: typeof window.soonSaveDialogDefaultPath === 'function' ? window.soonSaveDialogDefaultPath(openAs.name) : openAs.name })
.then(function(result) {
if (result.canceled) return;
var fp = result.filePath || (result.fileHandle && result.fileHandle.name);
var fp = typeof window.soonEnsureSaveFileName === 'function'
? window.soonEnsureSaveFileName(result.filePath || (result.fileHandle && result.fileHandle.name))
: (result.filePath || (result.fileHandle && result.fileHandle.name));
if (!fp) return;
var ext = (typeof path !== 'undefined' && path && path.extname) ? path.extname(fp) : (fp.indexOf('.') >= 0 ? fp.slice(fp.lastIndexOf('.')) : '');
if (ext !== '.soon') fp = (fp || 'design').replace(/\.soon$/i, '') + '.soon';
if (window.platformBridge && window.platformBridge.writeFile) {
window.platformBridge.writeFile(fp, content).then(function (res) {
onCloudWriteDone(res, fp, callback);
}).catch(reportSaveError);
return;
}
if (typeof window.soonWriteSoonContentWeb === 'function' &&
window.soonWriteSoonContentWeb(fp, content, prevOpenKey, function (res, pk) {
onCloudWriteDone(res, pk, callback);
})) return;
var fs = typeof require !== 'undefined' ? require('fs') : null;
if (fs) {
fs.writeFileSync(fp, content, 'utf8');
@@ -1247,12 +1253,27 @@ function save(op1, callback) {
if (callback && typeof callback === 'function') callback();
}
})
.catch(reportSaveError);
.catch(function (err) {
if (typeof window.soonReportSaveError === 'function') window.soonReportSaveError(err);
});
}
window.saveHistory = function saveHistory() {
var currentPath = openAs.name;
if (!currentPath) return;
if (window.platformBridge && window.fs == null) {
if (typeof window.soonRecentUpsert === 'function') {
window.soonRecentUpsert({
key: currentPath,
name: typeof window.soonDisplayFileName === 'function' ? window.soonDisplayFileName(currentPath) : currentPath,
type: soonPageDesignType(),
kind: typeof window.soonRecentKindFromKey === 'function' ? window.soonRecentKindFromKey(currentPath) : 'local',
thumbRef: currentPath
});
}
return;
}
function doWrite(j) {
var currentPath = openAs.name;
if (!currentPath) return;
var pathForHistory = currentPath;
if (window.platformBridge && currentPath.indexOf('soondesign_session:') !== 0 && currentPath.indexOf('soondesign_file:') !== 0) {
@@ -1455,6 +1476,7 @@ window.openFile = function open(file, jAlready) {
step = step2
}
if (typeof window.soonTryConsumeCloudImport === 'function') window.soonTryConsumeCloudImport(file);
if (typeof window.soonRecentUpsertFromOpen === 'function') window.soonRecentUpsertFromOpen(file, j);
}
canvas1.loadFromJSON(j.f, function () {
+44 -63
View File
@@ -359,9 +359,17 @@ $('#version_change').click(function () {
} else {
bg_version = 1
}
// 类型改变
$('#source_front').attr('src', soonAsset('front_bg') + bg_version + '_2.png')
canvas.renderAll()
var sf = document.getElementById('source_front')
if (!sf) return
sf.onload = function () {
if (typeof window.soonDesign2ScaleBgSources === 'function') {
window.soonDesign2ScaleBgSources()
}
canvas1.requestRenderAll()
canvas2.requestRenderAll()
}
sf.onerror = sf.onload
sf.src = soonAsset('front_bg' + bg_version + '_2.png')
})
$('#front_side').click(function () {
$(this).addClass('ui-button-active')
@@ -1373,58 +1381,6 @@ $('#new').click(function () {
)
})
function chagneTitle() { }
function addBackground() {
// 类型改变
fabric.Image.fromURL(soonAsset('bg_front_2.png'), function (image) {
//image.set("scaleX",$("#canvas-div").width() / 1200 < 1 ? $("#canvas-div").width() / 1200 : 1)
image.left = ($('#canvas1').width() - image.width * image.get('scaleX')) / 2
image.top = ($('#canvas1').height() - image.height * image.get('scaleY')) / 2
image.selectable = false
image.hoverable = false
image.hoverCursor = 'default'
image.setSrc(image.toDataURL(), function (image) {
background_image1 = image
background_image = background_image1
canvas.add(image)
canvas.renderAll()
//pre_objs1.push(JSON.stringify(objs1));
recordObjs1.push(JSON.stringify(objs1))
const props = window.TO_JSON_PROPERTIES || ['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline', 'evented', 'linethrough', 'textBackgroundColor', 'diameter', 'flipped'];
recordJson1.push(canvas1.toJSON(props))
})
// 类型改变
fabric.Image.fromURL(soonAsset('bg_back_2.png'), function (image) {
image.left = ($('#canvas2').width() - image.width) / 2
image.top = ($('#canvas2').height() - image.height) / 2
image.selectable = false
image.hoverable = false
image.hoverCursor = 'default'
image.setSrc(image.toDataURL(), function (image) {
background_image2 = image
canvas2.add(image)
canvas2.renderAll()
//pre_objs2.push(JSON.stringify(objs2));
recordObjs2.push(JSON.stringify(objs2))
const props = window.TO_JSON_PROPERTIES || ['selectable', 'hoverable', 'hoverCursor', 'text', 'fontStyle', 'fontWeight', 'underline', 'evented', 'linethrough', 'textBackgroundColor', 'diameter', 'flipped'];
recordJson2.push(canvas2.toJSON(props))
let file = GetFile().get('file')
if (file && file != 'empty') {
if (typeof window.openFile === 'function') {
window.openFile(file);
}
}
})
})
is_bgi_add = true
})
}
function selectObject(target, index) {
updateControls()
@@ -2749,10 +2705,19 @@ if (typeof window._design2CanvasEventsInitialized === 'undefined') {
// 保留 canvas1 特定的 after:render 处理
canvas1.on('after:render', function () {
if (is_bgi_add) {
var image = document.getElementById('source_front')
ctx1.drawImage(image, (canvas.width - $('#source_front').width()) / 2, (canvas.height - $('#source_front').height()) / 2, $('#source_front').width(), $('#source_front').height())
}
if (!window.is_bgi_add) return
var image = document.getElementById('source_front')
var metrics = typeof window.soonDesign2BgOverlayMetrics === 'function'
? window.soonDesign2BgOverlayMetrics(image)
: null
if (!metrics) return
ctx1.drawImage(
image,
(canvas1.width - metrics.w) / 2,
(canvas1.height - metrics.h) / 2,
metrics.w,
metrics.h
)
})
// 保留 canvas1 特定的 text:changed 处理
canvas1.on('text:changed', (e) => {
@@ -2760,11 +2725,27 @@ if (typeof window._design2CanvasEventsInitialized === 'undefined') {
})
// 保留 canvas2 特定的 after:render 处理
canvas2.on('after:render', function () {
if (is_bgi_add) {
var image = document.getElementById('source_back')
ctx2.drawImage(image, (canvas.width - $('#source_back').width()) / 2, (canvas1.height - $('#source_back').height()) / 2, $('#source_back').width(), $('#source_back').height())
}
if (!window.is_bgi_add) return
var image = document.getElementById('source_back')
var metrics = typeof window.soonDesign2BgOverlayMetrics === 'function'
? window.soonDesign2BgOverlayMetrics(image)
: null
if (!metrics) return
ctx2.drawImage(
image,
(canvas2.width - metrics.w) / 2,
(canvas2.height - metrics.h) / 2,
metrics.w,
metrics.h
)
})
requestAnimationFrame(function () {
requestAnimationFrame(function () {
if (typeof window.soonDesign2Kickoff === 'function') {
window.soonDesign2Kickoff();
}
});
});
// 注意:以下事件已在 core.js 的 initCanvasEvents() 中统一处理,移除重复监听以避免冲突:
// - mouse:down (通过 handleObjectSelected 处理)
// - mouse:up (已在 core.js 中处理)