Jump to content

mutation/intersection observer to add scroll fade-in effect in web app


Recommended Posts

Posted (edited)


Step one:

 

Add the code below to a file called 'mutation.js':

(function(win) {
    'use strict';

    var listeners = [],
        doc = win.document,
        MutationObserver = win.MutationObserver || win.WebKitMutationObserver,
        observer;



    function ready(selector, fn) {
        // Store the selector and callback to be monitored
        listeners.push({
            selector: selector,
            fn: fn
        });
        if (!observer) {
            // Watch for changes in the document
            observer = new MutationObserver(function(mutations) {
                check()
            });
            observer.observe(doc.documentElement, {
                childList: true,
                subtree: true,
                attributes: true,
                attributeOldValue: true,
            });
        }





        // Check if the element is currently in the DOM
        check();
    }



    function check() {
        // Check the DOM for elements matching a stored selector
        for (var i = 0, len = listeners.length, listener, elements; i < len; i++) {
            listener = listeners[i];
            // Query for elements matching the specified selector
            elements = doc.querySelectorAll(listener.selector);
            for (var j = 0, jLen = elements.length, element; j < jLen; j++) {
                element = elements[j];

                // Make sure the callback isn't invoked with the 
                // same element more than once
                if (!element.ready) {
                    element.ready = true;
                    // Invoke the callback with the element
                    listener.fn.call(element, element);
                }
            }
        }
    }

    // Expose `ready`
    win.ready = ready;

})(this);

This will allow us to monitor when elements are being created in the DOM in emby's web app.

 

Save this file to: '*AppData*\Roaming\Emby-Server\system\dashboard-ui\scripts' folder.

 

Step two:

 

Restart the emby server

 

Step three:

 

open emby web app's 'index.html' file located at: '*AppData*\Roaming\Emby-Server\system\dashboard-ui\index.html'

 

 

Step four:

 

Place the following '<script' tag at the bottom before the end '</body>' tag

<script src="scripts/mutation.js"></script>

Step five:

 

Save it!

 

Step six:

 

Add the following CSS classes to embys Custom CSS (Dashboard >Settings > Custom CSS)

.fade-in{
    opacity: 0;
    transition: opacity 1500ms ease-in;
}

.fade-in.appear {
    opacity: 1;
}

Save the CSS adding by clicking the 'Save' button.

 

Step seven:

 

Back into the 'index.html' file, add this before the end '</body>' tag

<script>
        mutations();

        function mutations() {

            return new Promise(() => {


                const options = {
                    root: null,
                    threshold: 0,
                    rootMargin: "-150px"
                }
                const cardScalableObserver = new IntersectionObserver((entries, cardScalableObserver) => {
                    entries.forEach(entry => {

                        if (!entry.isIntersecting) {
                            if (entry.target.classList.contains('appear')) {
                                entry.target.classList.remove('appear');
                            }
                            return;
                        } else {
                            entry.target.classList.add('appear');

                        }
                    })
                }, options);


                ready('.cardScalable', function(element) {
                    if (!document.querySelector('body').classList.contains('dashboardDocument')) {
                         element.classList.add('fade-in');
                    }

                    element.style.transition = 'ease';

                    cardScalableObserver.observe(element);
                })

            })
        }
</script>

All we did there was create a function that watches for media card elements to be created in the DOM using mutation Observer.

We add the 'fade-in' class from our Custom CSS which makes them have an opacity of zero.

 

We then added those created media card elements to our Intersection Observer, watching them for when they interact with the view-port.

 

When the interact with the view-port we add the 'appear' class to them which causes them to fade-in!

 

When they leave the view-port we remove the 'appear' class which causes them to fade-out back to opacity zero.

 

this will happen for both scrolling Y and scrolling X!

 

this is just the first incarnation of the code, keep an eye out for updates!

 

Thanks!

 

Step seven:

you may need to clear the browser cache to see these changes.

 

TODOs:

1. watch the 'parentElement' of cardScalable because the card text is still visible when the card Image is opacity 0

Edited by chef
StewieGreen
Posted

Brilliant, I just changed the time from 1500ms to 750ms because it was a bit too slow for my liking.  Looks good though! (and I had to add !important to the css, otherwise it didn't work...)

  • Like 1
Posted

I think I have found ways to speed up the code above by leveraging 'requestAnimationFrame' and 'requestIdleCallback'.

 

However edge browser apparently doesn't like the requestIdleCallback function so the console gets riddled with errors.

 

But it does speed up the process

StewieGreen
Posted

I noticed in one of your videos you had the text slide and fade in, how did you get that effect?

Posted

I think you mean on the Details page.

 

You can do this with Custom CSS. Add this to Dashboard>Settings>Custom CSS

#itemDetailPage>div.detailPageContent.padded-bottom-page.detailPageContent-nodetailimg>div.detailPagePrimaryContainer.padded-left.padded-right>div.detailPagePrimaryContent>div>div.nameContainer>h1 {
    font-weight: lighter !important;
    font-variant: petite-caps !important;
    font-size: 3em !important;
    color: black !important;
    animation: tracking-in-expand 1.6s 1.8s cubic-bezier(0.215, 0.610, 0.355, 1.000) both !important;
}

@keyframes tracking-in-expand {
    0% {
        letter-spacing: -0.5em;
        opacity: 0;
    }
    40% {
        opacity: 0.6;
    }
    100% {
        opacity: 1;
        color: white;
    }
}

Might need some fine tuning.

  • Like 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...