当你切换标签时,这是你的眼睛看到的第一件事。
这是解释favicon是什么的一种方式。标签区域是一个比大多数人认为的更珍贵的屏幕空间。如果做得好,除了是带有图标的标签外,它还可以成为表示网页内容或内容发生情况的完美广告牌。
当你在标签上没有活动时,Favicons实际上是最有用的。这是一个例子:
想象一下,您正在将最近暑假期间的照片备份到云服务中。在他们上传时,您已打开一个新标签,以收集有关您去度假的地方的详细信息,以便稍后注释这些照片。有一件事导致了另一件事,现在你正在第七个标签上看Casey Neistat。但是,如果没有重新检查云服务页面以查看照片是否已上传,您将无法继续进行YouTube马拉松。
正是这种情况我们才能发挥创意!如果我们可以动态更改该图标中的像素并显示上传进度,该怎么办?这正是我们在本文中要做的。
在支持的浏览器中,我们可以借助JavaScript,HTML <canvas>
和几个世纪以来的几何体来显示加载/进度动画作为图标。
直接进入,我们将从最简单的部分开始:将图标和画布元素添加到HTML中。
<head>
<link rel="icon" type="image/png" href="" width=32px>
</head>
<body>
<canvas width=32 height=32></canvas>
</body>
在实际使用中,您可能希望隐藏<canvas>
页面,其中一种方法是使用HTML hidden
属性。
<canvas hidden width=32 height=32></canvas>
我将<canvas>
在页面上留下可见的内容,让您看到favicon和canvas图像一起动画。
favicon和canvas都有一个标准的favicon尺寸:32平方像素。
为了演示目的,为了触发加载动画,我在页面上添加一个按钮,点击时将启动动画。这也包含在HTML中:
<button>Load</button>
现在让我们设置JavaScript。首先,检查画布支持:
onload = ()=> {
canvas = document.querySelector('canvas'),
context = canvas.getContext('2d');
if (!!context) {
/* if canvas is supported */
}
};
接下来,添加按钮单击事件处理程序,该处理程序将在画布中提示动画。
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
将是以每个60毫秒的间隔进行绘图的函数,但在我们编码之前,我想要定义要绘制的正方形线的样式。我们做一个渐变。
/* 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;
在drawLoader
,我们将按百分比绘制线条:在前25个区间内,顶线将逐渐绘制; 在第二季度,将绘制右线; 等等。
动画效果是通过实现擦除的<canvas>
每个间隔之前重绘从先前区间的路线长一点。
在每个间隔期间,一旦在画布中完成绘制,它就会快速转换为PNG图像以指定为图标。
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++;
}
现在到数学和绘制线条的代码。
以下是我们如何在前25个区间内逐渐绘制每个区间的顶线:
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)
在所有25个间隔完成时,x的值为32(favicon和画布的大小。)
所以…
x/n = 32/25
x = (32/25) * n
应用此数学并绘制线的代码是:
moveTo(0, 0); lineTo((32/25)*n, 0);
对于接下来的25个区间(右线),我们类似地以y坐标为目标。
moveTo(0, 0); lineTo(32, 0);
moveTo(32, 0); lineTo(32, (32/25)*(n-25));
这是使用其余代码绘制所有四行的指令。
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++;
}
您可以使用任何所需的形状,如果fill
在画布图形中使用该属性,则会产生不同的效果。