An exlusive free UI Kit for e-commerce app created at Five agency. This Kit - designed in sketch - is the first of live. it iclude 50+ useful screens you can reuse for your app design.
![]() |
| free |
Bee black designer Collectibles it's have a Latest free PSDs & other resources for designers
![]() |
| free |
<div id="boxgallery" class="boxgallery" data-effect="effect-1">
<div class="panel"><img src="img/1.jpg" alt="Image 1"/></div>
<div class="panel"><img src="img/2.jpg" alt="Image 2"/></div>
<div class="panel"><img src="img/3.jpg" alt="Image 3"/></div>
<div class="panel"><img src="img/4.jpg" alt="Image 4"/></div>
</div>
<div id="boxgallery" class="boxgallery" data-effect="effect-1">
<div class="panel current">
<div class="bg-tile">
<div class="bg-img"><img src="img/1.jpg" /></div>
</div>
<div class="bg-tile">
<div class="bg-img"><img src="img/1.jpg" /></div>
</div>
<div class="bg-tile">
<div class="bg-img"><img src="img/1.jpg" /></div>
</div>
<div class="bg-tile">
<div class="bg-img"><img src="img/1.jpg" /></div>
</div>
</div>
<div class="panel">
<div class="bg-tile">
<div class="bg-img"><img src="img/2.jpg" /></div>
</div>
<div class="bg-tile">
<div class="bg-img"><img src="img/2.jpg" /></div>
</div>
<div class="bg-tile">
<div class="bg-img"><img src="img/2.jpg" /></div>
</div>
<div class="bg-tile">
<div class="bg-img"><img src="img/2.jpg" /></div>
</div>
</div>
<div class="panel">
<!-- ... -->
</div>
<div class="panel">
<!-- ... -->
</div>
<nav>
<span class="prev"><i></i></span>
<span class="next"><i></i></span>
</nav>
</div>
background-size: cover can be a major source of jerkiness. Another critical thing that causes twitchy transitions (at least in Chrome) is using percentage values when translating. This might not be noticeable at first glance but when comparing with a pixel-based translation, you will be able to see an impactful difference. For that reason we will not be using classes to control the transforms, but we’ll instead do it in our script by getting the pixel values of the viewport and applying the respective translation values to the tiles’ “background images”.html, thebody and the main container to a height of 100% will allow us to expand our slideshow to the full height of the viewport:html, body, .container {
height: 100%;
}
.js .boxgallery,
.js .boxgallery div {
position: absolute;
}
.js .boxgallery,
.js .panel {
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.js .boxgallery,
.bg-tile,
.bg-img {
overflow: hidden;
}
.panel {
z-index: 0;
perspective: 1200px;
}
.bg-tile {
width: 50%;
height: 50%;
}
.bg-tile:nth-child(2),
.bg-tile:nth-child(4) {
left: 50%;
}
.bg-tile:nth-child(3),
.bg-tile:nth-child(4) {
top: 50%;
}
.bg-img {
width: 100%;
height: 100%;
background: #999;
}
min-aspect-ratio. This allows us to simply take the real size of our images as ratio value (width/height) and define, when we want the width and when the height to be calculated automatically:.bg-img img {
position: absolute;
display: block;
height: 200%;
}
@media screen and (min-aspect-ratio: 1280/850) {
.bg-img img {
width: 200%;
height: auto;
}
}
.bg-tile:nth-child(2) .bg-img img,
.bg-tile:nth-child(4) .bg-img img {
left: -100%;
}
.bg-tile:nth-child(3) .bg-img img,
.bg-tile:nth-child(4) .bg-img img {
top: -100%;
}
.panel.current {
z-index: 2;
}
.panel.active {
z-index: 1;
}
.panel.current .bg-img {
transition: transform 1.1s ease-in-out;
}
.boxgallery[data-effect="effect-1"] .panel.active .bg-tile,
.boxgallery[data-effect="effect-2"] .panel.active .bg-tile {
animation: scaleDown 1.1s ease-in-out;
}
@keyframes scaleDown {
from { transform: translate3d(0,0,380px); }
to { transform: translate3d(0,0,0); }
}
/* Variation 2 */
.boxgallery[data-effect="effect-2"] .panel.current .bg-img {
transition: transform 0.9s cubic-bezier(0.7,0,0.3,1);
}
.boxgallery[data-effect="effect-2"] .panel.current .bg-tile:nth-child(2) .bg-img {
transition-delay: 0.15s;
}
.boxgallery[data-effect="effect-2"] .panel.current .bg-tile:nth-child(3) .bg-img {
transition-delay: 0.3s;
}
.boxgallery[data-effect="effect-2"] .panel.current .bg-tile:nth-child(4) .bg-img {
transition-delay: 0.45s;
}
/* Variation 3 */
.boxgallery[data-effect="effect-3"] .panel::after {
position: absolute;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.8);
content: '';
transition: opacity 1.1s ease-in-out;
}
.boxgallery[data-effect="effect-3"] .panel.current::after,
.boxgallery[data-effect="effect-3"] .panel.active::after {
opacity: 0;
}
.boxgallery[data-effect="effect-3"] .panel.current::after {
transition: none;
}
.boxgallery[data-effect="effect-3"] .panel.current .bg-img {
transition: transform 1.1s cubic-bezier(0.7,0,0.3,1);
}
.boxgallery[data-effect="effect-3"] .panel.current .bg-tile:nth-child(2) .bg-img {
transition-delay: 0.15s;
}
.boxgallery[data-effect="effect-3"] .panel.current .bg-tile:nth-child(3) .bg-img {
transition-delay: 0.3s;
}
.boxgallery[data-effect="effect-3"] .panel.current .bg-tile:nth-child(4) .bg-img {
transition-delay: 0.45s;
}
src like the image. We also add the nav element at this point.BoxesFx.prototype._init = function() {
// set transforms configuration
this._setTransforms();
// which effect
this.effect = this.el.getAttribute( 'data-effect' ) || 'effect-1';
// check if animating
this.isAnimating = false;
// the panels
this.panels = [].slice.call( this.el.querySelectorAll( '.panel' ) );
// total number of panels (4 for this demo)
//this.panelsCount = this.panels.length;
this.panelsCount = 4;
// current panel´s index
this.current = 0;
classie.add( this.panels[0], 'current' );
// replace image with 4 divs, each including the image
var self = this;
this.panels.forEach( function( panel ) {
var img = panel.querySelector( 'img' ), imgReplacement = '';
for( var i = 0; i < self.panelsCount; ++i ) {
imgReplacement += '<div class="bg-tile"><div class="bg-img"><img src="' + img.src + '" /></div></div>'
}
panel.removeChild( img );
panel.innerHTML = imgReplacement + panel.innerHTML;
} );
// add navigation element
this.nav = document.createElement( 'nav' );
this.nav.innerHTML = '<span class="prev"><i></i></span><span class="next"><i></i></span>';
this.el.appendChild( this.nav );
// initialize events
this._initEvents();
}
BoxesFx.prototype._setTransforms = function() {
this.transforms = {
'effect-1' : {
'next' : [
'translate3d(0, ' + (win.height/2+10) + 'px, 0)', // transforms for panel 1
'translate3d(-' + (win.width/2+10) + 'px, 0, 0)', // transforms for panel 2
'translate3d(' + (win.width/2+10) + 'px, 0, 0)', // transforms for panel 3
'translate3d(0, -' + (win.height/2+10) + 'px, 0)' // transforms for panel 4
],
'prev' : [
'translate3d(' + (win.width/2+10) + 'px, 0, 0)',
'translate3d(0, ' + (win.height/2+10) + 'px, 0)',
'translate3d(0, -' + (win.height/2+10) + 'px, 0)',
'translate3d(-' + (win.width/2+10) + 'px, 0, 0)'
]
},
'effect-2' : {
'next' : [
'translate3d(-' + (win.width/2+10) + 'px, 0, 0)',
'translate3d(' + (win.width/2+10) + 'px, 0, 0)',
'translate3d(-' + (win.width/2+10) + 'px, 0, 0)',
'translate3d(' + (win.width/2+10) + 'px, 0, 0)'
],
'prev' : [
'translate3d(0,-' + (win.height/2+10) + 'px, 0)',
'translate3d(0,-' + (win.height/2+10) + 'px, 0)',
'translate3d(0,' + (win.height/2+10) + 'px, 0)',
'translate3d(0,' + (win.height/2+10) + 'px, 0)'
]
},
'effect-3' : {
'next' : [
'translate3d(0,' + (win.height/2+10) + 'px, 0)',
'translate3d(0,' + (win.height/2+10) + 'px, 0)',
'translate3d(0,' + (win.height/2+10) + 'px, 0)',
'translate3d(0,' + (win.height/2+10) + 'px, 0)'
],
'prev' : [
'translate3d(0,-' + (win.height/2+10) + 'px, 0)',
'translate3d(0,-' + (win.height/2+10) + 'px, 0)',
'translate3d(0,-' + (win.height/2+10) + 'px, 0)',
'translate3d(0,-' + (win.height/2+10) + 'px, 0)'
]
}
};
}
BoxesFx.prototype._initEvents = function() {
var self = this, navctrls = this.nav.children;
// previous action
navctrls[0].addEventListener( 'click', function() { self._navigate('prev') } );
// next action
navctrls[1].addEventListener( 'click', function() { self._navigate('next') } );
// window resize
window.addEventListener( 'resize', function() { self._resizeHandler(); } );
}
BoxesFx.prototype._navigate = function( dir ) {
if( this.isAnimating ) return false;
this.isAnimating = true;
var self = this, currentPanel = this.panels[ this.current ];
if( dir === 'next' ) {
this.current = this.current < this.panelsCount - 1 ? this.current + 1 : 0;
}
else {
this.current = this.current > 0 ? this.current - 1 : this.panelsCount - 1;
}
// next panel to be shown
var nextPanel = this.panels[ this.current ];
// add class active to the next panel to trigger its animation
classie.add( nextPanel, 'active' );
// apply the transforms to the current panel
this._applyTransforms( currentPanel, dir );
// let´s track the number of transitions ended per panel
var cntTransTotal = 0,
// transition end event function
onEndTransitionFn = function( ev ) {
if( ev && !classie.has( ev.target, 'bg-img' ) ) return false;
// return if not all panel transitions ended
++cntTransTotal;
if( cntTransTotal < self.panelsCount ) return false;
if( support.transitions ) {
this.removeEventListener( transEndEventName, onEndTransitionFn );
}
// remove current class from current panel and add it to the next one
classie.remove( currentPanel, 'current' );
classie.add( nextPanel, 'current' );
// reset transforms for the currentPanel
self._resetTransforms( currentPanel );
// remove class active
classie.remove( nextPanel, 'active' );
self.isAnimating = false;
};
if( support.transitions ) {
currentPanel.addEventListener( transEndEventName, onEndTransitionFn );
}
else {
onEndTransitionFn();
}
}
BoxesFx.prototype._applyTransforms = function( panel, dir ) {
var self = this;
[].slice.call( panel.querySelectorAll( 'div.bg-img' ) ).forEach( function( tile, pos ) {
tile.style.WebkitTransform = self.transforms[self.effect][dir][pos];
tile.style.transform = self.transforms[self.effect][dir][pos];
} );
}
BoxesFx.prototype._resetTransforms = function( panel ) {
[].slice.call( panel.querySelectorAll( 'div.bg-img' ) ).forEach( function( tile ) {
tile.style.WebkitTransform = 'none';
tile.style.transform = 'none';
} );
}
Bee black designer Collectibles © 2015. All Rights Reserved.
Théme Created BYal3arbi