Så här bygger du en sidrullningsindikator med jQuery och SVG

Idag kommer vi att titta på några tekniker som vi kan använda för att visa rullning framsteg för användare som läser en sida. Denna teknik används på ett ökande antal platser, och av goda skäl; Det ger en kontextuell förståelse för investeringar som behövs för att konsumera en viss sida. När användaren rullar presenteras de med en känsla av nuvarande framsteg i olika format. 

Såsom ses på ia.net

Idag kommer vi att täcka två specifika tekniker du kan använda för att visa rullningens framsteg, och lämna dig ett verktygssätt för att skapa din egen. Låt oss börja!

Ställa in dokumentet

Först kommer vi att skapa ett mock dokument som kommer att fungera som vår postsida. Vi kommer att använda normalize.css och jQuery, liksom en Google-typsnitt. Din tomma HTML-fil ska se ut så här:

   Progress Indicator Animation         

Därefter lägger vi till vårt falska inläggsinnehåll:

Hur ska vi visa framsteg medan du rullar en inlägg?

Lorem ipsum dolor sit amet, consectetur adipisicing elit.

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sitter som en del av semestern. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Förberedelserna är välkomna, förberedelserna, medvetna om, om du vill se det. Aenean fermentum, egen tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec är inte enbart i turpis pulvinar facilisis. Ut felis. Presentera dapibus, neque id kurs faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Alquam erat volutpat. Namnet visar mig, tincidunt quis, accumsan porttitor, facilisis luctus, metus

Läs följande:
Hur implementerar jag en Foobar?

Detta ger oss tillräckligt med innehåll för att testa våra rullningsbeteenden.

Grundläggande Styling

Vi ska använda några grundläggande styling för att göra vårt inlägg lite mer attraktivt.

