Die Entstehung eines animierten Favicons

Avatar of Preethi
Preethi am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Es ist das Erste, wonach Ihre Augen suchen, wenn Sie zwischen Tabs wechseln.

Das ist eine Möglichkeit, zu erklären, was ein Favicon ist. Der Tab-Bereich ist weitaus wertvollerer Bildschirmplatz, als die meisten annehmen. Richtig gemacht, kann es neben einem Label mit Icon auch die perfekte Werbetafel sein, um darzustellen, was auf einer Webseite stattfindet oder was gerade passiert.

Das CSS-Tricks Favicon

Favicons sind tatsächlich am nützlichsten, wenn Sie nicht auf einem Tab aktiv sind. Hier ist ein Beispiel

Stellen Sie sich vor, Sie sichern Fotos von Ihrem letzten Sommerurlaub auf einem Cloud-Dienst. Während sie hochgeladen werden, haben Sie einen neuen Tab geöffnet, um Details über die Orte zu sammeln, an denen Sie im Urlaub waren, um diese Fotos später zu annotieren. Das eine führte zum anderen, und jetzt schauen Sie Casey Neistat auf dem siebten Tab. Aber Sie können Ihren YouTube-Marathon nicht fortsetzen, ohne in angstvollen Intervallen auf die Cloud-Service-Seite zurückzublicken, um zu sehen, ob die Fotos hochgeladen wurden.

Genau in dieser Situation können wir kreativ werden! Was wäre, wenn wir die Pixel in diesem Favicon dynamisch ändern und den Upload-Fortschritt anzeigen könnten? Genau das werden wir in diesem Artikel tun.

In unterstützten Browsern können wir mit Hilfe von JavaScript, dem HTML <canvas>-Element und etwas jahrhundertealter Geometrie eine Lade-/Fortschrittsanimation als Favicon anzeigen.

Direkt einsteigen, wir beginnen mit dem einfachsten Teil: Hinzufügen der Icon- und Canvas-Elemente zum HTML.

<head>
    <link rel="icon" type="image/png" href="" width=32px>
</head>

<body>
    <canvas width=32 height=32></canvas>
</body>

In der praktischen Anwendung möchten Sie das <canvas>-Element auf der Seite ausblenden, und eine Möglichkeit, dies zu tun, ist das HTML-Attribut hidden.

<canvas hidden width=32 height=32></canvas>

Ich lasse das <canvas>-Element auf der Seite sichtbar, damit Sie sowohl das Favicon- als auch das Canvas-Bild zusammen animieren sehen können.

Sowohl das Favicon als auch das Canvas erhalten eine Standard-Favicon-Größe: 32 mal 32 Pixel.

Zu Demozwecken füge ich, um die Ladeanimation auszulösen, einen Button zur Seite hinzu, der die Animation beim Klicken startet. Dies kommt ebenfalls ins HTML

<button>Load</button>

Nun richten wir das JavaScript ein. Zuerst eine Prüfung auf Canvas-Unterstützung

onload = ()=> {
  canvas = document.querySelector('canvas'),
  context = canvas.getContext('2d');
  if (!!context) {
      /* if canvas is supported */
  }
};

Als Nächstes fügen wir den Event-Handler für den Button-Klick hinzu, der die Animation im Canvas auslöst.

button = document.querySelector('button');
button.addEventListener('click', function() { 
    /* A variable to track the drawing intervals */
    n = 0, 
    /* Interval speed for the animation */
    loadingInterval = setInterval(drawLoader, 60); 
});

drawLoader wird die Funktion sein, die mit Intervallen von jeweils 60 Millisekunden zeichnet. Bevor wir sie codieren, möchte ich den Stil der Linien des zu zeichnenden Quadrats definieren. Machen wir einen Farbverlauf.

/* Style of the lines of the square that'll be drawn */
let gradient = context.createLinearGradient(0, 0, 32, 32);
gradient.addColorStop(0, '#c7f0fe');
gradient.addColorStop(1, '#56d3c9');
context.strokeStyle = gradient;
context.lineWidth = 8;

In drawLoader zeichnen wir die Linien prozentual: Während der ersten 25 Intervalle wird die obere Linie schrittweise gezeichnet; im zweiten Viertel wird die rechte Linie gezeichnet; und so weiter.

Der Animationseffekt wird erzielt, indem das <canvas>-Element in jedem Intervall gelöscht wird, bevor die Linie(n) aus dem vorherigen Intervall etwas länger gezeichnet werden.

