Acest tutorial vă va îndruma prin dezvoltarea unui simplu spinner de încărcare SVG pentru utilizarea pe site-urile web mobile. Indicatorii vizuale precum spinner-ul construit în acest tutorial sunt folosite pentru a indica activitatea de fundal și sunt o parte crucială a designului puternic al experienței utilizatorilor!
Acest tutorial presupune că aveți deja cunoștințe de bază în Grafică Vector Scalabilă (SVG), HTML, CSS, JavaScript și jQuery. Cu toate acestea, conținutul este prezentat într-o manieră pas cu pas, care ar trebui să fie suficient de simplă pentru a vă urma.
Ce zici de Raphael?? Vom folosi proiectul Raphaël pentru realizarea desenului SVG în acest tutorial. Pentru a cita din site-ul oficial al proiectului Raphaël:
Raphaël utilizează Recomandarea SVG W3C și VML ca bază pentru crearea graficii. Aceasta înseamnă că fiecare obiect grafic pe care îl creați este, de asemenea, un obiect DOM, astfel încât să puteți atașa sau să le modificați mai târziu. Scopul lui Raphaël este de a oferi un adaptor care să facă arta vectorială de desen compatibilă încrucișată și ușoară.
Pentru a utiliza Raphaël în proiectul dvs., trebuie doar să urmați acești pași:
hârtie var = Raphael (divID, lățime, înălțime);
// Creează cercul la x = 50, y = 40, cu raza 10 var circle = paper.circle (50, 40, 10); // Setează atributul de umplere al cercului în roșu (# f00) circle.attr ("umple", "# f00");
Teoria suficientă! Să începem codarea!
Să începem prin construirea mai întâi a paginii noastre demo în HTML. Ar trebui să arate după cum urmează:
Încărcarea exemplului Spinner Eliberați puterea dispozitivului de încărcare.
În cele din urmă, dar nu în ultimul rând, adăugăm un link unde puteți face clic pentru a "dezlănțui" spinner-ul (adică începe animația de filare).
Eliberați puterea dispozitivului de încărcare.
Acum, că avem marcajele noastre pregătite, trebuie să începem să umplem stilul lipsă.
În ceea ce privește CSS, div divorț (adică) trebuie să fie negru și să ocupe întreg ecranul deasupra tuturor elementelor care nu aparțin rotorului.
Celelalte două diviziuni (adică și) utilizează un ușor "hack" pentru a centra în mod adecvat centura în mijlocul ecranului, indiferent de dimensiunea ecranului sau de locul unde este setată defilarea. Nu o voi explica în acest tutorial, deoarece CSS se referă doar la o pagină demo "dummy", nu la scopul central al acestui tutorial.
În final, fișierul spinner.css ar trebui să arate astfel:
#spinnerFullScreen display: none; lățime: 100%; înălțime: 100%; poziție: fixă; top: 0px; stânga: 0px; fundal-culoare: negru; opacitate: 0; z-index: 9999998; #floater display: table; lățime: 100%; înălțime: 100%; #spinner display: table-cell; vertical-aliniere: mijloc; text-align: centru; z-index: 9999999;
În teorie, spinner-ul nostru este compus dintr-un anumit număr de sectoare (8 din imagine) care au o lungime ("sectorLength") și o lățime ("sectorWidth"). Desigur, aceste sectoare au și o distanță față de centru ("centerRadius").
Dar este aceasta statică? Și animația? Ei bine, animația este doar un mic truc: având toate opacities de sector variind de la 0.0 la 1.0, schimbăm continuu opacitatea fiecărui sector pentru a fi egal cu opacitatea sectorului următor. Confuz? Acesta va deveni probabil mai transparent după ce veți vedea implementarea în JavaScript.
Pentru a crea o bibliotecă reutilizabilă, vom folosi o paradigmă orientată pe obiecte implementată în JavaScript. Biblioteca este construită în jurul unui constructor (funcția Spinner (date)
) și două funcții distincte:
În fișierul spinner.js creat anterior, mai întâi creăm constructorul Spinner-ului, permițând utilizatorului bibliotecii să stabilească unele valori cum ar fi numărul de sectoare, distanța sectoarelor de centru și așa mai departe.
/ ** * creează obiectul Spinner cu valori de date sau valori implicite în cazul în care acestea lipsesc * @param data * @constructor * / funcția Spinner (date) // numărul sectoarelor spinner - default = 12 this.sectorsCount = date.sectorsCount || 12; // distanța de la fiecare sector la centru - default = 70 this.centerRadius = data.centerRadius || 70; // lungimea / înălțimea fiecărui sector - implicit = 120 this.sectorLength = data.sectorLength || 120; // lățimea fiecărui sector al spinner-default = 25 this.sectorWidth = data.sectorWidth || 25; // culoarea rotorului - implicit = alb this.color = data.color || 'alb'; // opacitatea ecranului fullscreen this.fullScreenOpacity = data.fullScreenOpacity; // array de sectoare spinner, fiecare spinner este o cale svg this.sectors = []; // matrice cu opacitatea fiecărui sector this.opacity = []; // raphael spinner obiect this.spinnerObject = null; // id a funcției timeout pentru animația rotativă this.spinnerTick = null;
Acum, la cea mai mare metodă a obiectului spinner, metoda de creare. Această metodă se numește de fiecare dată când utilizatorul dorește să afișeze spinner-ul. Rețineți utilizarea jQuery pentru a selecta elementele noastre. Acesta este locul unde am vorbit id-urile de mai sus:
Spinner.prototype.create = funcția () // afișează fereastra spinner div $ ('# spinnerFullScreen'). Show (); // animă opacitatea întregului ecran div care conține spinner-ul de la 0 la 0,8 $ ('# spinnerFullScreen') animate (opacity: this.fullScreenOpacity, 1000, funcția () );
Continuând împreună cu metoda de creare, efectuăm câteva calcule inițiale, precum dimensiunea totală a rotorului, și pregătim obiectul Raphael pentru a desena secțiunile:
// punctul central al panzei / spinner / raphael object var spinnerCenter = acest.centrulRadius + acest.sectorLength + this.sectorWidth; // diferența de unghi / pas dintre fiecare sector var beta = 2 * Math.PI / this.sectorsCount; // params pentru fiecare sector / cale (culoare accidentală, lățimea cursei, lungimea cursei) var pathParams = "stroke": this.color, "width stroke": this.sectorWidth, "stroke-linecap" rotund "; / ** * creează obiectul Raphael cu o lățime și o înălțime * este egal cu dublul centrului spinner * "spinner" este ID-ul divului unde vor fi desenate elementele * / var paperSize = 2 * spinnerCenter; this.spinnerObject = Raphael ("spinner", paperSize, paperSize);
Următorul este desenul ciclului și construirea unei matrice cu opacitatea actuală a fiecărui sector:
// construiește sectoarele și opacitatea respectivă pentru (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);
Acum, când avem motorul nostru construit și afișat, trebuie să-l animăm. Aceasta este ultima parte a metodei de creare:
/ ** * efectuează un pas de animație și se solicită din nou * @param spinnerObject acest param trebuie să fie trecut * din cauza modificărilor de domeniu atunci când este apelat prin setTimeout funcție * / (function animationStep (spinnerObject) // schimbă spre dreapta opacitatea sectoarele spinnerObject.opacity.unshift (spinnerObject.opacity.pop ()); // actualizează opacitatea sectoarelor pentru (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
În cele din urmă, metoda de distrugere a spinner-ului nostru:
/ ** * distruge spinner-ul și ascunde ecranul complet div * / Spinner.prototype.destroy = funcția () // oprește funcția de animație clearTimeout (this.spinnerTick); // elimină obiectul spinner Raphael this.spinnerObject.remove (); this.spinnerObject = null; / / animates (opacitatea: 0), 2000, function () $ ('# spinnerFullScreen' ) .hide ();); ;
Cu ajutorul codului de centrifugare, acum este momentul să atașăm un eveniment la link, astfel încât atunci când utilizatorul îl dă clic pe el, vom afișa spinner-ul pentru un interval de 6 secunde. Personal, folosesc acest lucru pentru solicitări asincrone către server, iar când cererea este terminată, pur și simplu elimină rotița.
Rețineți că acest cod poate fi utilizat numai după ce sunt încărcate toate bibliotecile de care depinde. Puteți adăuga acest cod în fișierul spinner.js sau într-un alt fișier JavaScript dacă doriți să păstrați fișierul spinner.js independent și reutilizabil pentru alte proiecte.
$ (document) .ready (functie () $ ('# createSpinner'); click (unleashSpinner);); funcția unleashSpinner () var data = ; data.centerRadius = 35; data.sectorLength = 50; data.sectorsCount = 10; data.sectorWidth = 20; data.color = 'alb'; data.fullScreenOpacity = 0.8; var spinner = Spinner nou (date); spinner.create (); setTimeout (funcție () spinner.destroy ();, 6000); return false;
Putem reutiliza variabila spinner de câte ori dorim.
Spinnerul demonstrat în acest tutorial poate fi utilizat în pagini web concepute nu numai pentru dispozitivele mobile, ci și pentru paginile web "normale". Am încercat deja acest lucru cu ambele metode și a funcționat foarte bine!
Pentru a vă testa cunoștințele, puteți lucra la îmbunătățirea implementării actuale a spinner-ului în câteva moduri unice. De exemplu, puteți încerca să schimbați formatul / forma secțiunilor, permițând mișcarea în sensul acelor de ceasornic sau în sensul acelor de ceasornic sau să permiteți unui dezvoltator să aleagă orice id pentru spinner pentru a evita ciocnirile id.
Asta e pentru acest timp. Sper că ți-a plăcut acest tutorial!