@import url (http://fonts.googleapis.com/css?family=Domine:400,700); kropp font-size: 16px;  h1, h2, h3, h4, h5, h6 font-family: "Domine", sans-serif;  h1 font-size: 3.5em;  .lead-in color: #fff; font-vikt: 400; vaddering: 60px 0; bakgrundsfärg: # 0082FF;  artikelrubrik gräns-topp: 3px fast # 777; vaddering: 80px 0;  .artikelinnehåll font-size: 1em; font-vikt: 100; linjehöjd: 2,4em;  p marginal: 4em 0;  .container width: 700px; marginal: 0 auto;  footer text-align: center; bakgrundsfärg: # 666; färg: #fff; vaddering: 40px 0; marginal-topp: 60px;  .read-next font-size: 2em; 

Rulla position Beräkning

För att beräkna vår rullningsposition måste vi förstå begreppsmässigt vad vi spårar. Eftersom JavaScript kan spåra endast det högsta rullningsvärdet, måste vi spåra vårt rullningsvärde från 0 (högst upp, inte rullat) till vad det änvarande rullningsvärdet är. Det slutliga rullningsvärdet kommer att vara lika med den totala dokumentlängden minus höjden på själva fönstret (eftersom dokumentet bläddrar tills botten av dokumentet når längst ner i fönstret).

Vi använder följande JavaScript för att beräkna denna rullningsposition.

(funktion () var $ w = $ (fönster); var wh = $ w.height (); var h = $ ('kropp'). höjd (); var sHeight = h - wh; $ w.on 'scroll', funktion () var perc = Math.max (0, Math.min (1, $ w.scrollTop () / sHeight);; ());

Ovanstående kod anger fönsterhöjd och kroppshöjd, och när användaren rullar använder den dessa värden för att ställa in a perc variabel (kort för procentandel). Vi använder också Math.min och Math.max för att begränsa värdena till 0-100-intervallet.

Med denna procentsatsberäkning kan vi köra framdriftsindikatorn.

Cirkelindikator

Den första indikatorn vi ska skapa är en SVG-cirkel. Vi kommer att använda SVG stroke-dasharray ochstroke-dashoffset egenskaper för att visa framsteg. Låt oss först lägga fram framdriftsindikatorn i dokumentet.

Denna markering ger oss två cirklar i en SVG, såväl som en innehållande div för att visa vår procenttal. Vi måste också lägga till stil på dessa element och sedan förklarar vi hur dessa cirklar är placerade och animerade.

.framstegsindikator position: fixed; topp: 30px; höger: 30px; bredd: 100px; höjd: 100px;  .progress-count position: absolute; topp: 0; vänster: 0; bredd: 100%; höjd: 100%; text-align: center; linjehöjd: 100px; färg: # 0082FF;  svg position: absolut;  cirkel fyll: rgba (255,255,255,0,9);  svg .animated-circle fill: transparent; slagbredd: 40px; stroke: # 0A74DA; stroke-dasharray: 126; stroke-dashoffset: 126; 

Dessa stilar gör att vi kan animera vårt cirkelelement. Våra framsteg bör alltid vara synliga, så vi ställer ställning till fast på .framsteg-indikator klass, med positionering och limning regler. Vi ställer också vår framstegsräkning att centreras både vertikalt och horisontellt inuti denna div.

Cirklarna är placerade i mitten med hjälp av transformation på själva SVG-elementen. Vi börjar mitt i våra cirklar genom att använda transform. Vi använder en teknik här som tillåter oss att tillämpa en rotation från mitten av våra cirklar för att starta animeringen längst upp i cirkeln (snarare än i högra sidan av cirkeln). I SVG appliceras transformationer från övre vänstra delen av ett element. Det är därför vi måste centrera våra cirklar på 0, 0, och flytta cirkelns centrum till centrum av SVG själv med översätt (50, 50).

Använda stroke-dasharray och stroke-dashoffset

Egenskaperna stroke-dasharray ochstroke-dashoffset tillåta oss att animera stroke av en SVG. stroke-dasharray definierar de synliga bitarna av en stroke.  stroke-dashoffset flyttar starten på stroke. Dessa attribut kombinerar tillåter oss att skapa en "keyframing" -process.

Uppdaterar stroke-dasharray på Scroll

Därefter lägger vi till en funktion för att uppdatera stroke-dasharray på rullning, med hjälp av våra procentuella framsteg som tidigare visats.

(funktion () var $ w = $ (fönster); var $ circ = $ ('animerad cirkel'); var $ progCount = $ ('progress-count'); var wh = $ w.height ), var h = $ ('kropp'). höjd (); var sHeight = h - wh; $ w.on ('scroll', funktion () var perc = Math.max (0, Math.min ($) ; $ progCount.html (Math.round (perc * 100) + "%"); ());

Förskjutningen som matchar vår cirkel råkar vara ca 126. Det är viktigt att notera att detta inte kommer att fungera för alla kretsar, eftersom 126 är omkring omkretsen av en cirkel med en radie av 20. För att beräkna streckdashoffset för en given cirkel, mutiply radie med 2PI. I vårt fall skulle den exakta avräkningen vara 20 * 2PI = 125,66370614359172.

Horisontell Progress Variation

För vårt nästa exempel gör vi en enkel horisontell stapel som är fast i toppen av fönstret. För att uppnå detta använder vi en tom framdriftsindikator div.

Notera: Vi har lagt till "-2" så att vi kan inkludera detta exempel i samma CSS-fil.

Därefter lägger vi till vår stil för det här elementet.

.framstegsindikator-2 position: fixed; topp: 0; vänster: 0; höjd: 3px; bakgrundsfärg: # 0A74DA; 

Slutligen kommer vi att ställa in bredden på framdriftsfältet på rullning.

var $ prog2 = $ ('progress-indicator-2'); funktionsuppdateringProgress (perc) $ prog2.css (bredd: perc * 100 + '%'); 

Sammantaget bör vår sista JavaScript se så här ut:

(funktion ) var $ w = $ (fönster); var $ circ = $ ('animerad cirkel'); var $ progCount = $ ('progress-count'); var $ prog2 = $ ('. progress-indicator-2 '); var wh = $ w.height (); var h = $ (' kropp '). höjd (); var sHeight = h - wh; $ w.on ("scroll" ) var perc = Math.max (0, Math.min (1, $ w.scrollTop () / sHeight)); updateProgress (perc);); funktionsuppdateringProgress (perc) var circle_offset = 126 * perc; $ circ.css ("stroke-dashoffset": 126 - circle_offset); $ progCount.html (Math.round (perc * 100) + "%"); $ prog2.css (bredd: perc * 100 + '% '); ());

Andra idéer för framstegsstänger

Den här artikeln är avsedd att ge dig verktyg och inspiration för att designa dina egna framstegslösningar. Andra idéer för framstegsbarer kan innefatta att använda mer beskrivande eller humaniserade termer för framstegsindikationen i sig, till exempel "halvvägs där" eller "bara igång". Vissa implementeringar (som ia.net-exemplet visat tidigare) använder uppskattning av artikelns läsningstid. Detta kan beräknas med kod som liknar följande:

var wordsPerMin = 300; // baserat på denna artikel: http://www.forbes.com/sites/brettnelson/2012/06/04/do-you-read-fast-enough-to-be-successful/ var wordsArray = $ (". artikelinnehåll "). text (). split (" "); var wordCount = wordsArray.length; var minCount = Math.round (wordCount / wordsPerMin);

Du skulle då använda minCount i samband med perc variabel vi uppdaterar på rullning för att visa läsaren sin återstående tid för att läsa artikeln. Här är en mycket grundläggande implementering av detta koncept.

funktionsuppdateringProgress (perc) var minutesCompleted = Math.round (perc * minCount); var kvar = minCount - minutesCompleted; om (återstående) $ ("progress-indicator"). visa (). html (återstående + "kvarvarande minuter");  else $ ("progress-indicator"). hide (); 

En slutlig bit: Adaptiv skärmstorlek

För att säkerställa att vår framdriftsindikator fungerar som den ska ska vi se till att vår matta beräknar rätt saker vid rätt tidpunkt. För att det ska ske måste vi se till att vi beräknar höjderna och uppdaterar framdriftsindikatorn när användaren ändrar fönstret. Här är en anpassning av JavaScript för att få det att hända:

(funktion ) var $ w = $ (fönster); var $ circ = $ ('animerad cirkel'); var $ progCount = $ ('progress-count'); var $ prog2 = $ ('. progress-indicator-2 '); var wh, h, sHeight; funktion setSizes () wh = $ w.height (); h = $ (' body '). höjd (); sHeight = h - wh; setSizes (); $ w.on ("scroll", funktion () var perc = Math.max (0, Math.min (1, $ w.scrollTop () / sHeight)); uppdateraProgress (perc);). på ('resize', funktion () setSizes (); $ w.trigger ('scroll');); funktionsuppdateringProgress (perc) var circle_offset = 126 * perc; $ circ.css ("stroke-dashoffset ": 126 - circle_offset); $ progCount.html (Math.round (perc * 100) +"% "); $ prog2.css (bredd: perc * 100 + '%'); ;

Den här koden deklarerar en funktion som ställer in de variabler vi behöver för att beräkna framstegen vid vilken skärmstorlek som helst, och samtal som fungerar på storlek. Vi återaktiverar även rullning på fönsterändring så att vår updateProgress funktionen exekveras.

Du har nått slutet!

Har du lagt grunden för några olika varianter, vad kan du komma med? Vilka framstegsindikatorer har du sett det arbetet? Vad sägs om indikatorer som är dåliga för användbarhet? Dela dina erfarenheter med oss ​​i kommentarerna!