Hur man utformar animerade glidande sidelement med CSS

Det finns en återkommande trend att använda animerade sidelement i webbdesignen just nu - när du rullar ner på sidan, kommer objekten naturligt att passa in i vyn. Dessa animeringar händer bara en gång, och de börjar bara när elementet ligger i webbläsarens visningsport.

Jag har undersökt detta koncept lite med jQuery, tillsammans med CSS3-övergångar. I ett nötskal kontrollerar detta skript för speciella klasser på sidan och använder jQuery för att lägga till en ny klass för övergångseffekter. De element som redan har animerats tas sedan bort från händelsehanteraren. Och när det inte finns några fler element att animera, är händelsehanteraren helt borttagen tills du uppdaterar sidan. Ta en titt på mitt demo exempel för att se exakt vad vi skapar och följ med!

Live Demo - Hämta källkod

Grundläggande sidstruktur

Till att börja med skapade jag en enkel HTML5-layout med ett externt stilark och en kopia av det senaste jQuery-biblioteket. Alla mina anpassade JavaScript kommer att skrivas in i en annan extern fil som heter scrollview.js.

Animeringsinfo kan lagras direkt i HTML med hjälp av klasser och data attribut. Låt oss ta en titt på det första animerade elementet på min sida.

Detta innehåller två separata animerade div som flyter bredvid varandra i en behållare. Attributet uppgifter-positionen berättar vilken sida elementet kommer ifrån. De använder också några klasser för olika CSS-egenskaper.

De .floatr och .floatl klasser representerar flytande element till höger respektive vänster. .animBlock element är dolda som standard med noll opacitet tillsammans med övergångsegenskaper för animeringen.

Du hittar denna kodsedel ned i mitt stilark. Det kretsar runt .notViewed och .tittade klasser som berättar när ett element har (eller inte har) animerats. Varje block gör initialt användning av .notDit och jQuery kontrollerar dessa animerade element för att se vilka som har visats och vilka inte har.

Vid tillägg av .tittade klassen flyttar dessa element i 20% från höger / vänster sida och övergång från 0% opacitet upp till 100%. Teknikerna i CSS är ganska grundläggande och körs ordentligt i alla moderna webbläsare. Att hantera växeln mellan klasser med jQuery är när sakerna blir lite komplicerade.

Bindar rullningsevenemanget

Jag vill flytta över till scrollview.js som är skild från huvudindexfilen. Det finns två kodblock där en är händelsehanteraren och den andra är en förbyggd funktion.

De två första variablerna representerar cachade kopior av jQuery-objekt. $ block är ett jQuery-objekt som representerar alla animerade block med .notViewed klasser. I grund och botten borde det innehålla alla möjliga animerade element så att vi enkelt kan gå igenom allt. $ fönster kallas varje gång användaren rullar på sidan, så att använda en cachad kopia är effektivare när det gäller bearbetning och minne.

Metoden jQuery .each () kan iterera över objekt och arrays. I det här fallet har vi ett objekt som innehåller många andra objekt på sidan. På varje scrollhändelse behandlar denna funktion varje element i $ block objekt en-för-en.

Den första om{} uttalande sparar tid när ett element har avslutat animationen. Eftersom variabeln $ block är ett cachelagret objekt, kommer det inte automatiskt att uppdateras när vissa klasser har ändrats. Så i stället måste vi kontrollera om varje element redan har uppdaterats för att använda klassen .tittade, och i så fall stoppa den nuvarande operationen för att flytta till nästa.

Annars vet vi att elementet ännu inte har animerats i sikte. Här är den mer detaljerade funktionen isScrolledIntoView () kommer att köras genom att kolla ett antal specifika egenskaper. Min kod ändras faktiskt från det här inlägget på Stack Overflow vilket ger en utmärkt startmall.

Animerade element

Jag bryter denna funktion ner i segment för enklare förståelse. I början är det ganska grundläggande, inställning av variabler som är unika för rullningsevenemanget och varje element passerat genom $ block.

