UNPKG

favoritos

Version:

Favoritos is a JavaScript plugin that adds some HTML5 canvas magic to your favicon. With just a wee bit of code, we can make some really cool effects.

458 lines (369 loc) 15.1 kB
<!-- Favoritos is a JavaScript plugin that adds some HTML5 canvas magic to your favicon. With just a wee bit of code, we can make some really cool effects. --> <p align="center"> <img width="130" height="120" src="https://raw.githubusercontent.com/webistomin/favoritos/master/assets/logo.svg" alt="Favoritos"> </p> <h1 align="center">Favoritos</h1> <h4 align="center">Favoritos is a JavaScript plugin that adds some HTML5 canvas magic to your favicon. With just a wee bit of code, we can make some really cool effects.</h4> <h5 align="center">⭐️ Star me on GitHub — it helps!</h5> <p align="center"> <a href="https://github.com/webistomin/favoritos/actions/workflows/ci.yml"> <img src="https://github.com/webistomin/favoritos/actions/workflows/ci.yml/badge.svg" alt="GitHub Actions"> </a> <a href="https://codecov.io/gh/webistomin/favoritos"> <img src="https://codecov.io/gh/webistomin/favoritos/branch/master/graph/badge.svg" alt="codecoverage" /> </a> <a href="https://www.codefactor.io/repository/github/webistomin/favoritos"><img src="https://www.codefactor.io/repository/github/webistomin/favoritos/badge" alt="CodeFactor" /></a> <img alt="GitHub issues" src="https://img.shields.io/github/issues/webistomin/favoritos"> <img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/webistomin/favoritos"> <img alt="npm type definitions" src="https://img.shields.io/npm/types/favoritos"> <a href="https://bundlephobia.com/result?p=favoritos"> <img alt="npm bundle size" src="https://img.shields.io/bundlephobia/minzip/favoritos"> </a> </p> <p align="center"> <a href="https://www.npmjs.com/package/favoritos"><img alt="npm" src="https://img.shields.io/npm/v/favoritos" /></a> <a href="https://www.npmjs.com/package/favoritos"><img alt="downloads" src="https://img.shields.io/npm/dt/favoritos" /></a> <a href="https://www.jsdelivr.com/package/npm/favoritos"><img alt="jsdeliver" src="https://img.shields.io/jsdelivr/npm/hy/favoritos?style=rounded"/></a> <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> <img src="https://img.shields.io/badge/all_contributors-1-orange.svg" alt="contributors"> <!-- ALL-CONTRIBUTORS-BADGE:END --> </p> <p align="center"> <a href="#key-features-">Key Features</a><a href="#demo-">Demo</a><a href="#installation-">Installation</a><a href="#how-to-use-">How To Use</a><a href="#browsers-support-">Browsers support</a><a href="#license-">License</a><a href="#contributing-">Contributing</a> </p> ## Key Features ✨ * **Small.** ~ 2.78KB (minified and gzipped). <a href="https://github.com/ai/size-limit">Size Limit</a> controls the size. * **No dependencies.** * **Friendly and flexible configuration** * **Easy to use** * **Typescript** support * **SSR friendly** ## Demo 👀 ### [DEMO](https://favoritos.vercel.app/) ## Installation 🚀 ### Using package managers #### npm ```shell script $ npm install favoritos --save ``` #### yarn ```shell script $ yarn add favoritos ``` ### via CDN Add script right before closing `</body>` tag ```html <script src="https://unpkg.com/favoritos@1.0.1/dist/favoritos.iife.js"></script> or <script src="https://cdn.jsdelivr.net/npm/favoritos@1.0.1/dist/favoritos.iife.js"></script> ``` _Hint:_ for a better performance add [preconnect](https://css-tricks.com/using-relpreconnect-to-establish-network-connections-early-and-increase-performance/) link in the head of your document. ```html <head> <!-- for unkpg cdn --> <link rel="preconnect" href="https://unpkg.com"> <!-- for jsdelivr cdn --> <link rel="preconnect" href="https://cdn.jsdelivr.net"> <!-- dns-prefetch only for IE11 --> <!-- <link rel="dns-prefetch" href="https://unpkg.com"> --> <!-- <link rel="dns-prefetch" href="https://cdn.jsdelivr.net"> --> </head> ``` ## How to use 🤔 ### 1. Initialize favoritos **Option A: Using ES 2015:** ```js import Favoritos from 'favoritos'; const favoritos = new Favoritos({ icon: { // Your options }, badge: { // Your options }, debug: { // Your options }, }); ``` **Option B: Using CommonJS:** ```js const Favoritos = require('favoritos'); const favoritos = new Favoritos({ icon: { // Your options }, badge: { // Your options }, debug: { // Your options }, }); ``` **Option C: Using CDN:** ```js /* Favoritos is available from global namespace */ const favoritos = new Favoritos({ icon: { // Your options }, badge: { // Your options }, debug: { // Your options }, }); ``` ### 2. Add magic to your favicon #### Options #### Icon options <table> <thead> <tr> <th>Option</th> <th>Default value</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><code>iconSelector</code></td> <td><code>'link[rel*="icon"]'</code></td> <td>A selector for your favicon where magic will be drawn.</td> </tr> <tr> <td><code>backgroundColor</code></td> <td><code>'#d21f3c'</code></td> <td>Background color for the icon. Used when rendering the progress bar. May be a string or an array. If an array is passed, a gradient will be drawn. </td> </tr> <tr> <td><code>shape</code></td> <td><code>'circle'</code></td> <td>The shape for the icon. Can take the following values: <code>​​circle</code>, <code>rect</code>. </td> </tr> <tr> <td><code>lineWidth</code></td> <td><code>4</code></td> <td>Line width for your icon.</td> </tr> <tr> <td><code>width</code></td> <td><code>32</code></td> <td>Width for your icon. Initially, there is the width of a standard favicon. </td> </tr> <tr> <td><code>height</code></td> <td><code>32</code></td> <td>Height for your icon. Initially, there is the height of a standard favicon. </td> </tr> </tbody> </table> #### Badge options <table> <thead> <tr> <th>Option</th> <th>Default value</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><code>fontSize</code></td> <td><code>18</code></td> <td>Font size of badge text.</td> </tr> <tr> <td><code>backgroundColor</code></td> <td><code>'#d21f3c'</code></td> <td>Background color for the badge.</td> </tr> <tr> <td><code>fontFamily</code></td> <td><code>'Helvetica, Arial, sans-serif'</code></td> <td>Font family for the badge text.</td> </tr> <tr> <td><code>shape</code></td> <td><code>'circle'</code></td> <td>The shape for the icon. Can take the following values: <code>​​circle</code>, <code>rect</code>. </td> </tr> <tr> <td><code>position</code></td> <td><code>'bottom-right'</code></td> <td>Position for your badge. Can take the following values: <code>top-left</code>, <code>top-right</code>, <code>bottom-left</code>, <code>bottom-right</code>. </td> </tr> <tr> <td><code>minWidth</code></td> <td><code>22</code></td> <td>Minimal width for your badge.</td> </tr> <tr> <td><code>minHeight</code></td> <td><code>22</code></td> <td>Minimal height for your icon.</td> </tr> </tbody> </table> #### Debug options _Debug mode can be useful if you want to look at the favicon near_ <table> <thead> <tr> <th>Option</th> <th>Default value</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td><code>enabled</code></td> <td><code>false</code></td> <td>Turns debugging on and off.</td> </tr> <tr> <td><code>debugSelector</code></td> <td><code>'#favoritos-debug'</code></td> <td>Element selector where the canvas will be drawn.</td> </tr> </tbody> </table> ## 3. Call methods **favoritos.drawBadge()** ```js favoritos.drawBadge('') favoritos.drawBadge(1) favoritos.drawBadge(123) ``` Draws a badge on top of the favicon. With an empty string – an empty badge will be drawn. You can also pass numbers. --- **favoritos.drawImage()** ```js /* Image example */ const img = document.querySelector('.my-image'); favoritos.drawImage(img) /* Video example */ const video = document.querySelector('.my-video'); video.addEventListener('play', function () { function step() { favoritos.drawImage(video) requestAnimationFrame(step) } requestAnimationFrame(step); }) ``` Draws a picture or video instead of your favicon. Takes one argument - the content to be drawn. Image or video **must have** `crossorigin="anonymous"` attribute --- **favoritos.drawProgress()** ```js /* Scroll progress example */ document.addEventListener('scroll', () => { const root = document.documentElement; const scrollTopInPx = root.scrollTop; const pageHeightInPx = root.scrollHeight - root.clientHeight; const scrollPercent = (scrollTopInPx / pageHeightInPx) * 100; const scrollPercentRounded = Math.round(scrollPercent); favoritos.drawProgressBar(scrollPercentRounded); }) /* XHR example */ const formData = new FormData(); formData.append('files', /* Your data */); const xhr = new XMLHttpRequest(); xhr.open('POST', ''); xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); xhr.upload.addEventListener('progress', (event) => { if (event.lengthComputable) { const complete = (event.loaded / event.total * 100 | 0); favoritos.drawProgressBar(complete); } }); xhr.send(formData); ``` Allows you to draw a progress bar instead of your icon. The progress bar shape depends on the option <code>shape</code> passed during library initialization. The method takes two arguments: <code>progress</code> and <code>useFavicon</code>. <code>progress</code> indicates how much has already been completed. Value from 0 to 100. <code>useFavicon</code> indicates whether to draw the progress bar on top of the favicon. --- **favoritos.setOptions()** ```js /* For example, set icon background color to green if task was done */ favoritos.setOptions({ icon: { backgroundColor: 'green' } }) ``` You can change any options for the library. But after the change, you must definitely call the icon renderer with the method of which you use (<code>drawBadge()</code> or <code>drawProgress()</code>). --- **favoritos.setIcon()** ```js /* Change favicon on tab change */ document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible') { document.title = 'Hello again! 😀'; favoritos.setIcon('./on-visible.png') } else { document.title = 'I miss you! 😭'; favoritos.setIcon('./on-visible.png') } }) /* Change favicon on theme change */ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (event) => { const newColorScheme = event.matches ? "dark" : "light"; if (newColorScheme === 'dark') { favoritos.setIcon('./dark-favicon.png') } else { favoritos.setIcon('./light-favicon.png') } }); ``` Simply draws a new favicon. --- **favoritos.reset()** ```js favoritos.reset(); ``` Resets the library to its original state. Draws your default favicon. --- ## Browsers support 🌎 | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari-ios/safari-ios_48x48.png" alt="iOS Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>iOS Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Opera | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/yandex/yandex_48x48.png" alt="Yandex" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)<br/>Yandex | | --------- | --------- | --------- | --------- | --------- | --------- | --------- | | IE11*, Edge 12+| 40+ | 42+ | 10.1+| 10.3+ | 29+| 15.6+ `*` – For IE11 you need to install **Object.assign** polyfill. Also IE11 cannot render base64 icons, so the <code>setIcon</code> method only works there. If you want to send a polyfill only to browsers that need it, there's a handy service called [Polyfill.io](https://polyfill.io/v3/url-builder/) which does just that, it offers a wide array of polyfills. Here's an example of using [polyfill.io](https://polyfill.io/v3/url-builder/) to polyfill only the `Object.assign` feature, so if we put this right before closing `</body>` tag of `index.html` and `Favoritos` script, Polyfill.io will read the user agent and use that information to determine if the browser requires a polyfill for the feature or features listed. Since I'm using Chrome it will send back an empty response since my browser doesn't need it, pretty slick. ```html <script src="https://polyfill.io/v3/polyfill.min.js?features=Object.assign"></script> ``` ## License 📄 ### [MIT](https://github.com/webistomin/favoritos/blob/master/LICENSE) ## Contributing 🎉 Found a bug? Missing a specific feature? Your contributions are always welcome! Please have a look at the [contribution guidelines](https://github.com/webistomin/favoritos/blob/master/CONTRIBUTING.md) first. ## Contributors ✨ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): <!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> <!-- prettier-ignore-start --> <!-- markdownlint-disable --> <table> <tr> <td align="center"><a href="https://github.com/webistomin"><img src="https://avatars0.githubusercontent.com/u/30475699?v=4" width="100px;" alt=""/><br /><sub><b>Alexey Istomin</b></sub></a><br /><a href="#infra-webistomin" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://github.com/webistomin/favoritos/commits?author=webistomin" title="Code">💻</a> <a href="#ideas-webistomin" title="Ideas, Planning, & Feedback">🤔</a></td> </tr> </table> <!-- markdownlint-enable --> <!-- prettier-ignore-end --> <!-- ALL-CONTRIBUTORS-LIST:END --> This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!