एनिमेटेड Favicon: अपने ब्राउज़र टैब को हिलाएं (लाइव डेमो के साथ)
पढ़ते हुए शायद आपने इस टैब के ऊपर कुछ हिलता हुआ देखा। यह एनिमेटेड favicon है — वही ट्रिक जो Gmail नई मेल की गिनती के लिए और Discord नोटिफिकेशन डॉट के लिए इस्तेमाल करता है, बस आपका favicon वो कुछ भी कर सकता है जो आप canvas पर खींच सकें।
इस लेख में एक लाइव डेमो है जिसके साथ आप छेड़छाड़ कर सकते हैं। एक बटन क्लिक करें, और देखें कि असल में आपका ब्राउज़र टैब बदल रहा है। न कोई स्क्रीनशॉट, न एम्बेडेड वीडियो — आप अभी जो favicon देख रहे हैं, वही डेमो बन जाता है।
आख़िर favicon को एनिमेट क्यों करें?
ईमानदारी से, ज़्यादातर साइटों को नहीं करना चाहिए। हर टैब में एक घूमता आइकन जल्दी ही चिढ़ाने लगता है, और CPU भी खाता है। पर कुछ ऐसे केस हैं जहाँ यह सच में काम का है:
- लोडिंग या प्रोसेसिंग स्टेट। लंबे चलने वाले अपलोड, एक्सपोर्ट, या बिल्ड। यूज़र इंतज़ार में टैब बदल देते हैं, और एनिमेटेड favicon बताता है कि काम अभी भी चल रहा है।
- नोटिफिकेशन बैज। नए मैसेज, मेंशन, अलर्ट। हल्की पल्स करती लाल डॉट को स्थिर डॉट से तेज़ी से नोटिस किया जाता है।
- लाइव डेटा फीड। ट्रेडिंग डैशबोर्ड, मॉनिटरिंग टूल, स्पोर्ट्स स्कोर — जहाँ भी टैब टाइटल काफ़ी नहीं होता।
- ब्रांड मोमेंट। त्योहार का स्पिनर, लॉन्च-डे का जश्न। संयम से इस्तेमाल करें।
अगर आपका यूज़ केस इनमें से कोई नहीं है, तो एनिमेशन छोड़ दें। एक अच्छा स्टैटिक SVG favicon पहले ही फ़ाइल साइज़, डार्क मोड, और बैटरी लाइफ में जीतता है।
लाइव डेमो: अभी आज़माएँ
एक एनिमेशन चुनें। फिर अपने ब्राउज़र टैब पर देखें — ऊपर वो छोटा-सा आइकन जो रीड्रॉ हो रहा है।
असली favicon 16×16 पिक्सेल का है। इस आकार में डिटेल देखना मुश्किल है, इसलिए बाएँ बॉक्स में वही canvas 8× पर nearest-neighbor स्केलिंग के साथ दिखाया गया है।
स्टेटस: निष्क्रिय
एनिमेशन लूप अब पूरी तरह Web Worker के अंदर चलता है, बिल्कुल वैसे ही जैसे Aymkdn लाइब्रेरी का favicon_worker.js। हर 20 मिलीसेकंड (50fps) पर worker अपने OffscreenCanvas पर ड्रॉ करता है, उसे convertToBlob + FileReader से एक्सपोर्ट करता है, और तैयार data URL पेज पर पोस्ट कर देता है। मेन थ्रेड बस एक काम करता है: उस स्ट्रिंग को faviconLink.href में डाल देता है। इसी वजह से आइकन अब GitHub डेमो जितना ही स्मूद चलता है।
इस पैटर्न को किसी असली प्रोडक्ट में देखना चाहते हैं? Random Picker Wheel अपने घूमते व्हील के साथ एनिमेटेड favicon को सिंक करता है — रोटेशन-बेस्ड UI उन गिने-चुने मामलों में से एक है जहाँ चलता-फिरता आइकन वाकई प्रोडक्ट से मेल खाता है। पेज खोलें, व्हील घुमाएँ, और देखें कि टैब का आइकन भी उसके साथ घूमता है।
यह वास्तव में कैसे काम करता है
तीन स्टेप। बस इतनी ही पूरी टेक्निक है:
// 1. favicon link एलिमेंट पाएँ या बनाएँ
let link = document.querySelector('link[rel~="icon"]');
if (!link) {
link = document.createElement('link');
link.rel = 'icon';
document.head.appendChild(link);
}
// 2. एक छिपे canvas पर फ़्रेम ड्रॉ करें
const canvas = document.createElement('canvas');
canvas.width = 32;
canvas.height = 32;
const ctx = canvas.getContext('2d');
function drawFrame(t) {
const scale = 0.5 + 0.5 * Math.abs(Math.sin(t / 400));
ctx.clearRect(0, 0, 32, 32);
ctx.fillStyle = '#ef4444';
ctx.beginPath();
ctx.arc(16, 16, 14 * scale, 0, Math.PI * 2);
ctx.fill();
// 3. canvas को data URL में एक्सपोर्ट करें और favicon पर लगाएँ
link.href = canvas.toDataURL('image/png');
requestAnimationFrame(drawFrame);
}
requestAnimationFrame(drawFrame);
लगभग 15 लाइन में चलती-फिरती पल्सिंग डॉट तैयार। बाकी सब कुछ बस canvas पर अलग-अलग आकृतियाँ बनाना है।
ब्राउज़र सपोर्ट की हक़ीक़त
यहीं हालात बिगड़ते हैं। ब्राउज़र favicon को कितनी आक्रामकता से एनिमेट करते हैं, इसमें काफ़ी फ़र्क है:
- Firefox: टैब फ़ोकस में न हो तब भी स्मूद एनिमेट करता है। यह गोल्ड स्टैंडर्ड है।
- Chrome / Edge: टैब एक्टिव होने पर एनिमेट होते हैं। टैब बदलने पर
requestAnimationFrameलगभग एक बार प्रति सेकंड पर थ्रोटल हो जाता है, तो एनिमेशन धीमा या रुक जाता है। - Safari: फ़ोकस में एनिमेट करता है पर कभी-कभी आइकन को धीमे अंतराल पर ही अपडेट करता है। स्मूद मोशन की उम्मीद न रखें।
ज़्यादातर सामान्य उपयोगों के लिए यह असल में ठीक है — नोटिफिकेशन डॉट और प्रोग्रेस स्टेट को हर एक सेकंड में अपडेट होना ही काफ़ी है। स्मूद 60fps स्पिनर ज़्यादातर सजावटी ही हैं।
Web Worker ट्रिक (बैकग्राउंड टैब के लिए)
ऊपर का "GitHub-स्टाइल फ़्लिप" बटन Aymkdn/animated-favicon लाइब्रेरी की पहचान वाली एनिमेशन का सीधा पोर्ट है: आइकन A को 3 सेकंड रखें, उसकी चौड़ाई कोसाइन से शून्य तक सिकोड़ें, आइकन B पर स्वैप करें, और फिर उसे वापस फैलाएँ। मैथ सीधे लाइब्रेरी के favicon_worker.js से ली गई है — width = canvas.width * Math.abs(Math.cos(progress * Math.PI)), और जैसे ही progress 0.5 पार करता है, दूसरी इमेज ले लेती है।
Aymkdn की लाइब्रेरी हमसे एक कदम आगे जाती है: वह उस लूप को Web Worker के अंदर चलाती है। टैब बैकग्राउंड में जाने पर worker थ्रोटल नहीं होते, इसलिए एनिमेशन चलता रहता है, और OffscreenCanvas worker को DOM छुए बिना फ़्रेम रेंडर करने देता है।
पैटर्न लगभग ऐसा दिखता है:
// आपके पेज में
const worker = new Worker('favicon-worker.js');
worker.onmessage = (e) => {
if (e.data.type === 'updateFavicon') {
document.querySelector('link[rel~="icon"]').href = e.data.dataUrl;
}
};
worker.postMessage({ type: 'init', images: ['icon-a.png', 'icon-b.png'] });
// favicon-worker.js में
const canvas = new OffscreenCanvas(16, 16);
const ctx = canvas.getContext('2d');
// ...फ़्रेम ड्रॉ करें...
const blob = await canvas.convertToBlob();
const reader = new FileReader();
reader.onloadend = () => self.postMessage({ type: 'updateFavicon', dataUrl: reader.result });
reader.readAsDataURL(blob);
अगर आपका ऐप ऐसा है जिसे यूज़र बैकग्राउंड टैब में पार्क करते हैं — चैट क्लाइंट, बिल्ड डैशबोर्ड, मॉनिटरिंग टूल — तो मेहनत वाजिब है। बाकी मामलों में मेन-थ्रेड वर्शन सरल और काफ़ी अच्छा है।
जानने योग्य कुछ बातें
16×16 या 32×32 का इस्तेमाल करें, इससे बड़ा नहीं। favicon वैसे भी बहुत छोटा रेंडर होता है, और बड़ा canvas मतलब लंबा data URL और हर फ़्रेम पर ज़्यादा CPU। 32×32 साफ़ पिक्सेल के साथ बेस्ट जगह है।
favicon को PNG के रूप में सेट करें, ICO नहीं। canvas.toDataURL('image/png') ही एकमात्र चीज़ है जो भरोसेमंद ढंग से काम करती है। ICO ख़ुद एनकोड करने की कोशिश न करें।
रोकते समय असली favicon वापस लाएँ। एनिमेट शुरू करने से पहले link.href सेव करें और beforeunload पर या ऑपरेशन ख़त्म होने पर रिस्टोर करें। नेविगेशन के बाद टूटी-फूटी एनिमेशन दिखाते टैब बग्गी लगते हैं।
हमेशा एनिमेट न करें। हल्की पल्स भी मोबाइल की बैटरी खींचती है। लोडिंग स्टेट ख़त्म होने पर, यूज़र के नोटिफिकेशन पढ़ लेने पर, या टैब का फ़ोकस छूटने पर एनिमेशन रोक दें।
सरल केस के लिए छोड़ दें। अगर बस "1 अनरीड मैसेज" दिखाना है, तो favicon को स्थिर लाल-डॉट वर्शन पर बदल दें। एनिमेशन की ज़रूरत नहीं। एनिमेटेड favicon के ज़्यादातर उपयोग ज़रूरत से ज़्यादा हैं।
इसे कब अपनाएँ
एनिमेटेड favicon तब फ़िट होते हैं जब:
- एनिमेशन यूज़र की परवाह वाली असली स्टेट दिखाए (अपलोडिंग, प्रोसेसिंग, नया मैसेज)
- पेज ऐसा हो जो बैकग्राउंड टैब में रहता हो
- कोई स्थिर बैज या केवल टैब टाइटल बदलना वही बात नहीं कह पाता
ये तब फ़िट नहीं हैं जब:
- यह सिर्फ़ सजावट है
- टैब खुले रहने तक एनिमेशन चलता रहे
- आप Safari और मोबाइल यूज़र को टार्गेट कर रहे हैं जहाँ यह मुश्किल से काम करता है
ऊपर के डेमो को अपने प्रोजेक्ट में डालें, रंग और आकार अपने ब्रांड के लिए बदलें, और शिप करें। पूरा सोर्स यहीं इस पेज पर है — view source खोलें, कॉपी करें, ढालें।
संदर्भ
- Aymkdn/animated-favicon GitHub पर — Web Worker आधारित एनिमेटेड favicon लाइब्रेरी जो निष्क्रिय टैब में भी एनिमेट करती रहती है
- The Making of an Animated Favicon — CSS-Tricks — क्रिस कोयर का canvas-to-favicon टेक्निक का वॉकथ्रू
- How to animate a favicon? — Stack Overflow — कई तरीक़ों और ब्राउज़र सपोर्ट नोट्स वाला क्लासिक थ्रेड
- OffscreenCanvas — MDN — वह API जो Web Worker एनिमेशन पैटर्न को संभव बनाता है
Use favicon.im to quickly check if your favicon is configured correctly. Our free tool ensures your website's favicon displays properly across all browsers and devices.
Free Public Service
Favicon.im is a completely free public service trusted by developers worldwide.