De två första variablerna docViewTop och docViewBottom kommer att ändras på varje blad. Jag tänkte också ibland att vi kanske vill animera element innan de är helt inom utsikten. Det är därför jag skapade en offset variabel som kan appliceras direkt i HTML. Du märker att jag letar efter en singel data offset egendom - vilket är valfritt - och kommer att åsidosätta standardvärdet på 0. Du får se detta tillämpas på mitt 2: a animerade element ner på sidan:

Nästa bit av JS-koden kontrollerar var det aktuella elementet ligger på sidan. Kom ihåg att detta kommer att gå igenom allt, så dessa värden ändras baserat på aktuellt visningsport och vilket element som för närvarande överförs via funktionen. Två variabler elemTop och elemBottom ge oss numeriska värden som refererar till hela höjden för det aktuella objektet.

Med 0-offset behöver du inte byta någon av koderna, vi animerar bara när elementet är i full vy. Men när det finns en kompensation måste vi kontrollera om användaren rullar ner från toppen av sidan eller uppifrån från botten. Jag har gjort det genom att subtrahera det aktuella toppvisningsvärdet från det faktiska elementets topposition.

Om elementet ligger uppe på sidan än användarens visningsport blir det ett mindre antal (närmare 0). Att subtrahera elementets högsta värde (mindre) från visningsvärdet (större) kommer alltid att vara ett positivt tal eller mycket nära noll. Så användaren måste vara lägre på sidan och därigenom bläddra uppåt. Att lägga till offset till elementets högsta värde gör det till ett högre antal och därmed lägre? på sidan, även om det faktiskt inte rör sig någonstans. Det här är all figurativ logik för att bestämma när offsetanimationen ska börja.

Annars borde användaren komma ner från toppen och vi subtraherar detta offsetvärde från elementets botten (nu gör botten närmare). Detta begrepp är lite förvirrande först. Försök att tänka på dessa topp- / bottenvärden som pixeltal. Fönstrets högsta del representerar 0 och fönstret längst ner i fönstret är det högsta möjliga värdet vi kan få.

Byter CSS-klasser

Slutstycket till den här funktionen skapar animeringseffekten när elementet är inom vy. Vanligtvis går det logiska uttalandet endast när elementet är i fullvisningsporten. Ändå kan offsetvärdet tillåta att elementen startar animationsprocessen tidigare.

I enklare termer läser logiken något så här: när elementets bottenposition är inom synvinkel eller strax under vy och toppositionen är perfekt inriktad eller bara inom synhåll, animera elementet. Båda förhållandena måste vara sant innan JavaScript kör någon kod.

Det borde vara något uppenbart att det enda kravet är att ta bort .notViewed och lägg sedan till vår animeringsklass .tittade. Detta händer en gång per pagelad, så en gång ett element har blivit utsatt för det aktiverar nu returkommandot från mitt första block av kod. Det återstår fortfarande inuti $ blocket objekt men vi sparar tid genom att inte köra den genom denna funktion igen.

Så vad händer när alla element är synliga? Vi vill inte behålla den här scrollevenemanget förutom vad som är nödvändigt. $ ( ". AnimBlock.notViewed). Längd kommer att returnera ett antal totala element som matchar den jQuery-väljaren. När varje element har ändrats till .animBlock.viewed detta värde kommer tillbaka 0.

När detta når 0, slutade vi bara med att animera det sista elementet på sidan. Så när detta äntligen händer, startar vi .off () bifogad till fönstret Nu utlöses inte händelsehanteraren för rullning om inte användaren uppdaterar sidan igen. Det är vettigt att hålla den här metoden inom den slutliga logikkontrollen, eftersom den bara körs så många gånger som det finns element att animera (i min demo är det totalt 5).

Live Demo - Hämta källkod

Stängning

Denna teknik är inriktad på avancerade webbplatser som inte nödvändigtvis catering till äldre äldre webbläsare. De flesta Internet-användare har flyttat till de senaste versionerna av IE, Firefox, Chrome, Opera, etc. Men du kan alltid kolla webbläsarversioner i JavaScript för att tvinga dessa element till visning när CSS3-övergångar inte är möjliga. Du kan ladda ner en kopia av min källkod och se vad du kan bygga med den här effekten.