Slik lager du en animert favicon-laster med JavaScript
favicons er en viktig del av online branding, de gi en visuell cue til brukere, og hjelpe dem skille nettstedet ditt fra andre. Selv om de fleste favikoner er statiske, er det mulig å lage animerte favikoner også.
Et konstant bevegelige favicon er absolutt irriterende for de fleste brukere, og det skader også tilgjengeligheten, men når det bare animeres i kort tid som svar på en brukerhandling eller en bakgrunnshendelse, for eksempel en sidelast, kan den Gi ekstra visuell informasjon-Derfor forbedrer brukeropplevelsen.
I dette innlegget vil jeg vise deg hvordan du lager en animert sirkulær loader i et HTML-lerret, og hvordan du kan bruke den som et favicon. en animert favicon loader er et flott verktøy for visualisere fremdriften av enhver handling utført på en side, for eksempel filopplasting eller bildebehandling. Du kan se på demo som tilhører denne opplæringen på GitHub også.
1. Opprett
element
Først må vi Lag et lerret animasjon at tegner en full sirkel, totalt 100 prosent (dette vil være viktig når vi må øke buen).
Jeg bruker standard favicon størrelse, 16 * 16 piksler, for lerretet. Du kan bruke en størrelse større enn det hvis du vil, men vær oppmerksom på at lerretbildet blir nedskalert til 162 pikselområde når den brukes som et favicon.
2. Sjekk om
støttes
Inne i på Last()
hendelsehandler, vi få en referanse for lerretelementet [CV
] bruker querySelector ()
metode, og referer dens 2D tegning kontekst objekt [CTX
] ved hjelp av getContext ()
metode.
onload = function () cv = document.querySelector ('# cvl'), ctx = cv.getContext ('2d'); hvis (!! ctx) / * ... * /;
Vi må også sjekke hvis lerretet støttes av UA ved å sørge for at tegningskontekobjektet [CTX
] eksisterer og er ikke udefinert. Vi plasserer all koden som tilhører belastningsarrangementet inn i dette hvis
tilstand.
3. Opprett de første variablene
La oss lage tre globale variabler, s
for startvinkelen til buen, tc
for id for setInterval ()
tidsur, og pct
for prosentverdi av samme tidtaker. Koden tc = pct = 0
tilordner 0 som Opprinnelig verdi for tc
og pct
variabler.
onload = function () cv = document.querySelector ('# cvl'), ctx = cv.getContext ('2d'); hvis (!! ctx) s = 1,5 * Math.PI, tc = pct = 0; ;
For å vise hvordan verdien av s
ble beregnet, la meg raskt forklare hvordan lysvinkler arbeid.
Arc vinkler
De subtended vinkel (vinkelen består av de to strålene som definerer en bue) av omkretsen av en sirkel er 2π rad, hvor rad er radian-enhetssymbolet. Dette gjør vinkel for en kvartbue lik 0.5π rad.
Når visualisere lasting fremgang, Vi vil at sirkelen på lerretet skal tegnes fra topplasseringen i stedet for standardretten.
Går med klokken (standard retningsbue er tegnet på lerretet) fra riktig posisjon, toppunktet er nådd etter tre fjerdedeler, dvs. i en vinkel på 1.5π rad. Derfor har jeg opprettet variabelen s = 1,5 * Math.PI
til senere betegne startvinkelen for buene å bli trukket fra på lerretet.
4. Stil sirkelen
For tegne kontekstobjekt definerer vi linje bredde
og strokeStyle
sirkelens egenskaper vi skal tegne i neste trinn. De strokeStyle
eiendom står for fargen sin.
onload = function () cv = document.querySelector ('# cvl'), ctx = cv.getContext ('2d'); hvis (!! ctx) s = 1,5 * Math.PI, tc = pct = 0; ctx.lineWidth = 2; ctx.strokeStyle = 'fuchsia'; ;
5. Tegn sirkelen
Vi Legg til en klikkhendelsehandler til Load-knappen [#lbtn
] hvilken utløser en setInterval-timer på 60 millisekunder, som utfører funksjonen som er ansvarlig for å tegne sirkelen [updateLoader ()
] hver 60m til sirkelen er helt trukket.
De setInterval ()
metode returnerer en timer id å identifisere timeren som er tildelt til tc
variabel.
onload = function () cv = document.querySelector ('# cvl'), ctx = cv.getContext ('2d'); hvis (!! ctx) s = 1,5 * Math.PI, tc = pct = 0, btn = document.querySelector ('# lbtn'); ctx.lineWidth = 2; ctx.strokeStyle = 'fuchsia'; btn.addEventListener ('klikk', funksjon () tc = setInterval (updateLoader, 60);); ;
6. Opprett updateLoader ()
tilpasset funksjon
Det er på tide å lage skikken updateLoader ()
funksjon som skal være kalt av setInterval ()
metode når knappen klikkes (hendelsen utløses). La meg vise deg koden først, så kan vi gå med forklaringen.
funksjon updateLoader () ctx.clearRect (0, 0, 16, 16); ctx.beginPath (); ctx.arc (8, 8, 6, s, (pct * 2 * Math.PI / 100 + s)); ctx.stroke (); hvis (pct === 100) clearInterval (tc); komme tilbake; pct ++;
De clearRect ()
metode fjerner det rektangulære området av lerretet definert av parametrene: (x, y) koordinatene til øverste venstre hjørne. De clearRect (0, 0, 16, 16)
linje sletter alt i 16 * 16 piksler lerretet vi har opprettet.
De beginPath ()
metode lager en ny bane for tegningen, og slag ()
metode maler på den nyopprettede banen.
På slutten av updateLoader ()
funksjon, den Prosentandel [pct
] økes med 1, og før økningen vi sjekk om den tilsvarer 100. Når det er 100 prosent, er det setInterval ()
tidsur (identifisert av timeren id, tc
) er ryddet med hjelp av clearInterval ()
metode.
De tre første parametrene til bue()
metode er (x, y) koordinater av buenes midtpunkt og dens radius. Den fjerde og femte parameteren representerer start og slutt vinkler hvor tegningen av buen begynner og slutter.
Vi har allerede bestemt startpunktet for lastesirkelen, som ligger i vinkelen s
, og det blir det samme i alle iterasjoner.
Endevinkelen vil imidlertid økning med prosenttellingen, vi kan beregne Størrelsen på inkrementet på følgende måte. Si 1% (verdien 1 av 100) er tilsvarende vinkel α ut av 2π i en sirkel (2π = vinkel på hele omkretsen), da kan det samme skrives som følgende ligning:
1/100 = α/ 2π
Ved omarrangering av ligningen:
α = 1 * 2π / 100 α = 2π/ 100
Så er 1% ekvivalent med vinkelen 2π/ 100 i en sirkel. Dermed er endevinkelen under hvert prosentvis inkrement beregnes ved å multiplisere 2π/ 100 av prosentverdien. Så er resultatet lagt til s
(startvinkel), så buene er trukket fra samme startposisjon hver gang. Det er derfor vi brukte pct * 2 * Math.PI / 100 + s
formel for å beregne sluttvinkelen i kodestykket ovenfor.
7. Legg til favicon
La oss plassere a favicon link element inn i HTML seksjon, enten direkte eller via JavaScript.
I updateLoader ()
funksjon, først vi hente favicon bruker querySelector ()
metode, og tilordne den til lnk
variabel. Da må vi eksporter bildet på lerretet hver gang en bue er tegnet inn i et kodet bilde ved å bruke toDataURL ()
metode, og tilordne data URI-innhold som favicon-bilde. Dette skaper et animert favicon som er det samme som lerretlasteren.
onload = function () cv = document.querySelector ('# cvl'), ctx = cv.getContext ('2d'); hvis (!! ctx) s = 1,5 * Math.PI, tc = pct = 0, btn = document.querySelector ('# lbtn'), lnk = document.querySelector ('link [rel = "ikon"]') ; ctx.lineWidth = 2; ctx.strokeStyle = 'fuchsia'; btn.addEventListener ('klikk', funksjon () tc = setInterval (updateLoader, 60);); ; funksjon 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'); hvis (pct === 100) clearTimeout (tc); komme tilbake; pct ++;
Du kan se på hele koden på Github.
Bonus: Bruk lasteren for asynk hendelser
Når du trenger å bruke dette lerretet animasjon i forbindelse med en belastningshandling på en nettside, tilordne updateLoader ()
funksjon som hendelseshåndterer for framgang()
hendelsen av handlingen.
For eksempel vil JavaScript endres som dette i AJAX:
onload = function () cv = document.querySelector ('# cvl'), ctx = cv.getContext ('2d'); hvis (!! ctx) s = 1,5 * Math.PI, lnk = document.querySelector ('link [rel = "ikon"]'); ctx.lineWidth = 2; ctx.strokeStyle = 'fuchsia'; var xhr = ny XMLHttpRequest (); xhr.addEventListener ('progress', updateLoader); xhr.open ('GET', 'https://xyz.com/abc'); xhr.send (); ; funksjon 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');
I bue()
metode, erstatte prosentverdien [pct
] med lastet
eiendommen til arrangementet-det angir hvor mye av filen som er lastet, og i stedet for 100
bruke Total
eiendom av ProgressEvent, som angir totalbeløpet som skal lastes inn.
Det er ikke behov for setInterval ()
i slike tilfeller, som framgang()
hendelsen er automatisk sparken som lastingen utvikler seg.