Skip to content

Commit

Permalink
Merge pull request #117 from hlxsites/timeline-slider
Browse files Browse the repository at this point in the history
Added timeline slider
  • Loading branch information
davenichols-DHLS authored Nov 14, 2023
2 parents 46ff260 + 5e74cfa commit 183a290
Show file tree
Hide file tree
Showing 2 changed files with 304 additions and 0 deletions.
175 changes: 175 additions & 0 deletions blocks/timeline-slide/timeline-slide.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/* Container styles */
.timeline-slide {
display: flex;
flex-direction: column;
align-items: center;
padding: 40px 0;
overflow: hidden;
}

/* Slider styles */
#year-slider {
display: flex;
overflow: hidden;
transform: translate3d(43%, 0, 0);
transition: 0.5s all ease-in-out;
transition-duration: 0ms;
}

.year {
cursor: pointer;
border-radius: 5px;
color: #dbdbdb;
font-size: 40px;
font-weight: 700;
transition: 0.3s all ease-in-out;
text-align: center;
}

.year:hover, .year.active {
color: #f49600;
transition: 0.3s all ease-in-out;
}

/* Content area styles */
#content-slider-container {
position: relative;
width: 100%;
}

#content-slider {
/* width: 100%; */
display: flex;
align-items: center;
min-height: 250px;
max-width: 600px;
margin: 0 auto;
overflow: hidden;
}

#content-slider li::before {
color: var(--primary-color);
content: "\25A0";
font-family: Arial;
font-size: 1em;
left: 0;
line-height: 100%;
position: absolute;
top: 0.45em;
}

.year-content {
display: none;
transition: transform 0.5s ease, opacity 0.5s ease;
opacity: 0;
left: 0;
right: 0;
}

.year-content.active {
display: block;
opacity: 1;
transform: translateX(0);
}

/* buttons */
.button-container {
width: 100%;
position: absolute;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: space-between;
}

.button-container .hide {
opacity: 0.5;
}

.button-prev {
border: 2px solid #f49600;
border-radius: 50%;
color: #f49600;
cursor: pointer;
height: 50px;
text-align: center;
transition: all .3s;
user-select: none;
width: 50px;
position: relative;
float: left;
margin: 15px;
}

.button-prev::after {
content: '';
border: 2px solid #f49600;
border-width: 0 2px 2px 0;
transform: rotate(135deg); /* Rotates the arrow to point left */
position: absolute;
top: 15px;
left: 20px;
right: 0;
bottom: 0;
width: 20px;
height: 20px;
}

.button-next {
border: 2px solid #f49600;
border-radius: 50%;
color: #f49600;
cursor: pointer;
height: 50px;
text-align: center;
transition: all .3s;
user-select: none;
width: 50px;
position: relative;
float: right;
margin: 15px;
}



.button-next:hover {
background-color: #f49600;
}

.button-next:hover::after {
border-color: #fff;
}


.button-prev:hover {
background-color: #f49600;
}

.button-prev:hover::after {
border-color: #fff;
}

.button-next::after {
content: '';
border: 2px solid #f49600;
border-width: 0 2px 2px 0;
transform: rotate(315deg); /* Rotates the arrow to point left */
position: absolute;
top: 15px;
left: 10px;
right: 0;
bottom: 0;
width: 20px;
height: 20px;
}

@media (max-width: 767px) {
.button-container {
position: relative;
justify-content: center;
}
}
129 changes: 129 additions & 0 deletions blocks/timeline-slide/timeline-slide.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { div } from '../../scripts/dom-builder.js';

export default function decorate(block) {
const yearSlider = div({ id: 'year-slider' });
const contentSliderContainer = div({ id: 'content-slider-container' });
const contentSlider = div({ id: 'content-slider' });
const nextButton = div({ class: 'button-block' }, div({ class: 'button-next' }));
const prevButton = div({ class: 'button-block' }, div({ class: 'button-prev' }));
const buttonContainer = div({ class: 'button-container' });
let activeYearIndex = 0;

buttonContainer.appendChild(prevButton);
buttonContainer.appendChild(nextButton);

function translateYearSlider() {
const yearWidth = yearSlider.children[0].offsetWidth;
const translateDistance = yearWidth * activeYearIndex;
yearSlider.style.transform = `translate3d(calc( 43% - ${translateDistance}px ), 0px, 0px)`;
}

// Function to clear all active classes
function clearActiveClasses() {
[...yearSlider.children].forEach((year) => {
year.classList.remove('active');
});
[...contentSlider.children].forEach((content) => {
content.classList.remove('active');
});
}

function applySlideEffect(index, direction) {
const content = block.querySelector(`#content-${yearSlider.children[index].textContent.trim()}`);
if (content) {
// Apply sliding effect
content.style.transform = `translateX(${direction === 'left' ? '100%' : '-100%'})`;
setTimeout(() => {
content.style.transform = 'translateX(0)';
}, 50); // Delay to ensure the transition effect is applied
}
}

nextButton.addEventListener('click', () => {
// Calculate the next index
const nextIndex = activeYearIndex + 1;

if (nextIndex < yearSlider.children.length) {
// Move to the next year and update the active index
yearSlider.children[nextIndex].click();
activeYearIndex = nextIndex;
// Always show the prev button when moving forward
prevButton.classList.remove('hide');
translateYearSlider();
}

// Hide the next button if we reach the end
if (nextIndex === yearSlider.children.length - 1) {
nextButton.classList.add('hide');
}
});

prevButton.addEventListener('click', () => {
const prevIndex = activeYearIndex - 1;

if (prevIndex >= 0) {
// Move to the previous year and update the active index
yearSlider.children[prevIndex].click();
activeYearIndex = prevIndex;

// Always show the next button when moving backward
nextButton.classList.remove('hide');

// Translate the year slider
translateYearSlider();
}

// Hide the prev button if we reach the beginning
if (prevIndex === 0) {
prevButton.classList.add('hide');
}
});

[...block.children].forEach((child) => {
if (child.children.length >= 2) {
const yearChild = child.children[0].cloneNode(true);
yearChild.classList.add('year');
yearChild.style.width = '130px';
yearSlider.appendChild(yearChild);
const contentChild = child.children[1].cloneNode(true);
contentChild.classList.add('year-content');
contentChild.id = `content-${yearChild.innerText}`;
contentSlider.appendChild(contentChild);
}
});

block.innerHTML = '';
block.appendChild(yearSlider);
contentSliderContainer.appendChild(contentSlider);
contentSliderContainer.appendChild(buttonContainer);
block.appendChild(contentSliderContainer);
block.classList.add('clearfix');

[...yearSlider.children].forEach((year, index) => {
year.addEventListener('click', () => {
clearActiveClasses();

// Check direction for slide effect
const direction = index > activeYearIndex ? 'left' : 'right';
applySlideEffect(index, direction);

// Update active year
activeYearIndex = index;

translateYearSlider();

year.classList.add('active');
const contentId = `#content-${year.textContent.trim()}`;
block.querySelector(contentId).classList.add('active');
});
});

function makeElementActive() {
yearSlider.children[0].classList.add('active');
contentSlider.children[0].classList.add('active');
activeYearIndex = 0;
prevButton.classList.add('hide');
}

makeElementActive();
}

0 comments on commit 183a290

Please sign in to comment.