Denna handledning guidar dig genom utvecklingen av en enkel SVG-laddningsspinnare för användning på mobila webbplatser. Visuella indikatorer som spinnaren byggd i denna handledning används för att indikera bakgrundsaktivitet och är en viktig del av stark användarupplevelse design!
Denna handledning förutsätter att du redan har grundläggande kunskaper i skalbar vektorgrafik (SVG), HTML, CSS, JavaScript och jQuery. Innehållet presenteras dock i ett steg för steg som borde vara lätt att följa med.
Vad sägs om Raphaël? Vi kommer att använda Raphaël-projektet för att utföra SVG-ritningen i denna handledning. Att citera från den officiella Raphaël-projektet:
Raphaël använder SVG W3C-rekommendationen och VML som en bas för att skapa grafik. Det betyder att varje grafiskt objekt du skapar också är ett DOM-objekt, så att du kan bifoga JavaScript-händelsehanterare eller ändra dem senare. Raphaels mål är att tillhandahålla en adapter som gör att du kan använda vektorkompatibel tv-webbläsare och enkelt.
För att använda Raphaël i ditt projekt behöver du bara följa dessa steg:
varpapper = Raphael (divID, bredd, höjd);
// Skapar cirkel vid x = 50, y = 40, med radie 10 var cirkel = paper.circle (50, 40, 10); // Sätter fyllningsattributet för cirkeln till rött (# f00) circle.attr ("fill", "# f00");
Nog teori! Låt oss börja kodning!
Låt oss börja med att först bygga vår demosida i HTML. Det ska se ut som följande:
Laddar Spinner Exempel Släpp loss kraften i lastspinnaren.
Sist men inte minst lägger vi till en länk där du kan klicka för att "släppa" spinnaren (det vill säga starta den spinnande animationen).
Släpp loss kraften i lastspinnaren.
Nu när vi har klarat oss måste vi börja fylla i den saknade stilen.
När det gäller CSS måste den yttersta div (dvs) vara svart och uppta hela skärmen ovanpå alla element som inte hör till spinnaren.
De andra två delarna (dvs och) använder en liten "hack" för att centrerar spinnern på mitten av skärmen korrekt oavsett vad skärmstorleken är eller där rullningen är inställd. Jag kommer inte att förklara det på den här handledningen eftersom CSS endast hänför sig till en "dummy" demosida, inte det centrala syftet med denna handledning.
I slutändan ska filen spinner.css se så här ut:
#spinnerFullScreen display: none; bredd: 100%; höjd: 100%; position: fast; topp: 0px; vänster: 0px; bakgrundsfärg: svart; opacitet: 0; z-index: 9999998; #floater display: table; bredd: 100%; höjd: 100%; #spinner display: tabell-cell; vertikaljustering: mitt; text-align: center; z-index: 9999999;
I teorin består vår spinnare av ett visst antal sektorer (8 i bilden) som har en längd ("sectorLength") och en bredd ("sectorWidth"). Naturligtvis har dessa sektorer ett avstånd till centrum också ("centerRadius").
Men är det statiskt? Och vad sägs om animationen? Tja, animationen är bara ett litet knep: med alla sektionsdisperioder som sträcker sig från 0,0 till 1,0, förändras vi kontinuerligt opaciteten i varje sektor för att vara lika med opaciteten i nästa sektor. Förvirrad? Det kommer sannolikt att bli tydligare när du ser implementeringen i JavaScript.
För att skapa ett återanvändbart bibliotek använder vi ett objektorienterat paradigm som implementeras i JavaScript. Biblioteket är byggt runt en konstruktör (funktion Spinner (data)
) och två distinkta funktioner:
I filen spinner.js skapad tidigare skapar vi först Spinnerkonstruktorn, vilket gör det möjligt för bibliotekets användare att ange några värden som antal sektorer, avståndet mellan sektorerna till mitten och så vidare.
/ ** * skapar objektet Spinner med data värden eller standardvärden i fall de saknas * @param data * @constructor * / function Spinner (data) // antal spinnsektorer - default = 12 this.sectorsCount = data.sectorsCount || 12; // avståndet från varje sektor till centrum - default = 70 this.centerRadius = data.centerRadius || 70; // längden / höjden för varje sektor - default = 120 this.sectorLength = data.sectorLength || 120; // bredden på varje sektor i spinnaren - default = 25 this.sectorWidth = data.sectorWidth || 25; // spinnens färg - default = vit this.color = data.color || 'vit'; // fullskärmens opacitet this.fullScreenOpacity = data.fullScreenOpacity; // array av spinner sektorer, varje spinner är en svg-sökväg this.sectors = []; // array med opaciteten för varje sektor this.opacity = []; // raphael spinner objektet this.spinnerObject = null; // id för timeout-funktionen för den roterande animationen this.spinnerTick = null;
Nu på den största metoden för spinnerobjektet skapar metoden. Denna metod kallas varje gång användaren vill visa spinnaren. Notera användningen av jQuery för att välja våra element. Det är här iden vi talade om ovan kommer in:
Spinner.prototype.create = function () // visar fullscreen spinner div $ ('# spinnerFullScreen'). Show (); // animerar opaciteten av fullskärms div som innehåller spinnaren från 0 till 0,8 $ ('# spinnerFullScreen'). animera (opacitet: this.fullScreenOpacity, 1000, funktion () );
Fortsatt tillsammans med skapningsmetoden gör vi några initiala beräkningar, som den totala storleken på spinnaren, och förbereder Raphael-objektet för att rita avsnitten:
// mittpunkten för duken / spinner / raphael objekt var spinnerCenter = this.centerRadius + this.sectorLength + this.sectorWidth; // vinkelskillnad / steg mellan varje sektor var beta = 2 * Math.PI / this.sectorsCount; // Parametrar för varje sektor / sökväg (streckfärg, streckbredd, streckkodspapel) var pathParams = "stroke": this.color "Streckbredd": this.sectorWidth, "stroke-linecap": " runda "; / ** * skapar Raphael-objektet med en bredd och en höjd * motsvarar den dubbla av spinnerns centrum * "spinner" är id av div där elementen kommer att ritas * / var paperSize = 2 * spinnerCenter; this.spinnerObject = Raphael ("spinner", paperSize, paperSize);
Nästa är ritningen av cykeln och byggandet av en matris med nuvarande opacitet för varje sektor:
// bygger sektorerna och respektive opacitet för (var i = 0; i < this.sectorsCount; i++) //angle of the current sector var alpha = beta * i; var cos = Math.cos(alpha); var sin = Math.sin(alpha); //opacity of the current sector this.opacity[i] = 1 / this.sectorsCount * i; /** * builds each sector, which in reality is a SVG path * note that Upper case letter means that the command is absolute, * lower case means relative to the current position. * (http://www.w3.org/TR/SVG/paths.html#PathData) * we move the "cursor" to the center of the spinner * and add the centerRadius to center to move to the beginning of each sector * and draws a line with length = sectorLength to the final point * (which takes into account the current drawing angle) */ this.sectors[i] = this.spinnerObject.path([ ["M", spinnerCenter + this.centerRadius * cos, spinnerCenter + this.centerRadius * sin], ["l", this.sectorLength * cos, this.sectorLength * sin] ]).attr(pathParams);
Nu när vi har byggt vår spinnare och visat, måste vi animera den. Det här är den sista delen av skapningsmetoden:
/ ** * gör ett animationssteg och kallar sig igen * @param spinnerObject denna param måste överföras * på grund av förändringar i omfånget när det kallas genom setTimeout-funktionen * / (funktion animationStep (spinnerObject) // skifter till höger opaciteten av sektorerna spinnerObject.opacity.unshift (spinnerObject.opacity.pop ()); // uppdaterar sektornas opacitet för (var i = 0; i < spinnerObject.sectorsCount; i++) spinnerObject.sectors[i].attr("opacity", spinnerObject.opacity[i]); /** * safari browser helper * There is an inconvenient rendering bug in Safari (WebKit): * sometimes the rendering should be forced. * This method should help with dealing with this bug. * source: http://raphaeljs.com/reference.html#Paper.safari */ spinnerObject.spinnerObject.safari(); /** * calls the animation step again * it's called in each second, the number of sectors the spinner has. * So the spinner gives a round each second, independently the number of sectors it has * note: doesn't work on IE passing parameter with the settimeout function :( */ spinnerObject.spinnerTick = setTimeout(animationStep, 1000 / spinnerObject.sectorsCount, spinnerObject); )(this); ;//end of the create method
Slutligen, vår spinnares förstöringsmetod:
/ ** * förstör spinnaren och gömmer hela skärmen div * / Spinner.prototype.destroy = function () // stoppar animeringsfunktionen clearTimeout (this.spinnerTick); // tar bort Raphael spinner objektet this.spinnerObject.remove (); this.spinnerObject = null; // animerar opaciteten av div till 0 igen och gömmer den (display: none) i slutet $ ('# spinnerFullScreen'). animera (opacitet: 0, 2000, funktion () $ ('# spinnerFullScreen' ).Dölj(); ); ;
Med spinnningskoden på plats är det dags att bifoga en händelse till länken, så att när användaren klickar på det visar vi spinnaren i ett intervall på 6 sekunder. Personligen använder jag detta för asynkrona förfrågningar till servern, och när begäran är över tar jag bara bort spinnaren.
Observera att den här koden endast kan användas när alla bibliotek som spinnaren beror på är laddade. Du kan lägga till den här koden i slutet av filen spinner.js eller i en annan JavaScript-fil om du vill behålla filen spinner.js oberoende och återanvändbar för andra projekt.
$ (dokument) .ready (funktion () $ ('# createSpinner'). klicka (frigör spinn);); funktion unleashSpinner () var data = ; data.centerRadius = 35; data.sectorlength = 50; data.sectorsCount = 10; data.sectorWidth = 20; data.color = 'white'; data.fullScreenOpacity = 0,8; var spinner = ny spinner (data); spinner.create (); setTimeout (funktion () spinner.destroy ();, 6000); returnera false;
Vi kan återanvända spinnervariabeln så många gånger som vi vill.
Spinnaren som visas i denna handledning kan användas på webbsidor som är utformade inte bara för mobila enheter, men också för "normala" webbsidor. Jag har redan försökt detta med båda metoderna, och det fungerade bra!
För att testa din kunskap kan du arbeta med att förbättra det nuvarande spinnarimplementet på några unika sätt. Du kan till exempel försöka ändra formatet / formen på sektionerna, aktivera medurs eller motursriktning, eller aktivera en utvecklare att välja något id för spinnaren för att undvika id-konflikter.
Det är det för den här gången. Jag hoppas att du haft denna handledning!