Cara animada TDC Nav para contenido web largo

Tiempo de ejecución: 30 minutos. Empezar

Autor: hakimel
Views Total: 1,743
Sitio oficial: Ir a la web
Actualizado: January 13, 2017
Licencia: MIT

Vista prévia

Cara animada TDC Nav para contenido web largo

Descripción

Se trata de un TOC lateral bastante Cool (tabla de contenido) & sistema de navegación que permite resaltar el elemento NAV actual con una línea animada de progreso cuando se desplaza a través de la Página Web.

Funcionamiento

Cree la TDC & navegación junto con las secciones de contenido correspondientes y la barra de progreso basada en SVG en la Página Web de la siguiente manera:

<nav class="toc">

<ul>


<li><a href="#section1">Section One</a></li>


<li>



<a href="#section2">Section Two</a>



<ul>




<li><a href="#section21">Section 2-1</a></li>




<li><a href="#section22">Section 2-2</a></li>




<li><a href="#section23">Section 2-3</a></li>



</ul>


</li>

</ul>

<svg class="toc-marker" width="200" height="200" xmlns="http://www.w3.org/2000/svg">


<path stroke="#444" stroke-width="3" fill="transparent" stroke-dasharray="0, 0, 0, 1000" stroke-linecap="round" stroke-linejoin="round" transform="translate(-0.5, -0.5)" />

</svg>
</nav>
<article class="contents">


<section id="section1">


<h2>Section One</h2>

</section>


<section>



<div id="section2">



<h2>Section Two</h2>


</div>



<div id="section21">



<h3>Section 2-1</h3>


</div>



<div id="section22">



<h3>Section 2-2</h3>


</div>

 </section>

 ......

</article>

Estilo de la TDC & navegación.

.toc {

position: fixed;

left: 3em;

top: 5em;

padding: 1em;

width: 14em;

line-height: 2;
}

.toc ul {

list-style: none;

padding: 0;

margin: 0;
}

.toc ul ul { padding-left: 2em; }

.toc li a {

display: inline-block;

color: #aaa;

text-decoration: none;

-webkit-transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);

transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
}

.toc li.visible > a {

color: #111;

-webkit-transform: translate(5px);

transform: translate(5px);
}

.toc-marker {

position: absolute;

top: 0;

left: 0;

width: 100%;

height: 100%;

z-index: -1;
}

.toc-marker path {

-webkit-transition: all 0.3s ease;

transition: all 0.3s ease;
}

El principal JavaScript:

var toc = document.querySelector( '.toc' );
var tocPath = document.querySelector( '.toc-marker path' );
var tocItems;

// Factor of screen size that the element must cross
// before it's considered visible
var TOP_MARGIN = 0.1,


BOTTOM_MARGIN = 0.2;

var pathLength;

window.addEventListener( 'resize', drawPath, false );
window.addEventListener( 'scroll', sync, false );

drawPath();

function drawPath() {



tocItems = [].slice.call( toc.querySelectorAll( 'li' ) );


// Cache element references and measurements

tocItems = tocItems.map( function( item ) {


var anchor = item.querySelector( 'a' );


var target = document.getElementById( anchor.getAttribute( 'href' ).slice( 1 ) );



return {



listItem: item,



anchor: anchor,



target: target


};

} );


// Remove missing targets

tocItems = tocItems.filter( function( item ) {


return !!item.target;

} );


var path = [];

var pathIndent;


tocItems.forEach( function( item, i ) {



var x = item.anchor.offsetLeft - 5,




y = item.anchor.offsetTop,




height = item.anchor.offsetHeight;



if( i === 0 ) {



path.push( 'M', x, y, 'L', x, y + height );



item.pathStart = tocPath.getTotalLength() || 0;


}


else {



// Draw an additional line when there's a change in



// indent levels



if( pathIndent !== x ) path.push( 'L', pathIndent, y );




path.push( 'L', x, y );







// Set the current path so that we can measure it



tocPath.setAttribute( 'd', path.join( ' ' ) );



item.pathStart = tocPath.getTotalLength() || 0;







path.push( 'L', x, y + height );


}





pathIndent = x;





tocPath.setAttribute( 'd', path.join( ' ' ) );


item.pathEnd = tocPath.getTotalLength();


} );



pathLength = tocPath.getTotalLength();



sync();


}

function sync() {



var windowHeight = window.innerHeight;



var pathStart = Number.MAX_VALUE,



pathEnd = 0;



var visibleItems = 0;



tocItems.forEach( function( item ) {



var targetBounds = item.target.getBoundingClientRect();





if( targetBounds.bottom > windowHeight * TOP_MARGIN && targetBounds.top < windowHeight * ( 1 - BOTTOM_MARGIN ) ) {



pathStart = Math.min( item.pathStart, pathStart );



pathEnd = Math.max( item.pathEnd, pathEnd );







visibleItems += 1;







item.listItem.classList.add( 'visible' );


}


else {



item.listItem.classList.remove( 'visible' );


}




} );



// Specify the visible path or hide the path altogether

// if there are no visible items

if( visibleItems > 0 && pathStart < pathEnd ) {


tocPath.setAttribute( 'stroke-dashoffset', '1' );


tocPath.setAttribute( 'stroke-dasharray', '1, '+ pathStart +', '+ ( pathEnd - pathStart ) +', ' + pathLength );


tocPath.setAttribute( 'opacity', 1 );

}

else {


tocPath.setAttribute( 'opacity', 0 );

}

}

Te puede interesar: