JSFiddle - React, Tailwind, and code Playground
by Johan Muller
HTML
<div class="page-index-top-slider">
<div class="is-index-top-slider" data-is="index-top-slider">
<div class="ts-layer ts-layer-a">
<div class="ts-frame ts-frame-left">
<div class="ts-image" style="background-color:rgba(255,0,0,.3);"></div>
</div>
<div class="ts-frame ts-frame-right">
<div class="ts-image" style="background-color:rgba(255,0,0,.7);"></div>
</div>
</div>
<div class="ts-layer ts-layer-b">
<div class="ts-frame ts-frame-left">
<div class="ts-image" style="background-color:rgba(0,255,0,.3);"></div>
</div>
<div class="ts-frame ts-frame-right">
<div class="ts-image" style="background-color:rgba(0,255,0,.7);"></div>
</div>
</div>
<div class="ts-arrows ts-arrow-prev">
prev
</div>
<div class="ts-arrows ts-arrow-next">
next
</div>
</div>
</div>
SCSS
.is-index-top-slider {
display: block;
position: relative;
height: 100%;
background: #fff;
transform: translateZ(0);
.ts-frame {
display: block;
position: absolute;
overflow: hidden;
}
.ts-layer {
display: block;
position: absolute;
top: 0; left: 0;
width: 100%;
height: 100%;
}
.ts-image {
display: block;
position: absolute;
top: 0; left: 0;
width: 100%;
height: 100%;
will-change: transform;
background-repeat: no-repeat;
background-position: 50% 0;
background-size: cover;
}
.ts-layer-a {
.ts-frame-left {
top: 0;
left: 0;
width: 65%;
height: 100%;
}
.ts-frame-right {
top: 0;
left: 65%;
width: 35%;
height: 65%;
}
}
.ts-layer-b {
display: none;
.ts-frame-left {
top: 0;
left: 0;
width: 35%;
height: 65%;
}
.ts-frame-right {
top: 0;
left: 35%;
width: 65%;
height: 100%;
}
}
.ts-arrows {
cursor: pointer;
user-select: none;
display: block;
position: absolute;
width: 40px;
height: 40px;
top: 50%;
margin-top: -20px;
background: #fff;
box-shadow: 1px 1px 5px 0 rgba(0,0,0,.3);
transition: box-shadow .2s, background .2s;
&.ts-arrow-prev {
left: 10px;
}
&.ts-arrow-next {
right: 10px;
}
&:hover {
box-shadow: 1px 1px 10px 1px rgba(0,0,0,.3);
}
&:active {
background: #f0f0f0;
box-shadow: 0 0 5px 0 rgba(0,0,0,.3);
}
}
}
.page-index-top-slider {
position: relative;
display: block;
height: 650px;
}
JavaScript
var indexTopSlider = function($thisModule) {
var params = {
'duration': 700,
'delayRatio': 3,
'buttonPrev': $thisModule.find('.ts-arrow-prev'),
'buttonNext': $thisModule.find('.ts-arrow-next'),
'inner': {
'bouncer': false,
'actionState': 0,
'layerA': $thisModule.find('.ts-layer-a'),
'layerB': $thisModule.find('.ts-layer-b')
}
};
var timerDelay = parseInt(params.duration / params.delayRatio);
var sliderApp = {
'init': function() {
params.buttonPrev.on('click', sliderApp.eventSlidePrev);
params.buttonNext.on('click', sliderApp.eventSlideNext);
},
'eventSlidePrev': function(e) {
e.preventDefault();
if (params.inner.bouncer) {
return false;
} else {
params.inner.bouncer = true;
}
if (params.inner.actionState == 0) {
sliderApp.transformSlide(params.inner.layerB, params.inner.layerA, '100', '-100');
params.inner.actionState = 1;
return false;
}
if (params.inner.actionState == 1) {
sliderApp.transformSlide(params.inner.layerA, params.inner.layerB, '100', '-100');
params.inner.actionState = 0;
return false;
}
},
'eventSlideNext': function(e) {
e.preventDefault();
if (params.inner.bouncer) {
return false;
} else {
params.inner.bouncer = true;
}
if (params.inner.actionState == 0) {
sliderApp.transformSlide(params.inner.layerB, params.inner.layerA, '-100', '100');
params.inner.actionState = 1;
return false;
}
if (params.inner.actionState == 1) {
sliderApp.transformSlide(params.inner.layerA, params.inner.layerB, '-100', '100');
params.inner.actionState = 0;
return false;
}
},
'transformSlide': function(frontLayer, backLayer, frontValue, backValue) {
frontLayer.find('.ts-image').css({
'transition': 'none',
'transform': 'translateX(' +...