Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ohsoren/32981efd7e483a44663272854f2598ad to your computer and use it in GitHub Desktop.
Save ohsoren/32981efd7e483a44663272854f2598ad to your computer and use it in GitHub Desktop.
Horizontal Centered Slider Hearts Duo-Tone
<!--
HUGE SHOUTOUT to Lentie Ward
https://codepen.io/lentilz
https://codepen.io/lentilz/pen/mPOKdG
[thank you]
-->
<section class="sliderWrapper">
<div class="slider" data-slider-moving="false">
<div class="slide slide-1">1</div>
<div class="slide slide-2">2</div>
<div class="slide slide-3">3</div>
<div class="slide slide-4">4</div>
<div class="slide slide-5">5</div>
</div>
<button class="button buttonLeft">left</button>
<button class="button buttonRight">right</button>
</section>
<p>Next element after .sliderWrapper</p>
<svg class="duotone-filters" xmlns="http://www.w3.org/2000/svg">
<filter id="duotone_soren">
<feColorMatrix type="matrix" result="gray"
values="1 0 0 0 0
1 0 0 0 0
1 0 0 0 0
0 0 0 1 0" >
</feColorMatrix>
<feComponentTransfer color-interpolation-filters="sRGB" result="duotone">
<feFuncR type="table" tableValues="0.1647058824 0.2"></feFuncR>
<feFuncG type="table" tableValues="0.6588235294 0.2"></feFuncG>
<feFuncB type="table" tableValues="0.5490196078 0.2"></feFuncB>
<feFuncA type="table" tableValues="0 1"></feFuncA>
</feComponentTransfer>
</filter>
</svg>
/**
* Horizontally ceneterd slider/carousel
* caveat: slides are equal width
*/
var sliderWrapper = document.querySelector('.sliderWrapper');
var slider = document.querySelector(".slider");
var sliderWidth, slideWidth, slideHeight, sliderSpeed = 1000;
var sliderDimensions = slider.getBoundingClientRect();
var myWidth, left, itm, cln;
var buttonLeft = document.querySelector(".buttonLeft");
var buttonRight = document.querySelector(".buttonRight");
/**
* we want to keep the slider horizontally centered
* let's calculate shit and do stuff when window resized
*/
function keepSliderCenter() {
/* we need to calculate some shit. we'll need the width and height of a slide to calculate the slider width and height; we also need the window width. the plan is to push or pull the slider into position depending on its and the windows width */
// get first slide width
slideWidth = slider.firstElementChild.getBoundingClientRect().width;
// get first slide height
slideHeight = slider.firstElementChild.getBoundingClientRect().height;
// set slider width by slide width (times by number of slides)
slider.style.width = (slideWidth * 5) + "px";
// set slider wrapper height by slide height so that any content below clears the absolute positioned slider
sliderWrapper.style.height = slideHeight + "px";
// get window width
myWidth = window.innerWidth;
// get slider width
sliderWidth = slider.getBoundingClientRect().width;
// when we resize, if window width is equal to or greather than slider width
if (myWidth => sliderWidth) {
// push slider to center on window
left = (myWidth - sliderWidth) / 2;
slider.style.left = left + "px";
}
else {
// pull slider to center of window
left = (sliderWidth - myWidth) / 2;
slider.style.left = left + "px";
}
};
/**
* now let's make the slider move with buttons
*/
// we've clicked the button, the slider is about to move
// prepare the slider for transition
function sliderIsAboutToMove(ev) {
// disable button
ev.target.disabled = true;
// get slider dimensions in advance
sliderDimensions = slider.getBoundingClientRect();
// get slide width in advance
slideWidth = slider.firstElementChild.getBoundingClientRect().width;
// set slider moving data attribute to true
slider.setAttribute('data-slider-moving', 'true');
}
// the slider has stopped moving
// reset the slider to it's pre-transition state
function resetSlider(ev) {
// reset slider moving data attribute to false
slider.setAttribute('data-slider-moving', 'false');
// move slider back to original position
slider.style.left = sliderDimensions.left + "px";
// enable button now slider not moving
ev.target.disabled = false;
}
// let's do shit with left button
function leftButton(ev) {
// prepare the slider for transition
sliderIsAboutToMove(ev);
// let's go! push slider right by 1 slide width
slider.style.left = (sliderDimensions.left + slideWidth) + "px";
// get last slide
itm = slider.lastElementChild;
// clone last slide
cln = itm.cloneNode(true);
// do slide clone shit after slider transition ends
setTimeout(function() {
// remove last slide from slider
itm.remove();
// prepend clonded last slide to slider
slider.prepend(cln);
// slider transition has ended so reset slider
resetSlider(ev);
}, sliderSpeed)
}
// let's do pretty much the same shit with right button
function rightButton(ev) {
// prepare the slider for transition
sliderIsAboutToMove(ev);
// let's go! pull slider left by 1 slide width
slider.style.left = (sliderDimensions.left - slideWidth) + "px";
// get first slide
itm = slider.firstElementChild;
// clone first slide
cln = itm.cloneNode(true);
// do slide clone shit after slider transition ends
setTimeout(function() {
// remove first slide from slider
itm.remove();
// append clonded last slide to slider
slider.append(cln);
// slider transition has ended so reset slider
resetSlider(ev);
}, sliderSpeed)
}
// center on resize
window.onresize = keepSliderCenter;
// center on window load
window.onload = keepSliderCenter;
// left button event
buttonLeft.addEventListener("mouseup", leftButton);
// right button event
buttonRight.addEventListener("mouseup", rightButton);
:root {
--slide-width: 350px;
--slide-width-large: 700px;
--slide-height: 150px;
--slide-height-large: 200px;
--slide-bg-color: darkslateblue;
--slide-bg-color-highlight: slateblue;
}
body {
position: relative;
background-color: #333;
color: #e4e4e4;
font-weight: 300;
overflow: hidden;
}
body:before {
content: "";
display: block;
position: absolute;
top: 0;
bottom: 0;
height: 100vh;
left: 50%;
transform: translateX(-1px);
border-right: 2px dashed var(--slide-bg-color-highlight);
z-index: 20;
}
.sliderWrapper {
position: relative;
}
.slider {
position: absolute;
display: flex;
top: 0;
z-index: 5;
}
.slide {
flex: 0 0 var(--slide-width);
height: var(--slide-height);
background-size: 100% auto;
background-position: center;
text-align: center;
transition: background .3s;
z-index: 10;
/* filter: grayscale(100%); */
-webkit-filter: url(#duotone_soren);
-moz-filter: url(#duotone_soren);
-o-filter: url(#duotone_soren);
-ms-filter: url(#duotone_soren);
filter: url(#duotone_soren);
}
@media (min-width: 900px) {
.slide {
flex: 0 0 var(--slide-width-large);
height: var(--slide-height-large);
}
}
[data-slider-moving="false"] .slide:nth-child(3n):hover {
filter: none;
}
.slide-1 {
background-image: url('http://www.vectorbackground.net/wp-content/uploads/2013/06/Landscape_007.jpg');
}
.slide-2 {
background-image: url('https://previews.123rf.com/images/iimages/iimages1204/iimages120401206/13131616-Illustration-of-a-forest-Stock-Vector-forest-cartoon-jungle.jpg');
}
.slide-3 {
background-image: url('http://images.all-free-download.com/images/graphiclarge/cartoon_landscape_vector_background_278494.jpg');
}
.slide-4 {
background-image: url('https://images.vexels.com/media/users/2122/71333/preview2/7fab2f1c46e4208c996ddade1ede7749-forest-side-river-cartoon-landscape.jpg');
}
.slide-5 {
background-image: url('https://i.pinimg.com/736x/a1/cf/0d/a1cf0d5a2af2650a58c2d809cd7b90e7--original-wallpaper-cartoon.jpg');
}
[data-slider-moving="true"] {
transition: 1s;
}
.button {
position: absolute;
top: 0;
bottom: 0;
width: 44px;
background-color: rgba(34, 34, 34, .8);
border: 0;
z-index: 15;
opacity: 0;
text-indent: -9999px;
transition: opacity .35s;
}
.sliderWrapper:hover .button {
transition-delay: .1s;
opacity: 1;
cursor: pointer;
}
.buttonLeft {
left: 0;
}
.buttonRight {
right: 0;
}
.button:after {
content: "";
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 20px;
height: 20px;
background-color: slateblue;
}
.button[disabled],
.button[disabled]:hover {
opacity: .5;
}
.duotone-filters {
height: 0;
left: -9999em;
margin: 0;
padding: 0;
position: absolute;
width: 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment