Det sier seg selv at SVG ikke er så mye brukt som mange mennesker i nettutviklingssamfunnet, tror det burde være. Setter debatten til side, i denne opplæringen vil jeg demonstrere hvordan man bruker inline SVGer, dekker en rekke teknikker og utforsker samspillet mellom nettside og grafikk. Når det brukes sammen med andre nye standarder i HTML5, JavaScript og CSS3, kan inline SVGs vesentlig legge til brukeropplevelsen.
Du kan samhandle med SVG-elementene ved hjelp av DOM-teknikker, som du ville med andre nettsideelementer.
I denne opplæringen skal vi jobbe gjennom et praktisk eksempel på en inline SVG ved å lage en enkel komponent som representerer en rekorddekk. Platen vil spinne, og brukeren vil kunne samhandle med den - trykke for å senke den ned og slippe for å øke hastigheten opp igjen. SVG vil også inneholde en knapp som brukere kan klikke for å endre posten, noe som gjør at utseendet endres noe. De synlige SVG-elementene vil bli forbedret med gradienter og drop-shadow filtre.
Sjekk ut demoen nå slik at du har en klar ide om hva vi bygger.
Som du sannsynligvis vil være oppmerksom, faller SVG-er innenfor de nye HTML5-standardene, så koden vi bruker i denne opplæringen, støttes ikke fullt ut på alle nettlesere. Selv om inline SVGer er teoretisk støttet i alle gjeldende versjoner av de store nettleserne, er de interne animasjonene og de interaktive effektene vi bruker, ikke så godt støttet enda ennå. Det endelige resultatet skal fungere riktig i dagens versjoner av Firefox, Chrome og Opera. Som alltid med HTML5-teknikker, sørg for at du ikke stole på disse effektene i noen levende nettsteder du jobber med, og inkludere alternativer der det er mulig.
La oss grave i, og begynn med å lage en HTML5-sideoversikt, slik som:
En av de viktigste fordelene ved å bruke SVG er hvordan skalerbar det er. For å utnytte dette skal vi først og fremst bruke relative verdier for å definere SVG-innholdet. Legg til et beholderelement for SVG i sidekroppen:
For å se hvordan SVG sitter i det inneholdende elementet, legg til følgende i stilen i sidens hode:
#picHolder bakgrunn: #dedeff; grense: 1px solid # 666666;
I beholderelementet i kroppen på siden din, legg til SVG-elementets disposisjon, som følger:
Vi har satt bredden og høyden til 100%, da vi skal spesifisere bredden på det inneholdende elementet. I stedet for å spesifisere dimensjonene eksplisitt, vil vi i stedet bruke en JavaScript-funksjon for å avdekke hvor lett du kan skalere SVG opp og ned. Du kan inkludere en fast bredde og høyde i den åpne SVG-taggen eller stilavsnittet.
De synlige figurene i grafikken vil bli definert i SVG-elementet. Før det vil vi jobbe på defs seksjon. De defs delen er der du plasserer definisjoner som du senere kan se når du lager dine figurer. For denne opplæringen, defs delen skal inneholde definisjoner for noen gradientfyll og et par fallskygger. Legg til denne nye delen i SVG-elementet:
Elementene vi plasserer i denne delen, vises ikke i bildet, men vil bli brukt som fyll og filtre for de former som gjør. Vi vil inkludere flere gradient fyllinger; så la oss jobbe gjennom hverandre igjen.
Først opp er en lineær gradient:
Denne gradienten skal spesifiseres som fyll for bakgrunnsrektangelområdet. De x1 og y1 Attributene representerer startpunktene for gradienten i den fylte formen, med gradienten som utfolder seg derfra til punktet representert ved x2 og y2. I dette tilfellet vil graden løpe fra topp til bunn. Stoppelementene representerer fargepunkter i gradienten. Den første sier at 10% fra begynnelsen av gradienten vil være en solid mørk rød farge og den andre stopper at 90% fra slutten av graden blir en gul farge. Mellom disse to punktene vil gradienten blande fargene til hverandre. Begge farger har full opasitet.
Deretter la vi legge til en gradient for selve platen. Denne er litt mer kompleks - det er en radial gradient med flere fargestopp:
En radial gradient starter fra innsiden av sirkelen, med de innerste og ytre delene av sirkelen definert av cx, cy, fx og fy, oppført langs radiusen. I dette tilfellet vil den radiale gradienten okkupert hele den sirkulære rekordformen. Hovedparten av platen blir svart, med to ringer med litt lysere farge som representerer de glattere delene i midten av platen og kantene. Vi vil plassere en etikett på platen i sentrum, slik at den første oppdateringen av lysere farge på platen vil vises like utenfor det. Legg til etikettgradientfylling neste:
Dette er en enkel lineær gradient som vil bli brukt som fyll på den sirkulære plateselskapet. Vær imidlertid oppmerksom på at gradient-ID har en null på slutten av den. Dette skyldes at vi skal legge til en interaktiv funksjon, slik at brukeren kan "endre posten". En JavaScript-funksjon vil bytte mellom en rekke gradientfyll for etikettelementet. Til dette formål legger du til et annet par gradienter:
Gradienterne har hver en ID ender med et økende heltall, slik at vi kan iterere gjennom dem i JavaScript. Definer nå en annen gradient for å skape en skinneeffekt på toppen av posten:
Denne gangen bruker gradienten opak og alfa gjennomsiktig farge; effekten vil være en subtil skinne over posten. Til slutt trenger vi en metallfylling for knapp og spindel:
Denne gangen er den radiale gradienten litt utenfor sentrum for å skape en følelse av dybde og lys, som vil bli komplettert med et dråpeskyggefilter.
Før vi er ferdig med defs del, legg til et par drop shadows for å gi noen av figurene litt mer dybde:
Denne kommer til å vises bak rekordområdet. De x, y, bredde og høyde Egenskaper refererer til posisjon og dimensjoner i formen ved hjelp av dette filteret. Forskjellen definerer skyggen i forhold til den opprinnelige formen. Uklarheten forhindrer forskyvningsformen i å være farge, slik at den ser ut som en skygge. I dette tilfellet vises bare skyggen, ikke selve formen - skyggen skal defineres av en dedikert form som vil bli plassert bak rekordformen. For brukerens kontroller, som er sirkulære og metalliske, vil vi også ha en dråpeskygge, men vi ønsker at formen selv skal vises også:
Denne hovedforskjellen her, bortsett fra skyggenes skala, er blandingselementet, som vil bevare den opprinnelige formen samtidig som den viser skyggen rundt den.
Det er nok forberedelse; la oss fortsette med grafikken! Hvert element du legger til i SVGs kropp vil bli vist på toppen av tidligere oppførte elementer, så vi vil jobbe fra bunnen, begynner med figurene på baksiden og slutter med de på forsiden.
Først legger du til et rektangelform for bakgrunnen:
De rect Elementets dimensjoner og posisjon er spesifisert i forhold til den inneholdende SVG, som, hvis du husker, er i forhold til størrelsen på det inneholdende elementet. Vi vil sette dette senere i JavaScript. Vi vil bruke relative størrelses- og posisjonsverdier der det er mulig, slik at hele bildet plus animasjon og samhandling kan skalere opp eller ned på etterspørsel. Legg merke til at elementfyllingen spesifiserer en av gradienter som vi definerte, ved hjelp av ID-attributtet.
Neste opp fra bunnen er rekordskyggen, ved hjelp av en av de skyggefiltre vi opprettet:
Skyggen kommer til å ligge bak posten, som en sirkulær form med en radius som er omtrent en tredjedel av plassen som er tildelt bildet, plassert i midten. Siden filteret i dette tilfellet ikke gjelder blanding med bildet, vil sirkelen i seg selv ikke vises, bare skyggen.
Neste opp er posten selv:
Som med skyggen, den cx og cy Attributter representerer sentrum av platen, som er sentrert i bildet horisontalt og vertikalt, med en radius på omtrent en tredjedel. Igjen bruker vi en av de gradienter vi definerte, som vi vil gjøre i hver form.
På toppen av posten er etiketten, så legg den til neste:
Etikettsirkelen har samme sentrale punkt som posten, som strekker seg over en tredjedel av veien. Vi starter med den første av alternativene for etikettgradienten vi definerte, og vil implementere brukeren som bytter mellom disse senere - vi inkluderer en ID-attributt her for å referere til dette elementet i JavaScript.
Nå, la oss legge litt skinne på toppen av posten:
Når platen spinner, kommer den til å bevege seg til høyre og ned litt, så vi holder skinnen litt mindre enn platen slik at den ikke ser ut til å spre seg utover den når den beveger seg. Dette elementet har også et ID-attributt for å oppdage brukerinteraksjon.
For fullstendighet, la oss legge til en liten spindel i midten av posten:
Denne formen bruker metallisk gradienten vi opprettet. Vi bruker også det andre dråpeskyggefilteret, som inkluderer blanding slik at formen og skyggen begge vises.
Sist men ikke minst, trenger vi en liten knapp for brukere å kontrollere endringen av posten, med samme fyll og filter som spindelen:
Denne gangen, i stedet for et selvlukkende element, adskiller vi åpnings- og lukkekretsens koder. Dette skyldes at vi skal animere knappen når brukere klikker på den, og vil inneholde animasjonseffekten mellom disse kodene. Legg merke til at vi har vært i stand til å gjenbruke fylle og filtrere elementer fra defs seksjon. Her er det første utseendet på grafikken når sidedimensjonene er på plass:
Hvert element du legger til i SVGs kropp vil bli vist på toppen av tidligere oppførte elementer.
Nå har vi våre visuelle elementer på plass, la oss legge til litt animasjon. Vi kan gjøre rekordspinnet ved hjelp av SVG animasjonstransformasjoner, som er en utvidelse av SMIL animasjon. Disse animerte effektene er definert i SVG-oppslaget. En effekt gjelder hva som helst SVG-element som det ser ut i. Du kan bruke CSS3-transformasjoner på SVG-elementer, men de SMIL-baserte alternativene gir deg større kontroll.
Vi skal inkludere to enkle animasjoner: posten skal spinne og knappen kommer til å bevege seg litt når brukeren klikker på den. La oss starte med litt mer rett frem animasjon for knappen.
På innsiden av knappformelementet, mellom de åpnings- og lukkekretsene vi opprettet, legger du til animasjonstransformen som følger:
De animateTransform gjelder for et XML-attributt i elementet det vises i. I dette tilfellet er det en translatetransformasjon. De fra og til Attributter representerer start- og sluttposisjonene for elementet - disse er i forhold til startposisjonen, slik at knappen skal bevege seg til høyre og ned av en enkelt piksel. Transformasjonen vil begynne når en bruker klikker, går over en tiendedel av et sekund, og utfører en gang. Knappen kommer tilbake til sin opprinnelige posisjon når animasjonen fullføres. Tips: For å beholde et element i sluttposisjonen etter en animasjon, spesifiser fylle = "fryse".
Nå for å spinne oppføringen. en animateTransform gjelder for et SVG-element, men vi trenger at spinnen skal gjelde for mer enn ett element - spesielt til platen og etiketten (ikke til skinne eller skygge). I stedet for å lage separate animasjoner for hver og utføre dem samtidig, kan vi bruke en enkelt transformasjon ved å gruppere disse elementene sammen. Før sirkelelementet som representerer posten (med "recordGrad" som sin fylling) legger du til en åpningsgruppe-tagg:
Etter sirkelen som representerer etiketten, lukk gruppen:
Legg nå transformasjonen før denne lukkede gruppemerken slik at den gjelder for hele gruppen:
Denne gangen er den animerte effekten en roterende transformasjon. Elementet vil rotere 360 grader, og for å legge til effekten, vil det bevege seg til høyre og nedover av en enkelt piksel på hver rotasjon, over en periode på ett sekund, og gjentas på ubestemt tid. Denne transformasjonen vil også inkludere a fra attributt, som det er nødvendig å spesifisere den opprinnelige posisjonen til elementene som roteres. Hvis du ikke angir denne posisjonen, roterer elementene rundt 0, 0 pek som standard. For øyeblikket kan du imidlertid ikke levere relative (dvs. prosentvise) verdier til disse attributene, bare faste verdier. Av denne grunn skal vi sette fra Tilordne når vi spesifiserer SVG dimensjonene i JavaScript.
La oss nå implementere våre interaktive funksjoner: Klikk på knappen for å endre posten og trykke på posten for å senke den ned.
Først legger du til disse variablene for å telle og holde oversikt over etikettdesignene i skriptdelen av sidehodet ditt:
// holde styr på gjeldende plateselskap var currLabel = 0; // endre dette for et annet antall etiketter var numLabels = 3;
Nå, inne i åpningskoden for sirkelelementet som representerer knappen (som nå har en animasjon mellom kodene), legger du til følgende klikkhendelselytter:
onclick = "changeRecord ()"
Tilbake i hovedskripteksjonen, legg til funksjonsoversikten:
funksjonsendringRecord ()
Hver gang brukeren trykker på knappen, flyttes vi til neste etikett, flyttes tilbake til den første når vi kommer til den siste:
// Flytt til neste etikett currLabel ++; // tilbakestille hvis på høyeste tall hvis (currLabel> numLabels - 1) currLabel = 0; // sett fylleattributtet til neste gradient document.getElementById ("recordLabel"). setAttribute ("fill", "url (#labelGrad" + currLabel + ")");
Den siste linjen her demonstrerer hvordan du kan samhandle med SVG-elementene ved hjelp av DOM-teknikker, som du ville med andre websideelementer. Her satte vi fylle Attributt av etikettsirkelelementet for å bruke neste gradientfylling, og angi fyllings-ID.
Legg nå følgende hendelsesattributter til rekordlyselementet (med "shineGrad" som fylling), da vi skal bruke musen ned og opp hendelser på den for å utløse bremse opptaket og øke hastigheten opp igjen:
onmousedown = "onRecord ()" onmouseup = "offRecord ()"
Tilbake i script-delen, legg til funksjonen for når en bruker trykker på posten:
// funksjon kalt når brukeren trykker på rekordfunksjon onRecord ()
Innenfor denne funksjonen kan vi senke rekordspinn animasjonen ved å endre animateTransform varighetsattributt. Vi endrer også skinnens opasitet for å skape inntrykk av å trykke ned:
// sakte animasjonsvarigheten document.getElementById ("spinTrans"). setAttribute ("dur", "5s"); // redusere skinnens ustabilitet document.getElementById ("shine"). style.opacity = "0.7";
Når brukeren slipper posten, vil vi at den skal gå tilbake til normal fart og utseende, så legg til "mus opp" -funksjonen neste:
// funksjon kalt når brukeren slipper rekordfunksjon offRecord () // reset til normal hastighet document.getElementById ("spinTrans"). setAttribute ("dur", "1s"); // sette opacity tilbake til normal document.getElementById ("shine"). style.opacity = "1.0";
Vi kan endelig definere den totale størrelsen på SVG nå. Øverst i skripteksjonen, legg til en ny variabel:
// ønsket størrelse på SVG var størrelse = 300;
Vi vil først bruke 300
piksler for både bredde og høyde på grafikken, men du kan endre dette til enhver tid. Definer en funksjon i skriptdelen for å angi disse dimensjonene:
// funksjon for å sette SVG dimensjoner funksjon setSize () // sett css og transform størrelse var holder = document.getElementById ("picHolder"); holder.style.height = size + "px"; holder.style.width = size + "px"; document.getElementById ("spinTrans"). setAttribute ("fra", "0," + størrelse / 2 + "," + størrelse / 2 + "");
Vi setter størrelsen på den inneholdende div element. Ta et øyeblikk for å se på den endelige linjen i denne funksjonen. Siden roterende transformasjonsanimasjonen ikke kan bruke relative prosentverdier, må vi sette inn fra element ved hjelp av størrelsesvariabelen (delt med to for sentralpunktet i posten). Med 300 som SVG-størrelse, er det slik transformasjonen vil vises med faste verdier:
Hvis du vil bruke faste verdier i SVG, kan du gjøre det. Vi bruker bare denne teknikken til å demonstrere bruk av relative dimensjoner. Til slutt, ring denne funksjonen på slutten av script-delen:
window.addEventListener ("DOMContentLoaded", settSize, false);
Vår interaktive SVG-animasjon er nå fullført! Åpne siden din i en støttende nettleser for å se effekten; ikke glem å prøve å samhandle med posten og knappen. Prøv å endre størrelsesvariabelen for å se hvordan SVG-elementene alle tilpasser seg, inkludert animasjonene og interaksjonene.
Hvis du ønsker å utforske SVG videre, er det noen emner du bør vurdere å inkludere stier, tekst, maskering og klipping. Det er også en rekke ekstra animasjonsalternativer å vurdere. Selvfølgelig vil disse effektene ikke virke for alle brukere akkurat nå, men forhåpentligvis en dag snart ...