Skip to content

Instantly share code, notes, and snippets.

@rushkeldon
Created February 4, 2021 09:06
Show Gist options
  • Save rushkeldon/e2726e9c21437d681579ebb12ca8b381 to your computer and use it in GitHub Desktop.
Save rushkeldon/e2726e9c21437d681579ebb12ca8b381 to your computer and use it in GitHub Desktop.
carousel2
<h1>carousel</h1>
<div class="carousel">
<div class="btn left">&lt;</div>
<div class="btn right">&gt;</div>
<div class="stage">
<div class="tile stage-left">10</div>
<div class="tile stage-center">20</div>
<div class="tile stage-right">30</div>
<div class="tile offstage-right">40</div>
<div class="tile offstage-left">50</div>
<div class="tile offstage-left">60</div>
<div class="tile offstage-left">70</div>
<div class="tile offstage-left">80</div>
<div class="tile offstage-left">90</div>
<div class="tile offstage-left">100</div>
</div>
</div>
let isInTransition : boolean = false;
const btnLeft = document.querySelector( '.btn.left' );
btnLeft.addEventListener( 'click', transitionRight );
const btnRight = document.querySelector( '.btn.right' );
btnRight.addEventListener( 'click', transitionLeft );
const stage = document.querySelector( '.stage' );
stage.addEventListener( 'click', stageClicked, true );
const tiles = nodeListToArray( document.querySelectorAll( '.tile' ) );
resetCarousel();
function stageClicked( e ) {
switch( true ) {
case !e.target :
case !e.target.classList.contains( 'tile' ) :
break;
case e.target.classList.contains( 'stage-left' ) :
transitionRight();
break;
case e.target.classList.contains( 'stage-right' ) :
transitionLeft();
break;
case e.target.classList.contains( 'stage-center' ) :
centerTileClicked( e.target );
break;
}
}
function centerTileClicked( centerTile ) {
console.log( centerTile );
}
function transitionLeft() : void {
if( isInTransition ) return;
isInTransition = true;
const offstageTiles = nodeListToArray( document.querySelectorAll( '.tile.offstage-left' ) );
offstageTiles.find( tile => {
tile.className = 'no-transition tile offstage-right';
} );
const stageLeft = document.querySelector( '.stage-left' );
const stageCenter = document.querySelector( '.stage-center' );
const stageRight = document.querySelector( '.stage-right' );
const offStage = getTileToTheRight( stageRight );
stageLeft.addEventListener( 'transitionend', resetCarousel );
stageLeft.className = 'tile offstage-left';
stageCenter.className = 'tile stage-left';
stageRight.className = 'tile stage-center';
offStage.className = 'tile stage-right';
}
function transitionRight() : void {
if( isInTransition ) return;
isInTransition = true;
const offstageTiles = nodeListToArray( document.querySelectorAll( '.tile.offstage-right' ) );
offstageTiles.find( tile => {
tile.className = 'no-transition tile offstage-left';
} );
const stageLeft = document.querySelector( '.stage-left' );
const stageCenter = document.querySelector( '.stage-center' );
const stageRight = document.querySelector( '.stage-right' );
const offStage = getTileToTheLeft( stageLeft );
stageRight.addEventListener( 'transitionend', resetCarousel );
stageLeft.className = 'tile stage-center';
stageCenter.className = 'tile stage-right';
stageRight.className = 'tile offstage-right';
offStage.className = 'tile stage-left';
}
function resetCarousel() {
let offstageTiles = nodeListToArray( document.querySelectorAll( '.tile.offstage-right' ) );
offstageTiles.find( tile => {
tile.removeEventListener( 'transitionend', resetCarousel );
tile.className = 'no-transition tile offstage-right';
} );
offstageTiles = nodeListToArray( document.querySelectorAll( '.tile.offstage-left' ) );
offstageTiles.find( tile => {
tile.removeEventListener( 'transitionend', resetCarousel );
tile.className = 'no-transition tile offstage-left';
} );
isInTransition = false;
}
function nodeListToArray( nodeList : NodeList ) : any[] {
return Array.prototype.slice.call( nodeList );
}
function getTileToTheRight( refTile ){
let nextIndex;
tiles.find( ( tile, i ) =>{
if( tile === refTile ){
nextIndex = i + 1;
return true;
}
} );
return nextIndex >= tiles.length ? tiles[ 0 ] : tiles[ nextIndex ];
}
function getTileToTheLeft( refTile ){
let nextIndex;
tiles.find( ( tile, i ) =>{
if( tile === refTile ){
nextIndex = i - 1;
return true;
}
} );
return nextIndex < 0 ? tiles[ tiles.length - 1 ] : tiles[ nextIndex ];
}
@yellow: #efc369;
@purple: #a494c0;
@orange: #d7925f;
@green: #b5bc67;
@offBlack: #1d1f20;
@lightBlue: #87cefa;
@arrowBtnDims: 45px;
@dimTile: 200px;
@gutter: 40px;
@widthStage: 800px;
/* time */
@transDuration: 0.6s;
@transDurationFast: 0.4s;
@transDurationVeryFast: 0.2s;
@transDurationSlow: 1.5s;
@transUltraFast: 0.1s;
.TransAllCubic( @dur ) {
-webkit-transition: all @dur cubic-bezier(0.7, 0.01, 0.3, 1);
-moz-transition: all @dur cubic-bezier(0.7, 0.01, 0.3, 1);
-o-transition: all @dur cubic-bezier(0.7, 0.01, 0.3, 1);
transition: all @dur cubic-bezier(0.7, 0.01, 0.3, 1);
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
.TransNone() {
-webkit-transition: none !important;
-moz-transition: none !important;
-o-transition: all 0 none !important;
transition: none !important;
}
body {
font-family: "Courier New";
color: @green;
background-color: @offBlack;
font-size: 16px;
}
.yellow {
color: @yellow;
/*font-weight: bold;*/
}
.purple {
color: @purple;
font-weight: bold;
font-size: 18px;
}
.carousel {
position: relative;
width : @widthStage + 40px;
margin: 20px auto;
.btn {
user-select: none;
cursor: pointer;
position: absolute;
top: calc(50% - (@arrowBtnDims * 0.5));
display: inline-block;
width: @arrowBtnDims;
height: @arrowBtnDims;
font-size: 30px;
line-height: @arrowBtnDims;
font-weight: 900;
color: black;
z-index: 10;
text-align: center;
border-radius: 50%;
background: white;
.TransAllCubic( @transDurationVeryFast );
&:hover {
color : green;
}
&.left {
left: 0px;
}
&.right {
right: 0px;
}
}
.stage {
border-radius : 8px;
position: relative;
box-sizing: border-box;
background: #333642;
border: 2px solid @purple;
height: 400px;
width: @widthStage;
margin: 20px auto;
overflow: hidden;
padding: 0;
.tile {
background: @offBlack;
box-shadow: 4px 4px 6px 1px rgba(0, 0, 0, 0.3);
box-sizing: border-box;
user-select: none;
position: absolute;
height: @dimTile * 1.3;
width: @dimTile;
border: 3px solid @green;
top: 0; /*calc( 50% - ( @dimTile * 0.5 ) );*/
bottom: 0;
font-size: 70px;
line-height: @dimTile;
text-align: center;
border-radius: 10px;
color: @yellow;
.TransAllCubic( @transDurationFast );
transform: scale3d(0.8, 0.8, 0.8);
margin: auto 0;
overflow: hidden;
&:before {
content: "$";
font-size: 60%;
vertical-align: super;
}
&.stage-center {
left: calc(50% - (@dimTile * 0.5));
display: inline-block;
transform: scale3d(1.25, 1.25, 1.25);
border: 3px solid @yellow;
color: @green;
opacity: 1;
}
&.stage-left {
left: @gutter;
display: inline-block;
opacity: 0.8;
}
&.stage-right {
left: calc(100% - @dimTile - @gutter);
display: inline-block;
opacity: 0.8;
}
&.offstage-left {
left: -(@dimTile + @gutter);
display: inline-block;
opacity: 0;
transform: scale3d(0.5, 0.5, 0.5);
}
&.offstage-right {
left: calc(100% + @gutter);
display: inline-block;
opacity: 0;
transform: scale3d(0.5, 0.5, 0.5);
}
}
}
}
.no-transition {
.TransNone();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment