Skip to content

Glitch effect when refreshing the home page

Customisation
17 3 2.3k 1
  • Hello friends,

    It’s been a long time since I’ve been on Sudonix and I’m sorry (lots of things to do and I’ve resumed some studies since I was 38 :))

    To make up for it, here is a little script that I managed to create with ChatGpt and other sources. (I’m not a great dev)

    I think code it’s correct and don’t hesitate Mark @phenom if you see anything.

    I’m looking for ways to improve it but it’s functional.

    Here is what I would like to update:

    • The effect works almost everywhere except when you are in a topic. It would be that it also works in a topic therefore.
    • I would also like the effect to work on the entire page. For the moment the left and right navigation bars are ignored without me really knowing why.

    Despite everything, I find the effect quite nice and cool 🙂

    Mark, if you can make the 2 missing points work, I’m in!!!

    See you again!!

    here the code :

    https://github.com/DroidBV8/nodebb-glitch-refresh/tree/main

  • Hello friends,

    It’s been a long time since I’ve been on Sudonix and I’m sorry (lots of things to do and I’ve resumed some studies since I was 38 :))

    To make up for it, here is a little script that I managed to create with ChatGpt and other sources. (I’m not a great dev)

    I think code it’s correct and don’t hesitate Mark @phenom if you see anything.

    I’m looking for ways to improve it but it’s functional.

    Here is what I would like to update:

    • The effect works almost everywhere except when you are in a topic. It would be that it also works in a topic therefore.
    • I would also like the effect to work on the entire page. For the moment the left and right navigation bars are ignored without me really knowing why.

    Despite everything, I find the effect quite nice and cool 🙂

    Mark, if you can make the 2 missing points work, I’m in!!!

    See you again!!

    here the code :

    https://github.com/DroidBV8/nodebb-glitch-refresh/tree/main

    @DownPW can you post some screenshots or perhaps a video so we can see this in action?

  • @phenomlab

    Oh yes sorry, here a gif file (can you copy it to the first post ? I can’t edit my first post) :

    Glitch.gif

  • That looks pretty awesome!

  • That looks pretty awesome!

    @Madchatthew reminds me of the old days when you used to slap the top of your tv if it played up!

  • @Madchatthew reminds me of the old days when you used to slap the top of your tv if it played up!

    @phenomlab Baahahahah oh yeah, I remember that and don’t forget sometime with those old crt monitors as well hahahaha

  • ha ha. I have a code too for that 😉

    I have add monochrome colors-no colors 😉

    • Added a condition in a code function to check if one of the elements necessary for the animation still exists before continuing it. This ensures that the animation does not occur after this element has been removed from the DOM, which can avoid issues where the animation continues indefinitely.

    • Adding comments to the code

  • in Firefox, the effect lasts forever or a few seconds, it depends, and when it lasts forever it is on all pages when you navigate through the left bar. A CTRL-F5 makes it go away.

    This happens when you quickly move from one page to another before the effect is complete. In this case the effect remains in the DOM and is not deleted and therefore the effect remains indefinitely as long as the page is not refreshed via F5.

    @phenomlab If you have an idea for that, it will be very cool !!

  • So it also does it if I press the F5 key several times quickly

  • So it also does it if I press the F5 key several times quickly

    @DownPW that sounds like the loop is either running endlessly or the animation does not fully complete when it hits the next cycle.

  • @phenomlab maybe you are right but it’s really strange that it only affects Firefox !!

    Do you have any ideas for code that might work for it ?

  • @phenomlab

    I have this code who works better for fast refreshes in Firefox. However, the problem now occurs when clicking on a link which opens in a new tab on firefox.

    It would require the same code, the same behavior even when opening a link in a Firefox tab.

    // ------------------------------------------------------------------
    /* Glitch effect when refreshing the nodebb home page (TEST) */
    // ------------------------------------------------------------------
    
    $(document).ready(function() {
        // Variables globales pour le loader
        var glitchInterval;
        var loaderRemoved = false;
    
        // Get the height and width of the screen
        var screenWidth = $(window).width();
        var screenHeight = $(window).height();
    
        // Number of glitch boxes to create
        var numBoxes = 50;
    
        // Create a div to hold the glitch boxes
        var $loader = $("<div>", { id: "DAloader" });
    
        // Create the glitch boxes and add them to the loader div
        for (var i = 0; i < numBoxes; i++) {
            var $box = $("<div>", { class: "box" });
            $box.css({
                width: Math.floor(Math.random() * 200) + "px",
                height: Math.floor(Math.random() * 5) + "px",
                left: Math.floor(Math.random() * screenWidth) + "px",
                top: Math.floor(Math.random() * screenHeight) + "px",
                backgroundColor: getRandomColor()
            });
            $loader.append($box);
        }
    
        // Function to get a random color
        function getRandomColor() {
            var colors = ["#444444ff", "#545454ff", "#636363ff", "#737373ff", "#828282ff", "#929292ff", "#A2A2A2ff", "#B1B1B1ff", "#C1C1C1ff", "#D0D0D0ff", "#E0E0E0ff", "#EFEFEFff", "#FFFFFFff"];
            return colors[Math.floor(Math.random() * colors.length)];
        }
    
        // Function to animate the glitch effect
        function animateGlitch() {
            $(".box").each(function() {
                $(this).css({
                    left: Math.floor(Math.random() * screenWidth) + "px",
                    top: Math.floor(Math.random() * screenHeight) + "px",
                    width: Math.floor(Math.random() * 200) + "px",
                    height: Math.floor(Math.random() * 5) + "px"
                });
            });
        }
    
        // Start the glitch animation with an interval
        glitchInterval = setInterval(animateGlitch, 100);
    
        // Function to clean up loader and stop the animation
        function cleanUpLoader() {
            if (!loaderRemoved) {
                console.log("Cleaning up loader");
                clearInterval(glitchInterval);
                $("#DAloader").remove();
                loaderRemoved = true;
            }
        }
    
        // Clean up before navigating away or refreshing the page
        $(window).on("beforeunload pagehide", function() {
            cleanUpLoader();
        });
    
        // Extra cleanup on unload to handle rapid refreshes
        $(window).on("unload", function() {
            cleanUpLoader();
        });
    
        // Set styles when the page is fully loaded
        $(window).on("load", function() {
            console.log("Page loaded, fading out loader");
            $("#DAloader").css({
                opacity: 0,
                transition: "opacity 0.75s"
            });
            setTimeout(function() {
                cleanUpLoader();
            }, 750); // Adjust the time as needed
        });
    
        // Add the loader div to the page only after setting up all event handlers
        $("body").prepend($loader);
    });
    
  • @phenomlab

    I have this code who works better for fast refreshes in Firefox. However, the problem now occurs when clicking on a link which opens in a new tab on firefox.

    It would require the same code, the same behavior even when opening a link in a Firefox tab.

    // ------------------------------------------------------------------
    /* Glitch effect when refreshing the nodebb home page (TEST) */
    // ------------------------------------------------------------------
    
    $(document).ready(function() {
        // Variables globales pour le loader
        var glitchInterval;
        var loaderRemoved = false;
    
        // Get the height and width of the screen
        var screenWidth = $(window).width();
        var screenHeight = $(window).height();
    
        // Number of glitch boxes to create
        var numBoxes = 50;
    
        // Create a div to hold the glitch boxes
        var $loader = $("<div>", { id: "DAloader" });
    
        // Create the glitch boxes and add them to the loader div
        for (var i = 0; i < numBoxes; i++) {
            var $box = $("<div>", { class: "box" });
            $box.css({
                width: Math.floor(Math.random() * 200) + "px",
                height: Math.floor(Math.random() * 5) + "px",
                left: Math.floor(Math.random() * screenWidth) + "px",
                top: Math.floor(Math.random() * screenHeight) + "px",
                backgroundColor: getRandomColor()
            });
            $loader.append($box);
        }
    
        // Function to get a random color
        function getRandomColor() {
            var colors = ["#444444ff", "#545454ff", "#636363ff", "#737373ff", "#828282ff", "#929292ff", "#A2A2A2ff", "#B1B1B1ff", "#C1C1C1ff", "#D0D0D0ff", "#E0E0E0ff", "#EFEFEFff", "#FFFFFFff"];
            return colors[Math.floor(Math.random() * colors.length)];
        }
    
        // Function to animate the glitch effect
        function animateGlitch() {
            $(".box").each(function() {
                $(this).css({
                    left: Math.floor(Math.random() * screenWidth) + "px",
                    top: Math.floor(Math.random() * screenHeight) + "px",
                    width: Math.floor(Math.random() * 200) + "px",
                    height: Math.floor(Math.random() * 5) + "px"
                });
            });
        }
    
        // Start the glitch animation with an interval
        glitchInterval = setInterval(animateGlitch, 100);
    
        // Function to clean up loader and stop the animation
        function cleanUpLoader() {
            if (!loaderRemoved) {
                console.log("Cleaning up loader");
                clearInterval(glitchInterval);
                $("#DAloader").remove();
                loaderRemoved = true;
            }
        }
    
        // Clean up before navigating away or refreshing the page
        $(window).on("beforeunload pagehide", function() {
            cleanUpLoader();
        });
    
        // Extra cleanup on unload to handle rapid refreshes
        $(window).on("unload", function() {
            cleanUpLoader();
        });
    
        // Set styles when the page is fully loaded
        $(window).on("load", function() {
            console.log("Page loaded, fading out loader");
            $("#DAloader").css({
                opacity: 0,
                transition: "opacity 0.75s"
            });
            setTimeout(function() {
                cleanUpLoader();
            }, 750); // Adjust the time as needed
        });
    
        // Add the loader div to the page only after setting up all event handlers
        $("body").prepend($loader);
    });
    

    @DownPW your css would be better placed inside a css file or in the nodebb global. Whilst the code works, inline css may be causing this issue.

  • I think I have the great code :

    $(document).ready(function() {
        var glitchInterval;
        var loaderId = "DAloader";
        var effectDisplayed = false; // Flag to ensure effect is displayed
        
        // Get the height and width of the screen
        var screenWidth = $(window).width();
        var screenHeight = $(window).height();
    
        // Function to get a random color
        function getRandomColor() {
            var colors = ["#444444ff", "#545454ff", "#636363ff", "#737373ff", "#828282ff", "#929292ff", "#A2A2A2ff", "#B1B1B1ff", "#C1C1C1ff", "#D0D0D0ff", "#E0E0E0ff", "#EFEFEFff", "#FFFFFFff"];
            return colors[Math.floor(Math.random() * colors.length)];
        }
    
        // Function to animate the glitch effect
        function animateGlitch() {
            $(".box").each(function() {
                $(this).css({
                    left: Math.floor(Math.random() * screenWidth) + "px",
                    top: Math.floor(Math.random() * screenHeight) + "px",
                    width: Math.floor(Math.random() * 200) + "px",
                    height: Math.floor(Math.random() * 5) + "px"
                });
            });
        }
    
        // Function to clean up loader and stop the animation
        function cleanUpLoader() {
            if (effectDisplayed) {
                console.log("Cleaning up loader");
                clearInterval(glitchInterval);
                $("#" + loaderId).remove();
            }
        }
    
        // Function to set up the glitch effect
        function setupGlitchEffect() {
            // Create a div to hold the glitch boxes
            var $loader = $("<div>", { id: loaderId });
    
            // Create the glitch boxes and add them to the loader div
            for (var i = 0; i < 50; i++) {
                var $box = $("<div>", { class: "box" });
                $box.css({
                    width: Math.floor(Math.random() * 200) + "px",
                    height: Math.floor(Math.random() * 5) + "px",
                    left: Math.floor(Math.random() * screenWidth) + "px",
                    top: Math.floor(Math.random() * screenHeight) + "px",
                    backgroundColor: getRandomColor()
                });
                $loader.append($box);
            }
    
            // Add the loader div to the page
            $("body").prepend($loader);
    
            // Start the glitch animation with an interval
            glitchInterval = setInterval(animateGlitch, 100);
        }
    
        // Set styles when the page is fully loaded
        $(window).on("load", function() {
            setupGlitchEffect();
            
            // Ensure the effect is visible before fading out
            setTimeout(function() {
                effectDisplayed = true;
                $("#" + loaderId).css({
                    opacity: 0,
                    transition: "opacity 0.75s"
                });
    
                // Clean up after fade out transition
                setTimeout(cleanUpLoader, 750); // Time must match transition duration
            }, 0); // Immediate effect display
        });
    
        // Clean up loader on beforeunload and pagehide
        $(window).on("beforeunload pagehide", function() {
            cleanUpLoader();
        });
    
        // Extra cleanup on unload to handle rapid refreshes
        $(window).on("unload", function() {
            cleanUpLoader();
        });
    });
    

    If you can test it @phenomlab it will be cool !

    EDIT : CSS is on nodeBB ACP


    Improvement of the code to avoid several bugs affecting Firefox only and improvement for other browsers.

    • Added a unique ID for each glitch effect instance and check display status
    • Use of a flag to check the display state of the glitch effect.
    • Forced DOM cleanup using timers (setTimeout) to ensure the glitch effect is completely removed before new instances can be created.
      +Moved effect creation and start to a dedicated function for clarity.
    • The glitch effect is now immediately displayed upon loading the page.
    • The cleanUpLoader now checks if the effect was displayed before cleaning to avoid errors in the DOM.
    • The cleanup function is called after a delay to match the duration of the opacity transition.
    • Simplified DOM cleanup logic to avoid errors.
    • Using local storage via a key in “localStorage” to manage effects and opening links between tabs and in new tabs in Firefox:
    • Simplified DOM cleanup logic to avoid errors.
    • Improved DOM and animation handling.
  • I think I have the great code :

    $(document).ready(function() {
        var glitchInterval;
        var loaderId = "DAloader";
        var effectDisplayed = false; // Flag to ensure effect is displayed
        
        // Get the height and width of the screen
        var screenWidth = $(window).width();
        var screenHeight = $(window).height();
    
        // Function to get a random color
        function getRandomColor() {
            var colors = ["#444444ff", "#545454ff", "#636363ff", "#737373ff", "#828282ff", "#929292ff", "#A2A2A2ff", "#B1B1B1ff", "#C1C1C1ff", "#D0D0D0ff", "#E0E0E0ff", "#EFEFEFff", "#FFFFFFff"];
            return colors[Math.floor(Math.random() * colors.length)];
        }
    
        // Function to animate the glitch effect
        function animateGlitch() {
            $(".box").each(function() {
                $(this).css({
                    left: Math.floor(Math.random() * screenWidth) + "px",
                    top: Math.floor(Math.random() * screenHeight) + "px",
                    width: Math.floor(Math.random() * 200) + "px",
                    height: Math.floor(Math.random() * 5) + "px"
                });
            });
        }
    
        // Function to clean up loader and stop the animation
        function cleanUpLoader() {
            if (effectDisplayed) {
                console.log("Cleaning up loader");
                clearInterval(glitchInterval);
                $("#" + loaderId).remove();
            }
        }
    
        // Function to set up the glitch effect
        function setupGlitchEffect() {
            // Create a div to hold the glitch boxes
            var $loader = $("<div>", { id: loaderId });
    
            // Create the glitch boxes and add them to the loader div
            for (var i = 0; i < 50; i++) {
                var $box = $("<div>", { class: "box" });
                $box.css({
                    width: Math.floor(Math.random() * 200) + "px",
                    height: Math.floor(Math.random() * 5) + "px",
                    left: Math.floor(Math.random() * screenWidth) + "px",
                    top: Math.floor(Math.random() * screenHeight) + "px",
                    backgroundColor: getRandomColor()
                });
                $loader.append($box);
            }
    
            // Add the loader div to the page
            $("body").prepend($loader);
    
            // Start the glitch animation with an interval
            glitchInterval = setInterval(animateGlitch, 100);
        }
    
        // Set styles when the page is fully loaded
        $(window).on("load", function() {
            setupGlitchEffect();
            
            // Ensure the effect is visible before fading out
            setTimeout(function() {
                effectDisplayed = true;
                $("#" + loaderId).css({
                    opacity: 0,
                    transition: "opacity 0.75s"
                });
    
                // Clean up after fade out transition
                setTimeout(cleanUpLoader, 750); // Time must match transition duration
            }, 0); // Immediate effect display
        });
    
        // Clean up loader on beforeunload and pagehide
        $(window).on("beforeunload pagehide", function() {
            cleanUpLoader();
        });
    
        // Extra cleanup on unload to handle rapid refreshes
        $(window).on("unload", function() {
            cleanUpLoader();
        });
    });
    

    If you can test it @phenomlab it will be cool !

    EDIT : CSS is on nodeBB ACP


    Improvement of the code to avoid several bugs affecting Firefox only and improvement for other browsers.

    • Added a unique ID for each glitch effect instance and check display status
    • Use of a flag to check the display state of the glitch effect.
    • Forced DOM cleanup using timers (setTimeout) to ensure the glitch effect is completely removed before new instances can be created.
      +Moved effect creation and start to a dedicated function for clarity.
    • The glitch effect is now immediately displayed upon loading the page.
    • The cleanUpLoader now checks if the effect was displayed before cleaning to avoid errors in the DOM.
    • The cleanup function is called after a delay to match the duration of the opacity transition.
    • Simplified DOM cleanup logic to avoid errors.
    • Using local storage via a key in “localStorage” to manage effects and opening links between tabs and in new tabs in Firefox:
    • Simplified DOM cleanup logic to avoid errors.
    • Improved DOM and animation handling.

    @DownPW will do so ASAP. I am on annual leave currently and not near a PC.

  • No problem dude !

    I hope you have a good vacation. Enjoy your loved ones!

  • DownPWundefined DownPW marked this topic as a regular topic on

