1/** 2 * Sitewide ambient background registry. 3 * 4 * Each preset describes the full ambient stack (base gradient + shader layers). 5 * To add a new procedural background later: 6 * 1. Add a preset object below with a unique `id`. 7 * 2. Point `scripts` at your WebGL/GLSL module(s) â Three.js is loaded automatically. 8 * 3. Set `layers` to show/hide shared shell elements (#page-background, #aurora-overlay, #webgl-overlay). 9 * 4. Implement `onActivate(ctx)` to start your shader; use `onDeactivate(ctx)` to pause/hide if needed. 10 * 5. Append a picker option via `previewStripes` (optional swatch in settings). 11 */ 12(function (global) { 13 'use strict'; 14 15 var DEFAULT_ID = 'caustics'; 16 17 var THREE_CDN = 'https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js'; 18 19 var PRESETS = [ 20 { 21 id: 'caustics', 22 label: 'Caustics', 23 description: 'Rainbow water light with aurora wash', 24 previewStripes: ['#4a2d7a', '#2d8a7a', '#c8a8ff'], 25 layers: { 26 base: true, 27 aurora: true, 28 caustics: true, 29 bubbles: true 30 }, 31 scripts: [ 32 '/scripts/dependencies/webglCaustics.js', 33 '/scripts/dependencies/causticsTextureLoader.js', 34 '/scripts/dependencies/webglAurora.js', 35 '/scripts/dependencies/perfModeToggle.js' 36 ], 37 onActivate: function (ctx) { 38 return ctx.ensureCausticsStack().then(function () { 39 if (typeof global.setCausticsTexture === 'function') { 40 global.setCausticsTexture('/images/your_noise.webp', 0.69); 41 } else if (global.__causticsTextureLoader && 42 typeof global.__causticsTextureLoader.loadDefaultNoise === 'function') { 43 global.__causticsTextureLoader.loadDefaultNoise(); 44 } 45 }); 46 }, 47 onDeactivate: function () { 48 /* Layers hidden by apply module; keep canvases warm for fast switch-back. */ 49 } 50 }, 51 { 52 id: 'horizon', 53 label: 'Horizon', 54 description: 'Cloudy sky cubemap over procedural ocean', 55 previewStripes: ['#2d6a9a', '#89cff0', '#f4c095'], 56 layers: { 57 base: false, 58 aurora: false, 59 caustics: true, 60 bubbles: false 61 }, 62 scripts: [ 63 '/scripts/dependencies/webglHorizonScene.js' 64 ], 65 onActivate: function () { 66 if (global.HorizonBackground && typeof global.HorizonBackground.init === 'function') { 67 return global.HorizonBackground.init(); 68 } 69 return Promise.resolve(); 70 }, 71 onDeactivate: function () { 72 if (global.HorizonBackground && typeof global.HorizonBackground.stop === 'function') { 73 global.HorizonBackground.stop(); 74 } 75 if (global.HorizonBackground && typeof global.HorizonBackground.hide === 'function') { 76 global.HorizonBackground.hide(); 77 } 78 } 79 }, 80 { 81 id: 'clouds', 82 label: 'Clouds', 83 description: 'Volumetric sunset sky with drifting cloud layers', 84 previewStripes: ['#514060', '#aa96cc', '#ff9268'], 85 layers: { 86 base: false, 87 aurora: false, 88 caustics: true, 89 bubbles: false 90 }, 91 scripts: [ 92 '/scripts/dependencies/webglCloudsScene.js' 93 ], 94 onActivate: function () { 95 if (global.SiteBackgroundApply && 96 typeof global.SiteBackgroundApply.webgl2Supported === 'function' && 97 !global.SiteBackgroundApply.webgl2Supported()) { 98 return Promise.resolve(); 99 }
100 if (global.CloudsBackground && typeof global.CloudsBackground.init === 'function') { 101 return global.CloudsBackground.init(); 102 } 103 return Promise.resolve(); 104 }, 105 onDeactivate: function () { 106 if (global.CloudsBackground && typeof global.CloudsBackground.stop === 'function') { 107 global.CloudsBackground.stop(); 108 } 109 if (global.CloudsBackground && typeof global.CloudsBackground.hide === 'function') { 110 global.CloudsBackground.hide(); 111 } 112 } 113 }, 114 { 115 id: 'aquarium', 116 label: 'Aquarium', 117 description: 'Idle fish tank with swaying plants and underwater light', 118 previewStripes: ['#1e3c72', '#2a5298', '#6ec6ff'], 119 layers: { 120 base: false, 121 aurora: true, 122 caustics: true, 123 bubbles: false 124 }, 125 scripts: [ 126 '/scripts/dependencies/aquariumBackground.js' 127 ], 128 onActivate: function (ctx) { 129 if (global.AquariumBackground && typeof global.AquariumBackground.init === 'function') { 130 return global.AquariumBackground.init(ctx); 131 } 132 return Promise.resolve(); 133 }, 134 onDeactivate: function () { 135 if (global.AquariumBackground && typeof global.AquariumBackground.hide === 'function') { 136 global.AquariumBackground.hide(); 137 } 138 if (global.AquariumBackground && typeof global.AquariumBackground.stop === 'function') { 139 global.AquariumBackground.stop(); 140 } 141 } 142 } 143 ]; 144 145 var byId = {}; 146 PRESETS.forEach(function (preset) { 147 byId[preset.id] = preset; 148 }); 149 150 function getDefaultId() { 151 return DEFAULT_ID; 152 } 153 154 function normalizeId(id) { 155 if (id && byId[id]) return id; 156 return DEFAULT_ID; 157 } 158 159 function getPreset(id) { 160 return byId[normalizeId(id)]; 161 } 162 163 function listPresets() { 164 return PRESETS.slice(); 165 } 166 167 function listPickerOptions() { 168 return PRESETS.map(function (preset) { 169 return { 170 value: preset.id, 171 label: preset.label, 172 stripes: preset.previewStripes ? preset.previewStripes.slice() : null 173 }; 174 }); 175 } 176 177 function isValidId(id) { 178 return !!(id && byId[id]); 179 } 180 181 global.SiteBackgrounds = { 182 DEFAULT_ID: DEFAULT_ID, 183 THREE_CDN: THREE_CDN, 184 getDefaultId: getDefaultId, 185 normalizeId: normalizeId, 186 getPreset: getPreset, 187 listPresets: listPresets, 188 listPickerOptions: listPickerOptions, 189 isValidId: isValidId 190 }; 191})(typeof window !== 'undefined' ? window : this);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.