Während jedes Intervalls wird, nachdem das Zeichnen auf dem Canvas abgeschlossen ist, schnell in ein PNG-Bild umgewandelt und als Favicon zugewiesen.

function drawLoader() {
  with(context) {
    clearRect(0, 0, 32, 32);
    beginPath();
    /* Up to 25% */
    if (n<=25){ 
      /*
        (0,0)-----(32,0)
      */
      // code to draw the top line, incrementally
    }
    /* Between 25 to 50 percent */
    else if(n>25 && n<=50){ 
      /*
        (0,0)-----(32,0)
                  |
                  |
                  (32,32)
      */
      // code to draw the top and right lines.
    }
    /* Between 50 to 75 percent */
    else if(n>50 && n<= 75){ 
      /*
        (0,0)-----(32,0)
                  |
                  |
        (0,32)----(32,32)
      */
      // code to draw the top, right and bottom lines.
    }
      /* Between 75 to 100 percent */
    else if(n>75 && n<=100){
      /*
        (0,0)-----(32,0)
            |      |
            |      |
        (0,32)----(32,32)
      */
      // code to draw all four lines of the square.
    }
    stroke();
  }
  // Convert the Canvas drawing to PNG and assign it to the favicon
  favicon.href = canvas.toDataURL('image/png');
  /* When finished drawing */
  if (n === 100) {
    clearInterval(loadingInterval);
    return;
  }
  // Increment the variable used to keep track of the drawing intervals
  n++;
}

Nun zur Mathematik und zum Code zum Zeichnen der Linien.

So zeichnen wir die obere Linie in jedem Intervall während der ersten 25 Intervalle schrittweise

n = current interval, 
x = x-coordinate of the line’s end point at a given interval.
(y-coordinate of the end point is 0 and start point of the line is 0,0)

Nach Abschluss aller 25 Intervalle ist der Wert von x 32 (die Größe des Favicons und des Canvas).

Also…

x/n = 32/25
x = (32/25) * n

Der Code, um diese Mathematik anzuwenden und die Linie zu zeichnen, lautet

moveTo(0, 0); lineTo((32/25)*n, 0);

Für die nächsten 25 Intervalle (rechte Linie) zielen wir ähnlich auf die y-Koordinate ab.

moveTo(0, 0); lineTo(32, 0);
moveTo(32, 0); lineTo(32, (32/25)*(n-25));

Und hier ist die Anweisung zum Zeichnen aller vier Linien mit dem Rest des Codes.

function drawLoader() {
  with(context) {
    clearRect(0, 0, 32, 32);
    beginPath();
    /* Up to 25% of the time assigned to draw */
    if (n<=25){ 
      /*
        (0,0)-----(32,0)
      */
      moveTo(0, 0); lineTo((32/25)*n, 0);
    }
    /* Between 25 to 50 percent */
    else if(n>25 && n<=50){ 
      /*
        (0,0)-----(32,0)
                  |
                  |
                  (32,32)
      */
      moveTo(0, 0); lineTo(32, 0);
      moveTo(32, 0); lineTo(32, (32/25)*(n-25));
    }
    /* Between 50 to 75 percent */
    else if(n>50 && n<= 75){ 
      /*
        (0,0)-----(32,0)
                  |
                  |
        (0,32)----(32,32)
      */
      moveTo(0, 0); lineTo(32, 0);
      moveTo(32, 0); lineTo(32, 32);
      moveTo(32, 32); lineTo(-((32/25)*(n-75)), 32);
    }
      /* Between 75 to 100 percent */
    else if(n>75 && n<=100){
      /*
        (0,0)-----(32,0)
            |      |
            |      |
        (0,32)----(32,32)
      */
      moveTo(0, 0); lineTo(32, 0);
      moveTo(32, 0); lineTo(32, 32);
      moveTo(32, 32); lineTo(0, 32);
      moveTo(0, 32); lineTo(0, -((32/25)*(n-100)));
    }
    stroke();
  }

  // Convert the Canvas drawing to PNG and assign it to the favicon
  favicon.href = canvas.toDataURL('image/png');
  /* When finished drawing */
  if (n === 100) {
      clearInterval(loadingInterval);
      return;
  }
  // Increment the variable used to keep track of drawing intervals
  n++;
}

Das war's! Sie können den Demo-Code von diesem GitHub-Repo sehen und herunterladen. Bonus: Wenn Sie nach einem kreisförmigen Lader suchen, schauen Sie sich dieses Repo an.

Sie können jede beliebige Form verwenden, und wenn Sie das fill-Attribut bei der Canvas-Zeichnung verwenden, erhalten Sie einen anderen Effekt.