3D Carousel Study
HTML
<div class="viewPort" data-bind="foreach:items">
<div class="cardCon" data-bind="style:currentStyle">
<div class="cardShadow"></div>
<div class="card"></div>
</div>
</div>
<div class="dotBar" data-bind="foreach:items">
<a href="#" data-bind="css:{currentItem:isCurrentItem},click:function(){$parent.currentSelectedItem(myIndex)}"></a>
</div>
<div class="toolbar">
<a href="#" data-bind="click:prev,css:{disabled:cantPrev}"><</a>
<a href="#" data-bind="click:next,css:{disabled:cantNext}">></a>
<div class="tbRight">
<a href="#" class="righty" data-bind="click:addItem">+</a>
</div>
</div>
<div class="who">Written by <a href="http://www.hughanderson.com">Hugh Anderson</a></div>
CSS
body {
background:#eee;
}
a {text-decoration:none}
.viewPort {
perspective: 1500px;
perspective-origin: 50% 50%;
height:300px;
border:solid #666;
border-width:1px 1px 0;
background:white;
text-align:center;
position:relative;
overflow:hidden;
backface-visibility:hidden;
}
.toolbar {
border-radius:0 0 6px 6px;
border:solid #666;
border-width:0 1px 1px;
border-top:1px solid #bbb;
height:40px;
padding:9px 0 0;
background: -webkit-gradient(linear, 0 100%, 0 0, from(#d2ff52), to(#91e842));
background: -webkit-linear-gradient(#d2ff52 0%, #91e842 100%);
background: -moz-linear-gradient(#d2ff52 0%, #91e842 100%);
background: -o-linear-gradient(#d2ff52 0%, #91e842 100%);
background: linear-gradient(#d2ff52 0%, #91e842 100%);
text-align:center;
position:relative;
}
.toolbar a {
height:34px;
color:white;
font-weight:bold;
font-family: 'Arial Black',Arial,sans-serif;
font-size:24px;
margin:0 10px;
padding: 1px 8px;
background: -webkit-gradient(linear, 0 100%, 0 0, from(#b8c6df), to(#6d88b7));
background: -webkit-linear-gradient(#b8c6df 0%, #6d88b7 100%);
background: -moz-linear-gradient(#b8c6df 0%, #6d88b7 100%);
background: -o-linear-gradient(#b8c6df 0%, #6d88b7 100%);
background: linear-gradient(#b8c6df 0%, #6d88b7 100%);
border:1px solid #777;
box-shadow:1px 1px 5px rgba(0,0,0,0.3);
text-shadow:1px 1px white, -1px -1px #444;
border-radius:4px;
}
.toolbar a:not(.righty):active{
position:relative;
top:1px;
}
.tbRight {
position:absolute;
right: 1px;
top:8px;
}
.cardCon {
width:180px;
height:140px;
position:absolute;
bottom:70px;
left:50%;
margin-left:-91px;
-webkit-transition:-webkit-transform 300ms ease-out;
}
.card {
width:100%;
height:100%;
background: -webkit-gradient(linear, 0 100%, 0 0, from(#ffff9e), color-stop(0.35, #ffffd1), to(#ffff88));
background:...
JavaScript
// constructs an item for the carousel
// the current selection passed is a knockout observable
function newItem(index, currentSel) {
// which one am i
var myIndex = index;
// compute a 3D css style based on the difference between the selected index and my index
function getStyle(selIndex) {
var difference = myIndex - selIndex;
var style = {};
if (difference === 0) {
// currently focused item
style.webkitTransform = 'none';
style.zIndex = 100;
} else if (difference < 0) {
// back and left
var deltaX = -260 + (difference * 30) - (115 / (difference * 0.84));
var rotY = '60deg';
var scaleDelta = 1 + (difference * 0.1);
style.zIndex = 100 + difference;
style.transform = 'translateX('+deltaX+'px) translateZ(-100px) rotateY('+rotY+') scale('+scaleDelta+')';
} else {
// back and right
var deltaX = 260 + (difference * 30) - (115 / (difference * 0.84));
var rotY = '-60deg';
var scaleDelta = 1 - (difference * 0.1);
style.zIndex = 100 - difference;
style.transform = 'translateX('+deltaX+'px) translateZ(-100px) rotateY('+rotY+') scale('+scaleDelta+')';
}
return style;
}
// a ko computed for my style that depends on the observable current selection
var currentStyle = ko.computed(function() {
var selIndex = currentSel();
return getStyle(selIndex);
});
// a ko computed for current item state that depends on the observable current selection
var isCurrentItem = ko.computed(function() {
var selIndex = currentSel();
return selIndex === myIndex;
});
// return the public interface for binding
return {
currentStyle: currentStyle,
isCurrentItem: isCurrentItem,
myIndex: myIndex
};
}
// all items bound to the carousel
var items =...