diff --git a/blocks/timeline-slide/timeline-slide.css b/blocks/timeline-slide/timeline-slide.css new file mode 100644 index 00000000..445e7dcf --- /dev/null +++ b/blocks/timeline-slide/timeline-slide.css @@ -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; + } + } \ No newline at end of file diff --git a/blocks/timeline-slide/timeline-slide.js b/blocks/timeline-slide/timeline-slide.js new file mode 100644 index 00000000..24771277 --- /dev/null +++ b/blocks/timeline-slide/timeline-slide.js @@ -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(); +}