أيقونات Favicon المتحركة: اجعل تبويب المتصفح يتحرك (مع عرض حي)

Favicon.im

ربما لاحظت شيئاً يتحرك في أعلى هذا التبويب أثناء قراءتك. هذه أيقونة favicon متحركة — نفس الحيلة التي يستخدمها Gmail لعرض عدد الرسائل الجديدة، ويستخدمها Discord لنقاط الإشعارات، إلا أن أيقونتك يمكن أن تفعل أي شيء يمكنك رسمه على canvas.

هذا المقال يحتوي على عرض حي يمكنك العبث به. اضغط على زر، وراقب تبويب متصفحك يتغير فعلاً. لا توجد لقطات شاشة ولا فيديوهات مدمجة — الـ favicon الذي تنظر إليه الآن هو نفسه العرض التوضيحي.

لماذا قد ترغب في تحريك favicon أصلاً؟

بصراحة، معظم المواقع لا تحتاج إلى ذلك. أيقونة دوّارة في كل تبويب تصبح مزعجة بسرعة وتستهلك المعالج. لكن هناك حالات قليلة حيث تكون مفيدة فعلاً:

  • حالات التحميل أو المعالجة. عمليات الرفع أو التصدير أو البناء طويلة المدى. ينتقل المستخدمون بين التبويبات أثناء الانتظار، وتخبرهم الأيقونة المتحركة أن العمل لا يزال جارياً.
  • شارات الإشعارات. الرسائل الجديدة، الإشارات، التنبيهات. نقطة حمراء تنبض بهدوء يلاحظها المستخدم أسرع من نقطة ثابتة.
  • بيانات حية. لوحات التداول، أدوات المراقبة، نتائج المباريات — أي مكان لا يكفي فيه عنوان التبويب.
  • لحظات للهوية البصرية. أيقونة دوارة لمناسبة عيد، احتفال بيوم الإطلاق. استخدمها بحذر.

إذا لم تكن حالتك من هذه، تخطّ التحريك. أيقونة SVG ثابتة جيدة تتفوق بالفعل في حجم الملف ودعم الوضع الداكن وعمر البطارية.

عرض حي: جرّبها الآن

اختر تأثيراً متحركاً. ثم انظر إلى تبويب متصفحك — تلك الأيقونة الصغيرة في الأعلى هي ما يُعاد رسمه.

معاينة بتكبير 8×

الـ favicon الحقيقي بحجم 16×16 بكسل. التفاصيل صعبة الرؤية بهذا الحجم، لذا يعكس المربع على اليسار نفس الـ canvas بتكبير 8× مع تحجيم بأقرب جار.

الحالة: في الانتظار

تدور حلقة التحريك الآن بالكامل داخل Web Worker، تماماً مثل favicon_worker.js في مكتبة Aymkdn. كل 20 مللي ثانية (50 إطاراً في الثانية) يرسم الـ worker على OffscreenCanvas الخاص به، ويصدّر الناتج عبر convertToBlob + FileReader، ويرسل data URL الناتج إلى الصفحة. الخيط الرئيسي يفعل شيئاً واحداً فقط: تعيين تلك السلسلة في faviconLink.href. لهذا تتحرك الأيقونة الآن بنفس سلاسة عرض GitHub.

تريد رؤية هذا النمط مطبقاً في منتج حقيقي؟ يستخدم Random Picker Wheel أيقونة favicon متحركة تتزامن مع عجلة الاختيار الدوارة — واجهة مبنية على الدوران هي إحدى الحالات النادرة التي تتناسب فيها الأيقونة المتحركة فعلاً مع المنتج. افتح الصفحة، أدِر العجلة، وشاهد أيقونة التبويب تدور معها.

كيف يعمل الأمر فعلاً

ثلاث خطوات. هذه هي التقنية كلها:

// 1. الحصول على عنصر link الخاص بـ favicon أو إنشاؤه
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: يحرّك أثناء التركيز لكنه أحياناً يحدّث الأيقونة بفترات بطيئة. لا تعتمد على حركة سلسة.

في الواقع هذا مقبول لأكثر الحالات شيوعاً — نقاط الإشعارات وحالات التقدم تكفيها التحديثات كل ثانية تقريباً. الدوّارات بسلاسة 60 إطاراً في الثانية في الغالب تجميلية فقط.

حيلة 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. لا يخضع الـ workers للتقييد عندما يكون التبويب في الخلفية، فيستمر التحريك، ويتيح 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 أو عند انتهاء العملية. التبويبات التي تستمر في عرض حركة معطوبة جزئياً بعد التنقل تبدو كأن بها خللاً.

لا تحرّك إلى الأبد. حتى نبضة بسيطة تستنزف بطارية الجوّال. أوقف الحركة عند انتهاء حالة التحميل، أو عندما يقرأ المستخدم الإشعار، أو عندما يفقد التبويب التركيز.

تخطّاها للحالات البسيطة. إذا كنت تريد فقط إظهار "رسالة واحدة غير مقروءة"، غيّر الـ favicon إلى نسخة ثابتة بنقطة حمراء. لا حاجة للتحريك. معظم استخدامات الـ favicon المتحرك مبالَغ فيها.

متى تلجأ إليها

تناسب أيقونات الـ favicon المتحركة:

  • عندما تعكس الحركة حالة حقيقية تهم المستخدم (رفع، معالجة، رسالة جديدة)
  • عندما تكون الصفحة من النوع الذي يعيش في تبويب خلفي
  • عندما لا توصل شارة ثابتة أو مجرد تغيير لعنوان التبويب نفس الرسالة

ولا تناسبها:

  • عندما تكون مجرد زخرفة
  • عندما تعمل الحركة طوال فترة فتح التبويب
  • عندما تستهدف مستخدمين على Safari والجوّال حيث تعمل بالكاد

استورد العرض أعلاه إلى مشروعك، استبدل الألوان والأشكال بهوية علامتك التجارية، وأطلقه. الكود المصدري الكامل هنا في هذه الصفحة — افتح "عرض المصدر"، انسخ، عدّل.

المراجع

  1. Aymkdn/animated-favicon على GitHub — مكتبة favicon متحركة قائمة على Web Worker تستمر في التحريك في التبويبات غير النشطة
  2. The Making of an Animated Favicon — CSS-Tricks — شرح كريس كوييه لتقنية canvas-to-favicon
  3. How to animate a favicon? — Stack Overflow — السلسلة الكلاسيكية بأساليب متعددة وملاحظات على دعم المتصفحات
  4. OffscreenCanvas — MDN — الواجهة البرمجية التي تجعل نمط التحريك عبر Web Worker ممكناً
Check Your Favicon

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.

15M+
Monthly Favicon Requests
100%
Free Forever