(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)); }; })();