PageSourceSearch

https://pupwife.com/scripts/dependencies/aquariumBackground.js

js pupwife.com collected 2026-09-30 15:06:08 UTC 8,363 bytes, 231 lines download raw bytes

1/**
2 * Idle Aquarium sitewide background — ocean art, plants, fish, caustics wash.
3 */
4(function (global) {
5    'use strict';
6
7    var CSS_HREF = '/css/aquariumBackground.css';
8    var AQUARIUM_SCRIPT = '/scripts/code stuffs/aquarium.js';
9    var GLOW_SCRIPT = '/scripts/followers/fishBuddyGlow.js';
10    var CAUSTICS_SCRIPTS = [
11        '/scripts/dependencies/webglCaustics.js',
12        '/scripts/dependencies/causticsTextureLoader.js',
13        '/scripts/dependencies/webglAurora.js'
14    ];
15
16    var activeScene = null;
17    var cssLoaded = false;
18    var visible = false;
19
20    function loadScript(src) {
21        if (global.PupwifeScriptLoad && typeof global.PupwifeScriptLoad.once === 'function') {
22            return global.PupwifeScriptLoad.once(src);
23        }
24        return new Promise(function (resolve, reject) {
25            if (document.querySelector('script[src="' + src + '"]')) {
26                resolve();
27                return;
28            }
29            var s = document.createElement('script');
30            s.src = src;
31            s.async = false;
32            s.onload = function () { resolve(); };
33            s.onerror = function () { reject(new Error('Failed to load ' + src)); };
34            document.body.appendChild(s);
35        });
36    }
37
38    function ensureStylesheet() {
39        if (cssLoaded || document.querySelector('link[data-site-aquarium-bg="1"]')) {
40            cssLoaded = true;
41            return Promise.resolve();
42        }
43        return new Promise(function (resolve, reject) {
44            var link = document.createElement('link');
45            link.rel = 'stylesheet';
46            link.href = CSS_HREF;
47            link.setAttribute('data-site-aquarium-bg', '1');
48            link.onload = function () {
49                cssLoaded = true;
50                resolve();
51            };
52            link.onerror = function () { reject(new Error('Failed to load ' + CSS_HREF)); };
53            document.head.appendChild(link);
54        });
55    }
56
57    function insertBeforePageWrap(node) {
58        var anchor = document.getElementById('page-wrap') ||
59            document.getElementById('citrusos-boot') ||
60            document.body.firstChild;
61        if (anchor && anchor.parentNode) {
62            anchor.parentNode.insertBefore(node, anchor);
63        } else {
64            document.body.appendChild(node);
65        }
66    }
67
68    function ensureShellMarkup() {
69        var root = document.getElementById('site-aquarium-root');
70        if (!root) {
71            root = document.createElement('div');
72            root.id = 'site-aquarium-root';
73            root.setAttribute('aria-hidden', 'true');
74            insertBeforePageWrap(root);
75        }
76
77        if (!document.getElementById('site-aquarium-ocean')) {
78            var ocean = document.createElement('div');
79            ocean.id = 'site-aquarium-ocean';
80            root.appendChild(ocean);
81        }
82
83        if (!document.getElementById('site-aquarium-plants')) {
84            var plants = document.createElement('div');
85            plants.id = 'site-aquarium-plants';
86            plants.className = 'plants';
87            root.appendChild(plants);
88        }
89
90        if (!document.getElementById('site-aquarium-fish')) {
91            var fish = document.createElement('div');
92            fish.id = 'site-aquarium-fish';
93            root.appendChild(fish);
94        }
95
96        if (!document.getElementById('fish-glow-overlay')) {
97            var glow = document.createElement('div');
98            glow.id = 'fish-glow-overlay';
99            glow.style.cssText = 'position:fixed;inset:0;pointer-events:none;z-index:4;';
100            insertBeforePageWrap(glow);
101        }
102
103        return root;
104    }
105
106    function setShellVisible(show) {
107        var root = document.getElementById('site-aquarium-root');
108        var ocean = document.getElementById('site-aquarium-ocean');
109        var plants = document.getElementById('site-aquarium-plants');
110        var fish = document.getElementById('site-aquarium-fish');
111        var display = show ? '' : 'none';
112        if (root) root.style.display = display;
113        if (ocean) ocean.style.display = display;
114        if (plants) plants.style.display = display;
115        if (fish) fish.style.display = display;
116        visible = show;
117    }
118
119    function loadCausticsStack(ctx) {
120        if (ctx && typeof ctx.ensureCausticsStack === 'function') {
121            return ctx.ensureCausticsStack().then(function () {
122                if (typeof global.setCausticsTexture === 'function') {
123                    global.setCausticsTexture('/images/your_noise.webp', 0.69);
124                } else if (global.__causticsTextureLoader &&
125                    typeof global.__causticsTextureLoader.loadDefaultNoise === 'function') {
126                    global.__causticsTextureLoader.loadDefaultNoise();
127                }
128            });
129        }
130        var chain = Promise.resolve();
131        if (typeof global.THREE === 'undefined' && global.SiteBackgroun
131ds && global.SiteBackgrounds.THREE_CDN) {
132            chain = chain.then(function () { return loadScript(global.SiteBackgrounds.THREE_CDN); });
133        }
134        CAUSTICS_SCRIPTS.forEach(function (src) {
135            chain = chain.then(function () { return loadScript(src); });
136        });
137        return chain;
138    }
139
140    function loadAquariumScene() {
141        global.__aquariumDeferAutoBoot = true;
142        return loadScript(AQUARIUM_SCRIPT).then(function () {
143            if (!global.AquariumScene || typeof global.AquariumScene.boot !== 'function') {
144                throw new Error('AquariumScene unavailable');
145            }
146        });
147    }
148
149    function loadGlowIfNeeded() {
150        if (document.querySelector('script[src="' + GLOW_SCRIPT + '"]')) {
151            return Promise.resolve();
152        }
153        if (typeof global.THREE === 'undefined' && global.SiteBackgrounds && global.SiteBackgrounds.THREE_CDN) {
154            return loadScript(global.SiteBackgrounds.THREE_CDN).then(function () {
155                return loadScript(GLOW_SCRIPT);
156            });
157        }
158        return loadScript(GLOW_SCRIPT);
159    }
160
161    function bootScene() {
162        if (activeScene) return activeScene;
163        var fishMount = document.getElementById('site-aquarium-fish');
164        var plantsMount = document.getElementById('site-aquarium-plants');
165        if (!fishMount || !global.AquariumScene) return null;
166        activeScene = global.AquariumScene.boot({
167            aquariumEl: fishMount,
168            plantsEl: plantsMount,
169            skipKeydown: true
170        });
171        return activeScene;
172    }
173
174    function init(ctx) {
175        ensureShellMarkup();
176        return ensureStylesheet()
177            .then(function () { return loadCausticsStack(ctx); })
178            .then(function () { return loadAquariumScene(); })
179            .then(function () { return loadGlowIfNeeded(); })
180            .then(function () {
181                setShellVisible(true);
182                bootScene();
183                if (activeScene && typeof activeScene.resume === 'function') {
184                    activeScene.resume();
185                }
186                global.__spaBackgroundReady = true;
187                return true;
188            })
189            .catch(function (err) {
190                console.warn('[aquariumBackground] init failed', err);
191                return false;
192            });
193    }
194
195    function stop() {
196        if (activeScene && typeof activeScene.pause === 'function') {
197            activeScene.pause();
198        }
199    }
200
201    function hide() {
202        setShellVisible(false);
203        stop();
204    }
205
206    function destroy(removeShell) {
207        stop();
208        if (activeScene && typeof activeScene.destroy === 'function') {
209            activeScene.destroy();
210        }
211        activeScene = null;
212        if (removeShell) {
213            var root = document.getElementById('site-aquarium-root');
214            if (root && root.parentNode) root.parentNode.removeChild(root);
215        } else {
216            hide();
217        }
218    }
219
220    global.AquariumBackground = {
221        init: init,
222        stop: stop,
223        hide: hide,
224        destroy: destroy,
225        show: function () {
226            setShellVisible(true);
227            if (!activeScene) bootScene();
228            if (activeScene && typeof activeScene.resume === 'function') activeScene.resume();
229        }
230    };
231})(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.