PageSourceSearch

https://pupwife.com/scripts/effects/siteBackgrounds.js

js pupwife.com collected 2026-09-30 15:05:15 UTC 7,027 bytes, 191 lines download raw bytes

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.