Skip to content

Instantly share code, notes, and snippets.

@bluebrown
Last active March 8, 2020 20:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bluebrown/7ec0bcf85870f09aa7cec9dcbb603c0f to your computer and use it in GitHub Desktop.
Save bluebrown/7ec0bcf85870f09aa7cec9dcbb603c0f to your computer and use it in GitHub Desktop.
Slider
:root {
overflow: hidden;
--slide-transition: all 2s ease 0s;
--image-height: 300px;
--image-padding: 0.2vw;
--image-opacity: 0.5;
--image-left: 0%;
--wrap-width: 100%;
--wrap-right: 00%;
/* uncomment for a look under the hood */
/* --screen-width: 10vw;
--screen-border: black groove 5px;
--slider-border: red 1px groove; */
}
.screen {
width: var(--screen-width);
margin: auto;
border: var(--screen-border);
}
.slider-wrap {
border: var(--slider-border);
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: var(--wrap-width);
position: relative;
right: var(--wrap-right);
}
.img-box {
display: flex;
flex-direction: column;
flex-basis: 100%;
flex: 1;
position: relative;
left: var(--image-left);
transition: var(--slide-transition);
padding: var(--image-padding);
}
.img {
display: block;
background: gray;
height: var(--image-height);
opacity: var(--image-opacity);
border-radius: 6px;
}
<div class="screen">
<div class="slider-wrap"></div>
</div>
<template id='template'>
<div class="img-box">
<span class="img"></span>
</div>
</template>
const wrap = document.querySelector(".slider-wrap"),
style = document.documentElement.style;
// do change
const lazy = 3
const slideMany = lazy;
const elementsOnScreen = lazy;
// do not change
// as a second row eventaully slides in, the number of elements must be
// double the number of screen plus two for the overlapping quarter
const numberOfElements = 2 * elementsOnScreen + 2
// calculate how much space one elements takes on the visible screen
// and multiply its value by the number of elements
const wrapWidth =
(100 / (elementsOnScreen + 0.5)) * numberOfElements;
// the offset should be a quarter of one image
// as there is always 0.5 image more on the screen. Meaning,
// on each site one quarter of an image should be visible.
const wrapRight = 100 + wrapWidth / numberOfElements / 4;
// move all images by the width of one image
// multiplied by the amount of images to move
const imgLeft = 100 / numberOfElements * slideMany;
// adjust inital position
style.setProperty("--wrap-width", wrapWidth + "%");
style.setProperty("--wrap-right", wrapRight + "%");
const randomColor = () =>
"#" + Math.floor(Math.random() * 16777215).toString(16);
let imageCounter = 25
const slide = () => {
style.setProperty("--image-left", imgLeft + "%");
setTimeout(() => {
style.setProperty("--slide-transition", "none");
style.setProperty("--image-left", "0%");
Array.from(wrap.children)
.slice(-slideMany)
.forEach((c, i) => {
c.children[0].style.backgroundColor = randomColor();
//c.children[0].style.backgroundImage = `url('https://picsum.photos/id/${imageCounter++}/600/300')`
wrap.prepend(c);
});
setTimeout(
() => style.setProperty("--slide-transition", "all 2s ease 0s"),
1000
);
}, 3000);
};
const rotate = () => setInterval(slide, 10*1000);
for (let i = 0; i < numberOfElements; i++) {
let tmpl = document.getElementById("template");
let clone = tmpl.cloneNode(true).content;
let child = clone.children[0].children[0]
child.style.backgroundColor = randomColor();
//child.style.backgroundImage = `url('https://picsum.photos/id/${imageCounter++}/600/300')`
wrap.append(clone);
}
rotate();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment