Files
SoonDesign/frontend-web/js/common/asset-base.js
T
24kycj 4ce4486b26 Web 端本地缓存、首页与会员弹窗体验优化
新增 IndexedDB 与最近文件 L1 缓存、云保存/打开链路;首页支持下载与清空本地缓存;修复清空 storage 后语言初始化报错;优化 design2 背景加载与侧栏标签样式;完善会员激活/支付弹层样式;后端补充文件缩略图字段与 thumb 接口。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-11 11:05:44 +08:00

160 lines
4.8 KiB
JavaScript

(function () {
'use strict';
function computeAssetBase() {
if (typeof window === 'undefined' || !window.location) {
return 'assets/images/';
}
var p = window.location.pathname || '/';
if (p.indexOf('/pages/') !== -1 || /\.web\.html$/i.test(p) || /\/pages\/[^/]+\.html$/i.test(p)) {
return '../assets/images/';
}
if (p.endsWith('/pages/') || p.endsWith('/pages')) {
return '../assets/images/';
}
return 'assets/images/';
}
function computeJsBase() {
if (typeof window === 'undefined' || !window.location) {
return 'js/';
}
var p = window.location.pathname || '/';
if (p.indexOf('/pages/') !== -1 || /\.web\.html$/i.test(p) || /\/pages\/[^/]+\.html$/i.test(p)) {
return '../js/';
}
return 'js/';
}
window.SOON_ASSET_BASE = computeAssetBase();
window.SOON_JS_BASE = computeJsBase();
window.soonAsset = function (name) {
var n = String(name || '').replace(/^\/+/, '');
return window.SOON_ASSET_BASE + n;
};
window.soonJs = function (rel) {
var n = String(rel || '').replace(/^\/+/, '');
return window.SOON_JS_BASE + n;
};
/** 等 HTMLImage 解码完成后再 toDataURL / setSrc,避免间歇性空白背景 */
window.soonFabricImageWhenReady = function (image, cb, skipEmbed) {
if (!image) {
if (typeof cb === 'function') cb(null);
return;
}
function finalize() {
if (skipEmbed) {
if (typeof cb === 'function') cb(image);
return;
}
try {
var dataUrl = image.toDataURL();
if (dataUrl && dataUrl.length > 500) {
image.setSrc(dataUrl, function (img) {
if (typeof cb === 'function') cb(img || image);
});
return;
}
} catch (e) { /* ignore */ }
if (typeof cb === 'function') cb(image);
}
var el = image.getElement ? image.getElement() : null;
if (!el) {
finalize();
return;
}
if (el.complete && el.naturalWidth > 0) {
finalize();
return;
}
el.onload = function () { finalize(); };
el.onerror = function () {
if (typeof cb === 'function') cb(null);
};
};
window.soonFabricImageFromAsset = function (assetName, onReady, onFail, retryLeft, skipEmbed) {
if (typeof fabric === 'undefined' || !fabric.Image) {
if (typeof onFail === 'function') onFail();
return;
}
var retries = retryLeft == null ? 2 : retryLeft;
var url = window.soonAsset(assetName);
fabric.Image.fromURL(url, function (image) {
if (!image || !image.width) {
if (retries > 0) {
setTimeout(function () {
window.soonFabricImageFromAsset(assetName, onReady, onFail, retries - 1, skipEmbed);
}, 150);
return;
}
if (typeof onFail === 'function') onFail();
return;
}
function deliver(img) {
if (img && typeof onReady === 'function') onReady(img);
else if (retries > 0) {
setTimeout(function () {
window.soonFabricImageFromAsset(assetName, onReady, onFail, retries - 1, skipEmbed);
}, 150);
} else if (typeof onFail === 'function') onFail();
}
if (skipEmbed) {
window.soonFabricImageWhenReady(image, deliver, true);
return;
}
window.soonFabricImageWhenReady(image, deliver);
}, null, { crossOrigin: 'anonymous' });
};
window.soonRunWhenCanvasReady = function (selector, fn) {
function tryRun() {
var el = typeof selector === 'string' ? document.querySelector(selector) : selector;
var w = el ? (el.clientWidth || el.width || 0) : 0;
if ((!w || w < 50) && window.SOON_DEPLOY_CONFIG) {
requestAnimationFrame(function () {
requestAnimationFrame(tryRun);
});
return;
}
if (typeof fn === 'function') fn(w || 800);
}
tryRun();
};
var SOON_LOCALE_CODES = { zh: 1, ozh: 1, en: 1 };
window.soonNormalizeLocaleCode = function (loc) {
if (!loc) return 'zh';
if (SOON_LOCALE_CODES[loc]) return loc;
var s = String(loc);
if (s.indexOf('zh') === 0) return s.indexOf('TW') >= 0 ? 'ozh' : 'zh';
return 'en';
};
window.soonResolveLocale = function (cb) {
if (typeof cb !== 'function') return;
var stored;
try { stored = localStorage.getItem('lang'); } catch (e) { stored = null; }
if (stored && SOON_LOCALE_CODES[stored]) {
cb(stored);
return;
}
var bridge = window.platformBridge;
if (!bridge || typeof bridge.getLocale !== 'function') {
cb('zh');
return;
}
var ret;
try { ret = bridge.getLocale(); } catch (e) { cb('zh'); return; }
if (ret && typeof ret.then === 'function') {
ret.then(function (loc) { cb(window.soonNormalizeLocaleCode(loc)); }).catch(function () { cb('zh'); });
return;
}
cb(window.soonNormalizeLocaleCode(ret));
};
})();