Un favicon en constante movimiento es ciertamente molesto para la mayoría de los usuarios y también daña la accesibilidad; sin embargo, cuando solo está animado por un corto tiempo en respuesta a una acción del usuario o un evento de fondo , como una carga de página, puede proporcionar información visual adicional, por lo tanto mejorar la experiencia del usuario
1. Crea el
elemento Primero, necesitamos crear una animación de lienzo que dibuje un círculo completo, el 100 por ciento en total (esto será importante cuando necesitemos incrementar el arco).
Carga Estoy usando el tamaño de favicon estándar, 16 * 16 píxeles, para el lienzo. Puede usar un tamaño más grande que eso, si lo desea, pero tenga en cuenta que la imagen del lienzo se reducirá al área de 16 2 píxeles cuando se aplique como un favicon.
2. Marque si esta apoyado Dentro del controlador de eventos onload()
, obtenemos una referencia para el elemento lienzo [ cv
] utilizando el método querySelector()
y remitimos su objeto de contexto de dibujo 2D [ ctx
] con la ayuda del método getContext()
.
onload = function () {cv = document.querySelector ('# cvl'), ctx = cv.getContext ('2d'); if (!! ctx) {/ * ... * /}}; También debemos verificar si el lienzo es compatible con el UA asegurándose de que el objeto de contexto de dibujo [ ctx
] existe y no está indefinido . Colocaremos todo el código que pertenece al evento de carga en esta condición if
.
3. Crea las variables iniciales Creemos tres variables globales más , s
para el ángulo inicial del arco , tc
para el id para el temporizador setInterval()
y pct
para el valor porcentual del mismo temporizador . El código tc = pct = 0
asigna 0 como valor inicial para las variables tc
y pct
.
onload = function () {cv = document.querySelector ('# cvl'), ctx = cv.getContext ('2d'); if (!! ctx) {s = 1.5 * Math.PI, tc = pct = 0; }}; Para mostrar cómo se calculó el valor de s
, permítame explicar rápidamente cómo funcionan los ángulos de arco .
Ángulos de arco El ángulo subtendido (el ángulo formado por los dos rayos que definen un arco) de la circunferencia de un círculo es 2π rad , donde rad es el símbolo de la unidad de radianes. Esto hace que el ángulo de un cuarto de arco sea igual a 0.5π rad .
Al visualizar el progreso de la carga , queremos que el círculo en el lienzo se dibuje desde la posición superior en lugar del derecho predeterminado.Yendo en el sentido de las agujas del reloj (el arco de dirección predeterminado se dibuja en el lienzo) desde la posición correcta , el punto superior se alcanza después de tres cuartos , es decir, en un ángulo de 1, 5π rad . Por lo tanto, he creado la variable s = 1.5 * Math.PI
para luego denotar el ángulo inicial para los arcos que se dibujarán en el lienzo.
4. Estilo el círculo Para el objeto de contexto de dibujo, definimos las propiedades lineWidth
y strokeStyle
del círculo que vamos a dibujar en el siguiente paso. La propiedad strokeStyle
representa su color.
onload = function () {cv = document.querySelector ('# cvl'), ctx = cv.getContext ('2d'); if (!! ctx) {s = 1.5 * Math.PI, tc = pct = 0; ctx.lineWidth = 2; ctx.strokeStyle = 'fucsia'; }}; 5. Dibuja el círculo #lbtn
un controlador de evento de clic al botón Cargar [ #lbtn
] que activa un temporizador de intervalo de Intervalo de 60 milisegundos , que ejecuta la función responsable de dibujar el círculo [ updateLoader()
] cada 60 ms hasta que se dibuja completamente el círculo.
El método setInterval()
devuelve un identificador de temporizador para identificar su temporizador que está asignado a la variable tc
.
onload = function () {cv = document.querySelector ('# cvl'), ctx = cv.getContext ('2d'); if (!! ctx) {s = 1.5 * Math.PI, tc = pct = 0, btn = document.querySelector ('# lbtn'); ctx.lineWidth = 2; ctx.strokeStyle = 'fucsia'; btn.addEventListener ('click', function () {tc = setInterval (updateLoader, 60);}); }}; 6. Cree la función personalizada updateLoader()
Es hora de crear la función updateLoader()
personalizada a la que llamará el método setInterval()
cuando se setInterval()
clic en el botón (el evento se desencadena). Déjame mostrarte el código primero, luego podemos aceptar la explicación.
function updateLoader () {ctx.clearRect (0, 0, 16, 16); ctx.beginPath (); ctx.arc (8, 8, 6, s, (pct * 2 * Math.PI / 100 + s)); ctx.stroke (); if (pct === 100) {clearInterval (tc); regreso; } pct ++; } El método clearRect()
borra el área rectangular del lienzo definido por sus parámetros: las coordenadas (x, y) de la esquina superior izquierda. La línea clearRect(0, 0, 16, 16)
borra todo en el lienzo de 16 * 16 píxeles que hemos creado.
El método beginPath()
crea una nueva ruta para el dibujo, y el método stroke()
pinta sobre esa ruta recién creada .
Al final de la función updateLoader()
, el porcentaje de conteo [ pct
] se incrementa en 1 , y antes del incremento comprobamos si es igual a 100 . Cuando es 100 por ciento, el temporizador setInterval()
identificado por el ID del temporizador, tc
se borra con la ayuda del método clearInterval()
.
Los primeros tres parámetros del método arc()
son las coordenadas (x, y) del centro del arco y su radio . Los parámetros cuarto y quinto representan los ángulos de inicio y fin en los que comienza y termina el dibujo del arco.
Ya hemos decidido el punto de inicio del círculo del cargador, que está en el ángulo s
, y será el mismo en todas las iteraciones .
Sin embargo, el ángulo final se incrementará con el porcentaje de conteo , podemos calcular el tamaño del incremento de la siguiente manera. Digamos que el 1% (el valor 1 de 100) es equivalente al ángulo α de 2π en un círculo (2π = ángulo de toda la circunferencia), luego lo mismo puede escribirse como la siguiente ecuación:
1/100 = α / 2π Al reorganizar la ecuación:
α = 1 * 2π / 100 α = 2π / 100 Entonces, el 1% es equivalente al ángulo 2π / 100 en un círculo. Por lo tanto, el ángulo final durante cada incremento porcentual se calcula multiplicando 2π / 100 por el valor porcentual . Luego, el resultado se agrega a s
(ángulo de inicio) , por lo que los arcos se dibujan desde la misma posición de inicio cada vez. Es por eso que utilizamos la fórmula pct * 2 * Math.PI / 100 + s
para calcular el ángulo final en el fragmento de código anterior.
7. Agregue el favicon Coloquemos un elemento de enlace de favicon en el HTML
sección, ya sea directamente o a través de JavaScript.En la función updateLoader()
, primero buscamos el favicon usando el método querySelector()
y lo asignamos a la variable lnk
. Luego, debemos exportar la imagen de lienzo cada vez que se dibuja un arco en una imagen codificada utilizando el método toDataURL()
y asignar ese contenido de URI de datos como la imagen de favicon . Esto crea un favicon animado que es el mismo que el cargador de lona .
onload = function () {cv = document.querySelector ('# cvl'), ctx = cv.getContext ('2d'); if (!! ctx) {s = 1.5 * Math.PI, tc = pct = 0, btn = document.querySelector ('# lbtn'), lnk = document.querySelector ('link [rel = "icono"]') ; ctx.lineWidth = 2; ctx.strokeStyle = 'fucsia'; btn.addEventListener ('click', function () {tc = setInterval (updateLoader, 60);}); }}; function updateLoader () {ctx.clearRect (0, 0, 16, 16); ctx.beginPath (); ctx.arc (8, 8, 6, s, (pct * 2 * Math.PI / 100 + s)); ctx.stroke (); lnk.href = cv.toDataURL ('image / png'); if (pct === 100) {clearTimeout (tc); regreso; } pct ++; } Puedes echarle un vistazo al código completo en Github .
Bonificación: use el cargador para eventos asíncronos Cuando necesite utilizar esta animación de lienzo junto con una acción de carga en una página web, asigne la función updateLoader()
como el manejador de eventos para el evento progress()
de la acción .
Por ejemplo, nuestro JavaScript cambiará así en AJAX :
onload = function () {cv = document.querySelector ('# cvl'), ctx = cv.getContext ('2d'); if (!! ctx) {s = 1.5 * Math.PI, lnk = document.querySelector ('link [rel = "icono"]'); ctx.lineWidth = 2; ctx.strokeStyle = 'fucsia'; } var xhr = new XMLHttpRequest (); xhr.addEventListener ('progress', updateLoader); xhr.open ('GET', 'https://xyz.com/abc'); xhr.send (); }; function updateLoader (evt) {ctx.clearRect (0, 0, 16, 16); ctx.beginPath (); ctx.arc (8, 8, 6, s, (evt.loaded * 2 * Math.PI / evt.total + s)); ctx.stroke (); lnk.href = cv.toDataURL ('image / png'); } En el método arc()
, reemplace el valor porcentual [ pct
] con la propiedad loaded
del evento ; indica la cantidad del archivo que se ha cargado, y en lugar de 100
use la propiedad total
del evento ProgressEvent , que denota el total cantidad a cargar.
No es necesario establecer setInterval()
en tales casos, ya que el evento progress()
se dispara automáticamente a medida que avanza la carga.
22 cosas creativas que la gente hizo con Keycaps de teclado
¿Alguna vez has estado en una situación en la que de repente una de las teclas del teclado deja de funcionar mientras escribes? A veces se requiere un poco de fuerza para que funcione la clave, pero la mayoría de las veces se niega a ceder sin importar cuántas veces continúes presionándola. Finalmente, algunas otras teclas siguen su ejemplo y se ve obligado a reemplazar todo el teclado por completo.Ahora
(Consejos de tecnología y diseño)