DEV Community

loading...

Adding a dynamic favicon with users scroll percentage

styxofdynamite profile image Luke ・2 min read

See the effect here

Favicon Scroll

I decided to set myself the challenge of updating a favicon dynamically to show the users percentage scroll through the page.

First up, we introduce a function to generate an SVG as a data URL (which we will use for the favicon)

const faviconHref = (value) => {
    return `data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%22256%22 height=%22256%22 viewBox=%220 0 75 75 %22 fill=%22white%22><text x=%2250%%22 y=%2250%%22 dominant-baseline=%22central%22 text-anchor=%22middle%22 font-size=%2258%22 stroke=%22black%22 fill=%22white%22>${value}</text></svg>`;
};
Enter fullscreen mode Exit fullscreen mode

This function will take an input value and return a corresponding SVG (as a data URL) with the "value" text drawn on it.

The next step is to introduce a function to update the favicon in the page header.

const changeFavicon = (favicon) => {
    if (typeof window === 'undefined') {
        return;
    }
    const link = window.document.querySelector("link[rel*='icon']") || window.document.createElement('link');
    link.type = 'image/svg+xml';
    link.rel = 'shortcut icon';
    link.href = faviconHref(favicon);

    window.document.getElementsByTagName('head')[0].appendChild(link);
};
Enter fullscreen mode Exit fullscreen mode

Next we introduce a function to calculate the users sroll and change the favicon using the above functions.

const calculateScroll = () => {
    const parent = document.body.parentNode;
    let percentage =
        ((document.body.scrollTop || parent.scrollTop) /
            (parent.scrollHeight - parent.clientHeight)) *
        100;

    percentage = Math.round(percentage);

    changeFavicon(percentage);
};
Enter fullscreen mode Exit fullscreen mode

Here we are calculating the users scroll percentage of distance down the page and passing that percentage into the changeFavicon function, which in turns renders an SVG of the passed percentage value.

Finally we need to attach a window Event Listener that will call our calculateScroll function when a users scrolls as well as make an initial call to the function when the script is loaded.

window.addEventListener('scroll', calculateScroll);

//  initial call

calculateScroll();
Enter fullscreen mode Exit fullscreen mode

The above functions can be added to an HTML page, such that when a user scrolls it will update the favicon

Discussion (3)

Collapse
belinde profile image
Franco Traversaro

probably you should change changeFavicon() to not append a favicon every time, but replacing the old one instead. Appending only is a form of memory leak, because the DOM will increase indfinitely when the user scrolls up and down

Collapse
styxofdynamite profile image
Luke Author

Thanks I'll look into that when I get a chance and update accordingly.

Collapse
inrsaurabh profile image
Saurabh Ranjan

Can we use requestAnimationFrame on calculateScroll(); to throttle the request?

I think it will your page from lagging.

Forem Open with the Forem app