Related Topics
  • Custom Page - nodebb

    Solved Customisation custom-pages nodebb
    13
    2
    5 Votes
    13 Posts
    484 Views
    I’m happy to see this
  • NodeBB socket with CloudFlare

    Unsolved Performance socket cloudflare nodebb
    23
    1 Votes
    23 Posts
    7k Views
    @DownPW it’s your only realistic option at this stage.
  • Following the API docs but its not clear ...

    Solved Customisation api nodebb
    8
    2 Votes
    8 Posts
    2k Views
    @Panda you’d be surprised. If you consider that you’d need to use the API to be able to populate a WordPress widget for example (which in turn would of course be PHP), taking this route is still immensely popular.
  • Nodebb design

    Solved General nodebb
    2
    1 Votes
    2 Posts
    874 Views
    @Panda said in Nodebb design: One negative is not being so good for SEO as more Server side rendered forums, if web crawlers dont run the JS to read the forum. From recollection, Google and Bing have the capability to read and process JS, although it’s not in the same manner as a physical person will consume content on a page. It will be seen as plain text, but will be indexed. However, it’s important to note that Yandex and Baidu will not render JS, although seeing as Google has a 90% share of the content available on the web in terms of indexing, this isn’t something you’ll likely lose sleep over. @Panda said in Nodebb design: The “write api” is preferred for server-to-server interactions. This is mostly based around overall security - you won’t typically want a client machine changing database elements or altering data. This is why you have “client-side” which could be DOM manipulation etc, and “server-side” which performs more complex operations as it can communicate directly with the database whereas the client cannot (and if it can, then you have a serious security flaw). Reading from the API is perfectly acceptable on the client-side, but not being able to write. A paradigm here would be something like SNMP. This protocol exists as a UDP (UDP is very efficient, as it is “fire and forget” and does not wait for a response like TCP does) based service which reads performance data from a remote source, thus enabling an application to parse that data for use in a monitoring application. In all cases, SNMP access should be “RO” (Read Only) and not RW (Read Write). It is completely feasible to assume complete control over a firewall for example by having RW access to SNMP and then exposing it to the entire internet with a weak passphrase. You wouldn’t do it (at least, I hope you wouldn’t) and the same ethic applies to server-side rendering and the execution of commands.
  • Top Ranked Forums

    Chitchat nodebb top ranked
    9
    1
    3 Votes
    9 Posts
    2k Views
    The real issue here is that most people consider forums to be “dead” in the sense that nobody uses them anymore, and social media groups have taken their place. Their once dominant stance in the 90’s and early 00’s will never be experienced again, but having said that, there are a number of forums that did in fact survive the social media onslaught, and still enjoy a large user base. Forums tend to be niche. One that immediately sticks out is Reddit - despite looking like it was designed in the 80s, it still has an enormous user base. Another is Stack Overflow, which needs no introduction. The key to any forum is the content it offers, and the more people whom contribute in terms of posting , the more popular and widely respected it becomes as a reliable source of information. Forums are still intensely popular with gamers, alongside those that offer tips on hacking etc.
  • Make logo rotate on page load and hover

    Solved Customisation
    20
    2 Votes
    20 Posts
    3k Views
    @phenomlab grrrrrrr [image: grrr.gif] that simple… Thanks Mark
  • fading in /tags page

    Solved Customisation nodebb
    32
    1
    30 Votes
    32 Posts
    7k Views
    Fix working perfectly
  • [NODEBB] Help for my custom CSS

    Solved Customisation nodebb css bugfix
    237
    49 Votes
    237 Posts
    85k Views
    @baris said: You should change your selectors so it doesn’t look at the entire document. You probably only want to apply fancybox to stuff inside the #content element which is what changes when the user navigates around the page. So use $('#content a').... for your selectors then the forum logo in the header won’t be selected. I modified the JS Fancybox code now and this code and it seem better // --------------------------------------------- // Fancybox Media Reader (Without Website Logo) // --------------------------------------------- if (top.location.pathname !== '/login') { $(window).on('action:posts.loaded', function(data) { console.log("Polling DOM for lazyLoaded images to apply Fancybox"); $(document).ready(function() { $('#content a').not('.forum-logo').not(".avatar").not(".emoji").not(".bmac-noanimate").each(function() { $('#content a[href*=".jpg"], #content a[href*=".jpeg"], #content a[href*=".png"], #content a[href*=".gif"], #content a[href*=".webp"]').addClass("noanimate"); }); }); }); } if (top.location.pathname !== '/login') { $(document).ready(function() { $(window).on('action:ajaxify.end', function(data) { $('#content a').not('.logo').not(".avatar").not(".emoji").not(".bmac-noanimate").each(function() { $('#content a[href*=".jpg"], #content a[href*=".jpeg"], #content a[href*=".png"], #content a[href*=".gif"], #content a[href*=".webp"]').addClass("noanimate"); data.preventDefault() // Strip out the images contained inside blockquotes as this looks nasty :) $('#content blockquote img').remove(); }); Fancybox.bind( '#content a[href*=".jpg"], #content a[href*=".jpeg"], #content a[href*=".png"], #content a[href*=".gif"], #content a[href*=".webp"]', { groupAll: true, } ); }); }); } // Chat fancybox - fires when chat module loaded and AJAX calls new chat $(document).ready(function() { $(window).on('action:chat.loaded', function(data) { // >>> Se limiter au contenu principal uniquement <<< $('#content img').not('.forum-logo').not(".avatar").not(".emoji").not(".bmac-noanimate").each(function() { var newHref = $(this).attr("src"); $(this).wrap("<a class='fancybox' href='" + newHref + "'/>"); $('#content a[href*=".jpg"], #content a[href*=".jpeg"], #content a[href*=".png"], #content a[href*=".gif"], #content a[href*=".webp"]').addClass("noanimate"); data.preventDefault(); // Strip out the images contained inside blockquotes as this looks nasty :) $('#content blockquote img').remove(); }); Fancybox.bind( '#content a[href*=".jpg"], #content a[href*=".jpeg"], #content a[href*=".png"], #content a[href*=".gif"], #content a[href*=".webp"]', { groupAll: true, } ); }); }); For the logo, I must use overflow: visible !important; on [component="brand/logo"] /* --- Logo --- */ [component="brand/logo"] { max-height: 50px; width: auto; height: auto; max-width: 100%; display: block; object-fit: contain; object-position: left center; overflow: visible !important; } Better result !!