gal
by Julien Etienne
HTML
<div class="gal" id="gal">
<div class="gal-next" id="gal-next">▶</div>
<div class="gal-previous" id="gal-previous">
◀
</div> <span class="gal-images" id="gal-images">
<a href="#">
<img src="https://picsum.photos/id/237/800/400" alt="A">
</a>
<a href="#">
<img src="https://picsum.photos/id/456/800/400" alt="B">
</a>
<a href="#">
<img src="https://picsum.photos/id/124/800/400" alt="C">
</a>
<a href="#">
<img src="https://picsum.photos/id/354/800/400" alt="D">
</a>
<a href="#">
<img src="https://picsum.photos/id/338/800/400" alt="E">
</a>
<a href="#">
<img src="https://picsum.photos/id/564/800/400" alt="F">
</a>
<a href="#">
<img src="https://picsum.photos/id/145/800/400" alt="G">
</a>
<a href="#">
<img src="https://picsum.photos/id/387/800/400" alt="H">
</a>
<a href="#">
<img src="https://picsum.photos/id/866/200/300" alt="K">
</a>
</span>
</div>
CSS
.gal {
overflow: hidden;
position: absolute;
border: 1px solid red;
height: 100%;
}
.gal-images {
position: absolute;
display: block;
height: 100%;
}
.gal-images a {
background: #222;
display: flex;
border: 1px solid lime;
position: relative;
float: left;
height: 100%;
align-items: center;
}
.gal-images a img {
width: 120%;
/* width: 100%; */
display: block;
}
.gal-next,
.gal-previous {
background: rgb(0, 0, 0, 0.8);
position: absolute;
z-index: 3;
width: 4rem;
height: 4rem;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.6em;
color: rgba(255, 255, 255, 0.7);
top: calc(50% - 2rem);
cursor: pointer;
}
.gal-next {
right: 0;
}
.gal-previous {
left: 0;
}
JavaScript
/**
YES THE CODE IS A MESS I'M FULLY AWARE
*/
const gal = document.querySelector('#gal');
const galImages = gal.querySelector('#gal-images');
const getGalLinks = () => Array.from(galImages.children).filter(link => link.tagName === 'A');
const galLinks = getGalLinks();
let galImagesLeft = 0;
const setGallerySize = (width, height) => {
const px = 'px';
console.log('galImages', galImages)
const imagesWidth = galLinks.length * width;
galImages.style.width = imagesWidth + px;
galImages.style.marginLeft = '-70%'
gal.style.width = width + px;
gal.style.height = height + px;
galLinks.forEach(link => {
link.style.width = (100 / galLinks.length) * 0.8 + '%'
});
}
// Copy the last node to the start.
const lastLink = galLinks[galLinks.length - 1];
galImages.insertAdjacentElement('afterbegin', lastLink)
setGallerySize(800, 400);
let canCopy = false;
// To prevent leaks
document.addEventListener('mousedown', (e) => {
const {
target
} = e;
if (!gal.contains(target)) {
return;
}
console.log('yeaa')
switch (target.id) {
case 'gal-previous': {
// Copy last
const currentGalLinks = getGalLinks();
const currentLastLink = currentGalLinks[currentGalLinks.length - 1];
galImages.insertAdjacentElement('afterbegin', currentLastLink);
galImagesLeft -= (800 / 100 * 80);
console.log('galImagesLeft', galImagesLeft)
galImages.style.transition = 'none';
galImages.style.left = galImagesLeft + 'px';
requestAnimationFrame(() => {
galImages.style.transition = 'all 400ms ease';
galImagesLeft += (800 / 100 * 80);
galImages.style.left = galImagesLeft + 'px';
});
}
return;
case 'gal-next': {
if (canCopy) {
const currentGalLinks = getGalLinks();
const currentfirstLink = currentGalLinks[0];
galImages.insertAdjacentElement('beforeend', currentfirstLink);
galImagesLeft += (800 / 100 * 80);
console.log('galImagesLeft',...