/* ===================================================================== * loader.js — 无界笺的加载动画外壳。 * * 绘画引擎与 12 幅画作来自 Painting Loaders * (https://painterly.design-tools.workers.dev,作者 Sasha / x.com/aleksksaa), * engine.js 与 style-*.js 原样保留。这里只负责:随机挑一幅(不与上次重复), * 把画布铺满本页,并通知父页面已经开始作画。 * * 本页通过 iframe 嵌入,p5 的全局模式不会污染主应用。 * ===================================================================== */ const PAINTINGS = [ { key: 'garden', style: 'impressionismGarden', name: '花园', label: 'Garden' }, { key: 'dawn', style: 'impressionismDawn', name: '晨曦', label: 'Dawn' }, { key: 'willow', style: 'impressionismWillow', name: '垂柳', label: 'Willow' }, { key: 'wisteria', style: 'impressionismWisteria', name: '紫藤', label: 'Wisteria' }, { key: 'orchard', style: 'impressionismOrchard', name: '果园', label: 'Orchard' }, { key: 'irises', style: 'impressionismIrises', name: '鸢尾', label: 'Irises' }, { key: 'poppies', style: 'impressionismPoppies', name: '虞美人', label: 'Poppies' }, { key: 'koi', style: 'impressionismKoi', name: '锦鲤', label: 'Koi' }, { key: 'roses', style: 'impressionismRoses', name: '玫瑰', label: 'Roses' }, { key: 'oranges', style: 'impressionismOranges', name: '橘子', label: 'Oranges' }, { key: 'sail', style: 'impressionismSail', name: '远帆', label: 'Sail' }, { key: 'dusk', style: 'abstractionDusk', name: '黄昏', label: 'Dusk' }, ]; const LAST_KEY = 'boundless-last-painting'; function choosePainting() { const wanted = new URLSearchParams(location.search).get('p'); const exact = PAINTINGS.find((item) => item.key === wanted); if (exact) return exact; let last = null; try { last = localStorage.getItem(LAST_KEY); } catch (e) { /* 隐私模式 */ } const pool = PAINTINGS.filter((item) => item.key !== last); const picked = pool[Math.floor(Math.random() * pool.length)] || PAINTINGS[0]; try { localStorage.setItem(LAST_KEY, picked.key); } catch (e) { /* 隐私模式 */ } return picked; } const painting = choosePainting(); const config = window.STYLES[painting.style]; document.documentElement.style.background = config.palette.ground; function notifyParent(type) { if (window.parent === window) return; window.parent.postMessage( { source: 'boundless-painterly', type, key: painting.key, name: painting.name, label: painting.label, ground: config.palette.ground }, location.origin, ); } notifyParent('chosen'); let engine = null; const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; // p5 全局模式:页面加载后若 window 上有 setup / draw 就会自动开始。 // 系统要求减少动态效果时不作画,只留下画纸底色。 if (!reduceMotion) { window.setup = function () { // 画布内部固定 600×600,再由 CSS 缩放;不跟随设备像素比可以省下不少显存 pixelDensity(1); engine = createEngine(config, { mount: document.body }); engine.setup(); notifyParent('start'); }; window.draw = function () { if (engine) engine.draw(); }; }