PageSourceSearch

https://stuff.steplab.co/static/js/scaredy-egg.0.0.0.js?

js steplab.co collected 2026-10-01 11:51:30 UTC 11,953 bytes, 362 lines download raw bytes

1
2const img = new Image();
3img.src = '/static/images/ice.jpg';
4
5
6loadJSFile("https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js", function() { 
7    console.log('loaded html2canvas')
8    loadJSFile("/static/js/disintegrate.js", function() {
9        console.log('loaded disintegrate')
10        // disintegrate.init();
11    })
12});
13
14
15var scaredyFader;
16
17function scaredycat_init(initial_e) {
18    const navTitle = $('#navbar-mw-nav').attr('title');
19    $('#navbar-mw-nav').removeAttr('title');
20
21    const laserSound = new Audio('/static/audio/laser.mp3');
22    laserSound.preload = 'auto';
23    laserSound.volume = 0.3;
24    laserSound.load();
25
26    const initSound = new Audio('/static/audio/scaredy-alert.mp3');
27    initSound.preload = 'auto';
28    initSound.volume = 0.5;
29    initSound.load();
30
31    const freezeSound = new Audio('/static/audio/freeze.mp3');
32    freezeSound.preload = 'auto';
33    freezeSound.volume = 0.2;
34    freezeSound.load();
35
36    
37    const hitSound = new Audio('/static/audio/too-small.mp3');
38    hitSound.preload = 'auto';
39    hitSound.volume = 1;
40    hitSound.load();
41    
42    const splodeSound = new Audio('/static/audio/bye.mp3');
43    splodeSound.preload = 'auto';
44    splodeSound.volume = 1;
45    splodeSound.load();
46    
47    const tadaSound = new Audio('/static/audio/tada.mp3');
48    tadaSound.preload = 'auto';
49    tadaSound.volume = 1;
50    tadaSound.load();
51    
52    function playScaredySound(sound) {
53        sound.currentTime = 0; // rewind to start if needed
54        sound.play();
55    }
56
57    const brand = $('#navbar-brand');
58    FADER_DESTINATION_OPACITY = '0.5';
59    
60    if (brand.closest('.scaredycat-outer').length) {
61        // already initialised
62        return;
63    }
64    
65    $('body').append(`
66        <div class="scaredycat-outer">
67            <div class="scaredycat-container">
68                <div class="scaredycat-bounds">
69                    <div class="scaredycat"></div>
70                </div>
71            </div>
72        </div>
73    `);
74    
75    scaredyFader = $(`<div id="scaredy-fader"></div>`);
76    scaredyFader.on('click', endScaredy(scaredyFader))
77    
78    $('body').append(scaredyFader);
79    
80    do_on_delay(function() {
81        scaredyFader.css('opacity', FADER_DESTINATION_OPACITY)
82    }, 0)
83    playScaredySound(initSound);
84    
85    // init disintegrate, even though it doesn't seem to work, removing
86    // this will break things
87    disintegrate.init();
88
89    // set boundary box for moving out the way
90    const move_box_bounds = $('.scaredycat-bounds');
91    move_box_bounds.css({left: brand[0].getBoundingClientRect().left - 30})
92    move_box_bounds.append(brand);
93
94    // laser stuff
95    function jumpElement(elem, { height = 100, duration = 600, gravitySteps = 30 } = {}) {
96        if (!elem) return;
97        const startTime = performance.now();
98        const interval = duration / gravitySteps;
99
100        const heights = Array.from({ length: gravitySteps }, (_, i) => {
101            const t = i / (gravitySteps - 1);
102            return -(-4 * (t - 0.5) ** 2 + 1) * height;
103        });
104
105        let i = 0;
106        const offsetTop = elem.offsetTop;
107        const originalPosition = window.getComputedStyle(elem).position;
108        if (originalPosition === "static") elem.style.position = "relative";
109
110        function step() {
111            if (i < heights.length) {
112                elem.style.top = `${heights[i]}px`;
113                i++;
114                setTimeout(step, interval);
115            } else {
116                elem.style.top = "0px";
117            }
118        }
119
120        step();
121    }
122    
123    function shootLaserBullet({
124        targetSelector,
125        speed = 1000,
126        onBeforeHit = () => {},
127        onHit = () => {},
128        onPassThrough = () => {}
129    }) {
130
131        const target = document.querySelector(targetSelector);
132        if (!target) return console.warn("Target element not found");
133
134        const mousePos = { x: window.event.clientX, y: window.event.clientY };
135        const targetRect = target.getBoundingClientRect();
136        const targetCenter = {
137            x: targetRect.left + targetRect.width / 2,
138            y: targetRect.top + targetRect.height / 2
139        };
140
141        const dx = targetCenter.x - mousePos.x;
142        const dy = targetCenter.y - mousePos.y;
143        const angle = Math.atan2(dy, dx);
144        const distanceToTarget = Math.hypot(dx, dy);
145        const totalDistance = 2000;
146
147        const bullet = document.createElement("div");
148        bullet.className = "laser-bullet";
149        bullet.style.left = `${mousePos.x}px`;
150        bullet.style.top = `${mousePos.y}px`;
151        bullet.style.transform = `rotate(${angle}rad)`;
152        document.body.appendChild(bullet);
153
154        const fps = 60;
155        const distancePerFrame = speed / fps;
156
157        let x = mousePos.x, y = mousePos.y;
158        let distanceTraveled = 0, hitFired = false, beforeHitFired = false;
159
160        function animate() {
161            x += Math.cos(angle) * distancePerFrame;
162            y += Math.sin(angle) * distancePerFrame;
163            distanceTraveled += distancePerFrame;
164
165            bullet.style.left = `${x}px`;
166            bullet.style.top = `${y}px`;
167
168            if (!beforeHitFired && distanceTraveled >= distanceToTarget - 200) {
169                onBeforeHit();
170                beforeHitFired = true;
171            }
172
173            if (!hitFired && distanceTraveled >= distanceToTarget) {
174                onHit();
175                hitFired = true;
176                if (brand.hasClass('scaredycat-shifted')) {
177                    bullet.remove();
178                    return;
179                }
180            }
181
182            if (distanceTraveled >= totalDistance) {
183                onPassThrough();
184                bullet.remove();
185            } else {
186                requestAnimationFrame(animate);
187            }
188        }
189
190        playScaredySound(laserSound);
191        requestAnimationFrame(animate);
192    }
193    
194    // movement of logo
195    function scaredycat_moveDiv(mouse, edge, elem, force_animate) {
196        const width = $(elem).outerWidth();
197        let newLeft = edge === "left"
198            ? mouse.pageX + 5
199            : mouse.pageX - width - 20;
200
201        let animateLeft = null;
202        if (newLeft < 0) animateLeft = width + 50;
203        else if (newLeft > $(window).width() - width)
204            animateLeft = mouse.pageX - (width + 30);
205
206        if (newLeft !== undefined) {
207            const left = animateLeft || newLeft;
208            (animateLeft || force_animate)
209                ? $(elem).animate({ left }, 100)
210                : $(elem).css({ left });
211
212            const topNav = $('.top-nav-bunch');
213            const leftEdge = topNav[0].getBoundingClientRect().left - 170;
214            topNav.toggleClass('scaredycat-passerby', parseFloat(left) > leftEdge);
215        }
216    }
217
218    function scaredycat_closestEdge(mouse, elem, force_animate) {
219        const { left, right } = elem.getBoundingClientRect();
220        const mouseX = mouse.pageX;
221        const edge = Math.abs(left - mouseX) < Math.abs(right - mouseX) ? 'left' : 'right';
222        scaredycat_moveDiv(mouse, edge, elem, force_animate);
223    }
224
225    function scaredycat_killLogo() {
226        playScaredySound(hitSound);        
227
228        disintegrate.init(); // re-init to make sure the ice colours are correct
229        stopTremble('#navbar-brand'); // stop trembling
230        shake_element($('#navbar-brand'), 400, 100); // here we go...
231        brand.removeClass('scaredy-teasing')
232
233        killAllListeners();
234
235        do_on_delay(() => {
236            const disObj = disintegrate.getDisObj(brand[0]);
237            disintegrate.createSimultaneousParticles(disObj); // explode!
238            playScaredySound(splodeSound);
239    
240            brand.hide().find('.brand-title strong').addClass('text-danger').text($('#current-user-name .forename').text() + 'lab');
241            brand.find('.brand-title').css('font-family', '"Rock Salt", cursive')
242            brand.find('.icon-slab').removeClass('icon-slab').addClass('fas fa-trophy-alt'); // make trophy
243            
244            $(".scaredycat-bounds").css('left', ''); // move back to orig position
245            brand.removeClass('scaredycat-shifted');
246
247            
248            do_on_delay(() => {
249                brand.fadeIn(500, function() {
250                    
251                    scaredyFader.css('opacity', '0');
252                    do_on_delay(function() {
253                        scaredyFader.remove()
254                    }, 1000)
255                });
256                do_on_delay(function() {
257                    playScaredySound(tadaSound);
258                    confetti_burst({ seconds: 0.8, delay: 0.2 })
259                }, 1500);
260            }, 2000);
261        }, 500);
262    }
263
264    function endScaredy(fader) {
265        return function() {
266            $('.scaredy-teasing').removeClass('scaredy-teasing');
267            $('#navbar-mw').prepend($('#navbar-brand'));
268            $('.scaredycat-outer').remove();
269            fader.css('opacity', '0');
270            do_on_delay(function() {
271                fader.remove()
272            }, 1000);
273            killAllListeners();
274        }
275    }
276
277    // listeners    
278    $(document).on('click.scaredy', '#navbar-mw-nav', function() {
279        shootLaserBullet({
280            targetSelector: "#navbar-brand",
281            onBeforeHit: () => {
282                if (!brand.hasClass('scaredycat-shifted')) {
283                    jumpElement(brand[0], { height: 60, duration: 300 }); // jump out way
284                }
285            },
286            onHit: () => {
287                if (brand.hasClass('scaredycat-shifted')) scaredycat_killLogo(); // git it!
288            },
289            onPassThrough: () => {}
290        });
291    });
292    
293    // click to 'splode
294    brand.on('click', e => {
295        e.preventDefault();
296        scaredycat_killLogo();
297    }); 
298    
299    // freeze
300    var canChangeFreeze = true;
301    
302    $(document).on('keyup.scaredy keydown.scaredy', function(e){
303        if(e.shiftKey) {
304            canChangeFreeze = false;
305            brand.addClass('scaredycat-shifted');
306            playScaredySound(freezeSound);  
307            // start randomly shaking
308            startTremble('#navbar-brand');
309            do_on_delay(function() {
310                brand.removeClass('scaredycat-shifted');
311                stopTremble('#navbar-brand');
312                canChangeFreeze = true;
313                
314            }, 700)  
315        } else {
316            if (canChangeFreeze) {                
317                brand.removeClass('scaredycat-shifted');
318                stopTremble('#navbar-brand');
319            }
320        }
321    } );
322    
323    $(document).on('mouseenter.scaredy mouseover.scaredy', ".scaredycat-bounds,.scaredycat", function(e) {
324        if (!shifted) {
325            scaredycat_closestEdge(e, move_box_bounds[0]);
326        }
327    });
328    
329    $(document).on('mouseout.scaredy', '#navbar-mw-nav', function(e) {
330        if (!e.relatedTarget || !e.currentTarget.contains(e.relatedTarget)) {
331            brand.addClass('scaredy-teasing');
332            // console.log('fader out')
333            // fader.css('opacity', '0');
334        }
335    });
336    
337    $(document).on('mouseover.scaredy', '#navbar-mw-nav', function(e) {
338        if (!e.relatedTarget || !e.currentTarget.contains(e.relatedTarget)) {
339            brand.removeClass('scaredy-teasing');
340            // console.log('fader in')
341            // fader.css('opacity', FADER_DESTINATION_OPACITY);
342        }
343    });
344    
345    $(window).on('resize.scaredy', function(move_e) {
346        move_box_bounds.css({
347            left: 10
348        });
349        $('.top-nav-bunch').removeClass('scaredycat-passerby')
350    })
351    
352    function killAllListeners() {
353        $(document).off('.scaredy'); // stop listening for trembles
354        $(".scaredycat-bounds,.scaredycat").off('mouseenter mouseover'); // remove listeners
355        $(window).off('.scaredy');
356        brand.off('click')
357    }
358    
359
360    scaredycat_closestEdge(initial_e, move_box_bounds[0], true);    
361}
362

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.