HTML结构将由一个主容器和一些行,我们将使用左派和右派的元素。左边和右边元素要么包含一个h2标题,一个圆形与背景图片或描述的h3元素与一个链接和一个跨越:
<div id="ss-container" class="ss-container">
<div class="ss-row">
<div class="ss-left">
<h2 id="november">November</h2>
</div>
<div class="ss-right">
<h2>2011</h2>
</div>
</div>
<div class="ss-row ss-medium">
<div class="ss-left">
<a href="#" class="ss-circle ss-circle-1">Some title</a>
</div>
<div class="ss-right">
<h3>
<span>November 28, 2011</span>
<a href="#">Some Title</a>
</h3>
</div>
</div>
<!-- more rows... -->
</div>
圆圈里我们会有三个不同尺寸和我们会表明,但是给各自的行“ss-small”类,“ss-medium”或“ss-large”。
让我们看一下样式。
容器将占领所有的宽度,我们会设置溢出隐藏,因为我们不需要一个滚动条出现当我们移动的左和右的元素如果:
.ss-container{
width: 100%;
position: relative;
text-align: left;
float: left;
overflow: hidden;
padding-bottom: 500px;
}
创建中线整个集装箱,我们将使用一个伪元素,我们将在容器的中间位置:
.ss-container:before{
position: absolute;
width: 4px;
background: rgba(17,17,22,0.8);
top: 0px;
left: 50%;
margin-left: -2px;
content: '';
height: 100%;
}
该行将作为左翼和右翼的包装器元素:
.ss-row{
width: 100%;
clear: both;
float: left;
position: relative;
padding: 30px 0;
}
两个横向元素将占据一半的宽度:
.ss-left, .ss-right{
float: left;
width: 48%;
position: relative;
}
.ss-right{
padding-left: 2%;
}
.ss-left{
text-align: right;
float: left;
padding-right: 2%;
}
标题的样式:
.ss-container h2{
font-size: 40px;
text-transform: uppercase;
color: rgba(78,84,123,0.2);
text-shadow: 0px 1px 1px #fff;
padding: 20px 0px;
}
.ss-container h3{
margin-top: 34px;
padding: 10px 15px;
background: rgba(26, 27, 33, 0.6);
text-shadow: 1px 1px 1px rgba(26, 27, 33, 0.8)
}
创建一个圆,我们将锚的边界半径设置为50%,我们将添加一些整洁的阴影:
.ss-circle{
border-radius: 50%;
overflow: hidden;
display: block;
text-indent: -9000px;
text-align: left;
box-shadow:
0px 2px 5px rgba(0,0,0,0.7) inset,
0px 0px 0px 12px rgba(61,64,85,0.3);
background-size: cover;
background-color: #f0f0f0;
background-repeat: no-repeat;
background-position: center center;
}
我们有三个不同大小的圆圈,根据哪一方我们我们将圆要么向左或向右浮动:
.ss-small .ss-circle{
width: 100px;
height: 100px;
}
.ss-medium .ss-circle{
width: 200px;
height: 200px;
}
.ss-large .ss-circle{
width: 300px;
height: 300px;
}
.ss-left .ss-circle{
float: right;
margin-right: 30%;
}
.ss-right .ss-circle{
float: left;
margin-left: 30%;
}
我们将使用伪元素:之前和之后为了创建的线和箭头指向中线。将被定义为一个百分比宽度,适应屏幕大小。我们还将中心通过顶部设置为50%,正确位置通过设置margin-top 3 px。根据(左或右)我们想要的位置不同:
.ss-circle-deco:before{
width: 29%;
height: 0px;
border-bottom: 5px dotted #ddd;
border-bottom: 5px dotted rgba(17, 17, 22, 0.3);
box-shadow: 0px 1px 1px #fff;
position: absolute;
top: 50%;
content: '';
margin-top: -3px;
}
.ss-left .ss-circle-deco:before{
right: 2%;
}
.ss-right .ss-circle-deco:before{
left: 2%;
}
小箭头将由边框样式和根据如果是左边或者右边的一个孩子,我们将设置显示边界和位置:
.ss-circle-deco:after{
width: 0px;
height: 0px;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
content: '';
position: absolute;
top: 50%;
margin-top: -10px;
}
.ss-left .ss-circle-deco:after{
right: 0;
border-right: 10px solid rgba(17,17,22,0.8);
}
.ss-right .ss-circle-deco:after{
left: 0;
border-left: 10px solid rgba(17,17,22,0.8);
}
由于不同大小的圆,我们需要调整的位置标题在另一边。我们希望他们在箭头的高度,因此我们将设置不同的(一个用于ss-small已经设置在圆本身):
.ss-container .ss-medium h3{
margin-top: 82px;
}
.ss-container .ss-large h3{
margin-top: 133px;
}
.ss-container .ss-left h3{
border-right: 5px solid rgba(164,166,181,0.8);
}
.ss-container .ss-right h3{
border-left: 5px solid rgba(164,166,181,0.8);
}
.ss-container h3 span{
color: rgba(255,255,255,0.8);
font-size: 13px;
display: block;
padding-bottom: 5px;
}
.ss-container h3 a{
font-size: 28px;
color: rgba(255,255,255,0.9);
display: block;
}
.ss-container h3 a:hover{
color: rgba(255,255,255,1);
}
每个圈会有一个不同的背景图片:
.ss-circle-1{
background-image:url(../images/1.jpg);
}
.ss-circle-2{
background-image: url(../images/2.jpg);
}
.ss-circle-3{
background-image: url(../images/3.jpg);
}
/* and so on... */
这是所有的样式让我们看看JavaScript。
最初想法是显示所有元素是可见的视窗上。所有其他元素将隐藏通过向左或向右值设置为-50%。如果角度选项设置为true,那么这些元素将翻译和y轴旋转,不透明度设置为0。在滚动,我们想通过滑动显示外侧元素位置0(分别向左或向右),或角度的情况下,相应的旋转。
var $rows = $('#ss-container > div.ss-row'),
// we will cache the inviewport
// rows and the outside viewport rows
$rowsViewport, $rowsOutViewport,
// navigation menu links
$links = $('#ss-links > a'),
// the window element
$win = $(window),
// we will store the window sizes here
winSize = {},
// used in the scroll setTimeout function
anim = false,
// page scroll speed
scollPageSpeed = 2000 ,
// page scroll easing
scollPageEasing = 'easeInOutExpo',
// perspective?
hasPerspective = true,
perspective = hasPerspective && Modernizr.csstransforms3d,
我们将有以下方法:
// initialize function
init = function() {
// get window sizes
getWinSize();
// initialize events
initEvents();
// define the inviewport selector
defineViewport();
// gets the elements that match the previous selector
setViewportRows();
// if perspective add css
if( perspective ) {
$rows.css({
'-webkit-perspective' : 600,
'-webkit-perspective-origin' : '50% 0%'
});
}
// show the pointers for the inviewport rows
$rowsViewport.find('a.ss-circle').addClass('ss-circle-deco');
// set positions for each row
placeRows();
},
defineViewport定义了一个选择器,收集的行元素最初是可见的。一个元素是可见的,如果其最高不到窗口的高度。这些元素滚动页面时将不受影响:
defineViewport = function() {
$.extend( $.expr[':'], {
inviewport : function ( el ) {
if ( $(el).offset().top < winSize.height ) {
return true;
}
return false;
}
});
},
setViewportRows检查哪些行是最初可见:
setViewportRows = function() {
$rowsViewport = $rows.filter(':inviewport');
$rowsOutViewport = $rows.not( $rowsViewport )
},
getWinSize获取窗口宽度和高度:
getWinSize = function() {
winSize.width = $win.width();
winSize.height = $win.height();
},
现在让我们来初始化一些事件:
initEvents = function() {
// navigation menu links.
// scroll to the respective section.
$links.on( 'click.Scrolling', function( event ) {
// scroll to the element that has id = menu's href
$('html, body').stop().animate({
scrollTop: $( $(this).attr('href') ).offset().top
}, scollPageSpeed, scollPageEasing );
return false;
});
$(window).on({
// on window resize we need to redefine
// which rows are initially visible
// (this ones we will not animate).
'resize.Scrolling' : function( event ) {
// get the window sizes again
getWinSize();
// redefine which rows are initially
// visible (:inviewport)
setViewportRows();
// remove pointers for every row
$rows.find('a.ss-circle').removeClass('ss-circle-deco');
// show inviewport rows and respective pointers
$rowsViewport.each( function() {
$(this).find('div.ss-left')
.css({ left : '0%' })
.end()
.find('div.ss-right')
.css({ right : '0%' })
.end()
.find('a.ss-circle')
.addClass('ss-circle-deco');
});
},
// when scrolling the page change
// the position of each row
'scroll.Scrolling' : function( event ) {
// set a timeout to avoid that the
// placeRows function gets called on
// every scroll trigger
if( anim ) return false;
anim = true;
setTimeout( function() {
placeRows();
anim = false;
}, 10 );
}
});
},
placeRows集的位置行(左和右行元素)。这两个元素将开始为-50%左/右(不可见)。这个值应该是0%(最终位置)时,在窗口的中心元素。
placeRows = function() {
// how much we scrolled so far
var winscroll = $win.scrollTop(),
// the y value for the center of the screen
winCenter = winSize.height / 2 + winscroll;
// for every row that is not inviewport
$rowsOutViewport.each( function(i) {
var $row = $(this),
// the left side element
$rowL = $row.find('div.ss-left'),
// the right side element
$rowR = $row.find('div.ss-right'),
// top value
rowT = $row.offset().top;
// hide the row if it is under the viewport
if( rowT > winSize.height + winscroll ) {
if( perspective ) {
$rowL.css({
'-webkit-transform' : 'translate3d(-75%, 0, 0) rotateY(-90deg) translate3d(-75%, 0, 0)',
'opacity' : 0
});
$rowR.css({
'-webkit-transform' : 'translate3d(75%, 0, 0) rotateY(90deg) translate3d(75%, 0, 0)',
'opacity' : 0
});
}
else {
$rowL.css({ left : '-50%' });
$rowR.css({ right : '-50%' });
}
}
// if not, the row should become visible
// (0% of left/right) as it gets closer to
// the center of the screen.
else {
// row's height
var rowH = $row.height(),
// the value on each scrolling step
// will be proporcional to the distance
// from the center of the screen to its height
factor = ( ( ( rowT + rowH / 2 ) - winCenter ) / ( winSize.height / 2 + rowH / 2 ) ),
// value for the left / right of each side of the row.
// 0% is the limit
val = Math.max( factor * 50, 0 );
if( val <= 0 ) {
// when 0% is reached show the pointer for that row
if( !$row.data('pointer') ) {
$row.data( 'pointer', true );
$row.find('.ss-circle').addClass('ss-circle-deco');
}
}
else {
// the pointer should not be shown
if( $row.data('pointer') ) {
$row.data( 'pointer', false );
$row.find('.ss-circle').removeClass('ss-circle-deco');
}
}
// set calculated values
if( perspective ) {
var t = Math.max( factor * 75, 0 ),
r = Math.max( factor * 90, 0 ),
o = Math.min( Math.abs( factor - 1 ), 1 );
$rowL.css({
'-webkit-transform' : 'translate3d(-' + t + '%, 0, 0) rotateY(-' + r + 'deg) translate3d(-' + t + '%, 0, 0)',
'opacity' : o
});
$rowR.css({
'-webkit-transform' : 'translate3d(' + t + '%, 0, 0) rotateY(' + r + 'deg) translate3d(' + t + '%, 0, 0)',
'opacity' : o
});
}
else {
$rowL.css({ left : - val + '%' });
$rowR.css({ right : - val + '%' });
}
}
});
};
return { init : init };