PATH:
home
/
lab2454c
/
sothebankuab.com
/
wp-content
/
plugins
/
bdthemes-element-pack
/
assets
/
vendor
/
js
function timeline(collection, options) { const timelines = []; const warningLabel = 'Timeline:'; let winWidth = window.innerWidth; let resizeTimer; let currentIndex = 0; // Set default settings const defaultSettings = { forceVerticalMode: { type: 'integer', defaultValue: 700 }, horizontalStartPosition: { type: 'string', acceptedValues: ['bottom', 'top'], defaultValue: 'top' }, mode: { type: 'string', acceptedValues: ['horizontal', 'vertical'], defaultValue: 'horizontal' }, moveItems: { type: 'integer', defaultValue: 1 }, startIndex: { type: 'integer', defaultValue: 0 }, verticalStartPosition: { type: 'string', acceptedValues: ['left', 'right'], defaultValue: 'left' }, verticalTrigger: { type: 'string', defaultValue: '15%' }, visibleItems: { type: 'integer', defaultValue: 3 } }; // Helper function to test whether values are an integer function testValues(value, settingName) { if (typeof value !== 'number' && value % 1 !== 0) { console.warn(`${warningLabel} The value "${value}" entered for the setting "${settingName}" is not an integer.`); return false; } return true; } // Helper function to wrap an element in another HTML element function itemWrap(el, wrapper, classes) { wrapper.classList.add(classes); el.parentNode.insertBefore(wrapper, el); wrapper.appendChild(el); } // Helper function to wrap each element in a group with other HTML elements function wrapElements(items) { items.forEach((item) => { itemWrap(item.querySelector('.bdt-timeline-content'), document.createElement('div'), 'bdt-timeline-content-wrapper'); itemWrap(item.querySelector('.bdt-timeline-content-wrapper'), document.createElement('div'), 'bdt-timeline-item-inner'); }); } // Helper function to check if an element is partially in the viewport function isElementInViewport(el, triggerPosition) { const rect = el.getBoundingClientRect(); const windowHeight = window.innerHeight || document.documentElement.clientHeight; const defaultTrigger = defaultSettings.verticalTrigger.defaultValue.match(/(\d*\.?\d*)(.*)/); let triggerUnit = triggerPosition.unit; let triggerValue = triggerPosition.value; let trigger = windowHeight; if (triggerUnit === 'px' && triggerValue >= windowHeight) { console.warn('The value entered for the setting "verticalTrigger" is larger than the window height. The default value will be used instead.'); [, triggerValue, triggerUnit] = defaultTrigger; } if (triggerUnit === 'px') { trigger = parseInt(trigger - triggerValue, 10); } else if (triggerUnit === '%') { trigger = parseInt(trigger * ((100 - triggerValue) / 100), 10); } return ( rect.top <= trigger && rect.left <= (window.innerWidth || document.documentElement.clientWidth) && (rect.top + rect.height) >= 0 && (rect.left + rect.width) >= 0 ); } // Helper function to add transform styles function addTransforms(el, transform) { el.style.webkitTransform = transform; el.style.msTransform = transform; el.style.transform = transform; } // Create timelines function createTimelines(timelineEl) { const timelineName = timelineEl.id ? `#${timelineEl.id}` : `.${timelineEl.className}`; const errorPart = 'could not be found as a direct descendant of'; const data = timelineEl.dataset; let wrap; let scroller; let items; const settings = {}; // Test for correct HTML structure try { wrap = timelineEl.querySelector('.bdt-timeline-wrapper'); if (!wrap) { throw new Error(`${warningLabel} .bdt-timeline-wrapper ${errorPart} ${timelineName}`); } else { scroller = wrap.querySelector('.bdt-timeline-items'); if (!scroller) { throw new Error(`${warningLabel} .bdt-timeline-items ${errorPart} .bdt-timeline-wrapper`); } else { items = [].slice.call(scroller.children, 0); } } } catch (e) { console.warn(e.message); return false; } // Test setting input values Object.keys(defaultSettings).forEach((key) => { settings[key] = defaultSettings[key].defaultValue; if (data[key]) { settings[key] = data[key]; } else if (options && options[key]) { settings[key] = options[key]; } if (defaultSettings[key].type === 'integer') { if (!settings[key] || !testValues(settings[key], key)) { settings[key] = defaultSettings[key].defaultValue; } } else if (defaultSettings[key].type === 'string') { if (defaultSettings[key].acceptedValues && defaultSettings[key].acceptedValues.indexOf(settings[key]) === -1) { console.warn(`${warningLabel} The value "${settings[key]}" entered for the setting "${key}" was not recognised.`); settings[key] = defaultSettings[key].defaultValue; } } }); // Further specific testing of input values const defaultTrigger = defaultSettings.verticalTrigger.defaultValue.match(/(\d*\.?\d*)(.*)/); const triggerArray = settings.verticalTrigger.match(/(\d*\.?\d*)(.*)/); let [, triggerValue, triggerUnit] = triggerArray; let triggerValid = true; if (!triggerValue) { console.warn(`${warningLabel} No numercial value entered for the 'verticalTrigger' setting.`); triggerValid = false; } if (triggerUnit !== 'px' && triggerUnit !== '%') { console.warn(`${warningLabel} The setting 'verticalTrigger' must be a percentage or pixel value.`); triggerValid = false; } if (triggerUnit === '%' && (triggerValue > 100 || triggerValue < 0)) { console.warn(`${warningLabel} The 'verticalTrigger' setting value must be between 0 and 100 if using a percentage value.`); triggerValid = false; } else if (triggerUnit === 'px' && triggerValue < 0) { console.warn(`${warningLabel} The 'verticalTrigger' setting value must be above 0 if using a pixel value.`); triggerValid = false; } if (triggerValid === false) { [, triggerValue, triggerUnit] = defaultTrigger; } settings.verticalTrigger = { unit: triggerUnit, value: triggerValue }; if (settings.moveItems > settings.visibleItems) { console.warn(`${warningLabel} The value of "moveItems" (${settings.moveItems}) is larger than the number of "visibleItems" (${settings.visibleItems}). The value of "visibleItems" has been used instead.`); settings.moveItems = settings.visibleItems; } if (settings.startIndex > (items.length - settings.visibleItems) && items.length > settings.visibleItems) { console.warn(`${warningLabel} The 'startIndex' setting must be between 0 and ${items.length - settings.visibleItems} for this timeline. The value of ${items.length - settings.visibleItems} has been used instead.`); settings.startIndex = items.length - settings.visibleItems; } else if (items.length <= settings.visibleItems) { console.warn(`${warningLabel} The number of items in the timeline must exceed the number of visible items to use the 'startIndex' option.`); settings.startIndex = 0; } else if (settings.startIndex < 0) { console.warn(`${warningLabel} The 'startIndex' setting must be between 0 and ${items.length - settings.visibleItems} for this timeline. The value of 0 has been used instead.`); settings.startIndex = 0; } timelines.push({ timelineEl, wrap, scroller, items, settings }); } if (collection.length) { [].forEach.call(collection, createTimelines); } // Set height and widths of timeline elements and viewport function setHeightandWidths(tl) { // Set widths of items and viewport function setWidths() { tl.itemWidth = tl.wrap.offsetWidth / tl.settings.visibleItems; tl.items.forEach((item) => { item.style.width = `${tl.itemWidth}px`; }); tl.scrollerWidth = tl.itemWidth * tl.items.length; tl.scroller.style.width = `${tl.scrollerWidth}px`; } // Set height of items and viewport function setHeights() { let oddIndexTallest = 0; let evenIndexTallest = 0; tl.items.forEach((item, i) => { item.style.height = 'auto'; const height = item.offsetHeight; if (i % 2 === 0) { evenIndexTallest = height > evenIndexTallest ? height : evenIndexTallest; } else { oddIndexTallest = height > oddIndexTallest ? height : oddIndexTallest; } }); const transformString = `translateY(${evenIndexTallest}px)`; tl.items.forEach((item, i) => { if (i % 2 === 0) { item.style.height = `${evenIndexTallest}px`; if (tl.settings.horizontalStartPosition === 'bottom') { item.classList.add('bdt-timeline-item--bottom'); addTransforms(item, transformString); } else { item.classList.add('bdt-timeline-item--top'); } } else { item.style.height = `${oddIndexTallest}px`; if (tl.settings.horizontalStartPosition !== 'bottom') { item.classList.add('bdt-timeline-item--bottom'); addTransforms(item, transformString); } else { item.classList.add('bdt-timeline-item--top'); } } }); tl.scroller.style.height = `${evenIndexTallest + oddIndexTallest}px`; } if (window.innerWidth > tl.settings.forceVerticalMode) { setWidths(); setHeights(); } } // Create and add arrow controls to horizontal timeline function addNavigation(tl) { if (tl.items.length > tl.settings.visibleItems) { const prevArrow = document.createElement('button'); const nextArrow = document.createElement('button'); const topPosition = tl.items[0].offsetHeight; prevArrow.className = 'bdt-timeline-nav-button bdt-timeline-nav-button--prev'; nextArrow.className = 'bdt-timeline-nav-button bdt-timeline-nav-button--next'; prevArrow.textContent = 'Previous'; nextArrow.textContent = 'Next'; prevArrow.style.top = `${topPosition}px`; nextArrow.style.top = `${topPosition}px`; if (currentIndex === 0) { prevArrow.disabled = true; } else if (currentIndex === (tl.items.length - tl.settings.visibleItems)) { nextArrow.disabled = true; } tl.timelineEl.appendChild(prevArrow); tl.timelineEl.appendChild(nextArrow); } } // Add the centre line to the horizontal timeline function addHorizontalDivider(tl) { const divider = tl.timelineEl.querySelector('.bdt-timeline-divider'); if (divider) { tl.timelineEl.removeChild(divider); } const topPosition = tl.items[0].offsetHeight; const horizontalDivider = document.createElement('span'); horizontalDivider.className = 'bdt-timeline-divider'; horizontalDivider.style.top = `${topPosition}px`; tl.timelineEl.appendChild(horizontalDivider); } // Calculate the new position of the horizontal timeline function timelinePosition(tl) { const position = tl.items[currentIndex].offsetLeft; const str = `translate3d(-${position}px, 0, 0)`; addTransforms(tl.scroller, str); } // Make the horizontal timeline slide function slideTimeline(tl) { const navArrows = tl.timelineEl.querySelectorAll('.bdt-timeline-nav-button'); const arrowPrev = tl.timelineEl.querySelector('.bdt-timeline-nav-button--prev'); const arrowNext = tl.timelineEl.querySelector('.bdt-timeline-nav-button--next'); const maxIndex = tl.items.length - tl.settings.visibleItems; const moveItems = parseInt(tl.settings.moveItems, 10); [].forEach.call(navArrows, (arrow) => { arrow.addEventListener('click', function(e) { e.preventDefault(); currentIndex = this.classList.contains('bdt-timeline-nav-button--next') ? (currentIndex += moveItems) : (currentIndex -= moveItems); if (currentIndex === 0 || currentIndex < 0) { currentIndex = 0; arrowPrev.disabled = true; arrowNext.disabled = false; } else if (currentIndex === maxIndex || currentIndex > maxIndex) { currentIndex = maxIndex; arrowPrev.disabled = false; arrowNext.disabled = true; } else { arrowPrev.disabled = false; arrowNext.disabled = false; } timelinePosition(tl); }); }); } // Set up horizontal timeline function setUpHorinzontalTimeline(tl) { currentIndex = tl.settings.startIndex; tl.timelineEl.classList.add('bdt-timeline--horizontal'); setHeightandWidths(tl); timelinePosition(tl); addNavigation(tl); addHorizontalDivider(tl); slideTimeline(tl); } // Set up vertical timeline function setUpVerticalTimeline(tl) { let lastVisibleIndex = 0; tl.items.forEach((item, i) => { item.classList.remove('animated', 'fadeIn'); if (!isElementInViewport(item, tl.settings.verticalTrigger) && i > 0) { item.classList.add('animated'); } else { lastVisibleIndex = i; } const divider = tl.settings.verticalStartPosition === 'left' ? 1 : 0; if (i % 2 === divider && window.innerWidth > tl.settings.forceVerticalMode) { item.classList.add('bdt-timeline-item--right'); } else { item.classList.add('bdt-timeline-item--left'); } }); for (let i = 0; i < lastVisibleIndex; i += 1) { tl.items[i].classList.remove('animated', 'fadeIn'); } // Bring elements into view as the page is scrolled window.addEventListener('scroll', () => { tl.items.forEach((item) => { if (isElementInViewport(item, tl.settings.verticalTrigger)) { item.classList.add('fadeIn'); } }); }); } // Reset timelines function resetTimelines(tl) { tl.timelineEl.classList.remove('bdt-timeline--horizontal', 'bdt-timeline--mobile'); tl.scroller.removeAttribute('style'); tl.items.forEach((item) => { item.removeAttribute('style'); item.classList.remove('animated', 'fadeIn', 'bdt-timeline-item--left', 'bdt-timeline-item--right'); }); const navArrows = tl.timelineEl.querySelectorAll('.bdt-timeline-nav-button'); [].forEach.call(navArrows, (arrow) => { arrow.parentNode.removeChild(arrow); }); } // Set up the timelines function setUpTimelines() { timelines.forEach((tl) => { tl.timelineEl.style.opacity = 0; if (!tl.timelineEl.classList.contains('bdt-timeline--loaded')) { wrapElements(tl.items); } resetTimelines(tl); if (window.innerWidth <= tl.settings.forceVerticalMode) { tl.timelineEl.classList.add('bdt-timeline--mobile'); } if (tl.settings.mode === 'horizontal' && window.innerWidth > tl.settings.forceVerticalMode) { setUpHorinzontalTimeline(tl); } else { setUpVerticalTimeline(tl); } tl.timelineEl.classList.add('bdt-timeline--loaded'); setTimeout(() => { tl.timelineEl.style.opacity = 1; }, 500); }); } // Initialise the timelines on the page setUpTimelines(); window.addEventListener('resize', () => { clearTimeout(resizeTimer); resizeTimer = setTimeout(() => { const newWinWidth = window.innerWidth; if (newWinWidth !== winWidth) { setUpTimelines(); winWidth = newWinWidth; } }, 250); }); } // Register as a jQuery plugin if the jQuery library is present if (window.jQuery) { (($) => { $.fn.timeline = function(opts) { timeline(this, opts); return this; }; })(window.jQuery); }
[-] SplitText.js
[edit]
[-] awesomeCloud.min.js
[edit]
[-] prism.min.js
[edit]
[-] jquery.progressScroll.js
[edit]
[-] jquery.mThumbnailScroller.min.js
[edit]
[-] parallax.js
[edit]
[-] chart.min.js
[edit]
[-] typed.min.js
[edit]
[-] jquery.appear.min.js
[edit]
[-] lottie.d.ts
[edit]
[-] jquery.imagezoom.js
[edit]
[-] jquery.tagcanvas.min.js
[edit]
[-] prism.js
[edit]
[-] metisMenu.js
[edit]
[-] lottie.js
[edit]
[-] jquery.honeycombs.js
[edit]
[-] sidetabs.js
[edit]
[-] timeline.min.js
[edit]
[-] datatables.min.js
[edit]
[-] datatables.uikit.js
[edit]
[-] jquery.appear.js
[edit]
[+]
..
[-] popper.js
[edit]
[-] jquery.jplayer.js
[edit]
[-] image-compare-viewer.min.js
[edit]
[-] calendly.js
[edit]
[-] tilt.jquery.js
[edit]
[-] particles.min.js
[edit]
[-] jquery.progressHorizontal.min.js
[edit]
[-] timeline.js
[edit]
[-] jQuery.circleMenu.min.js
[edit]
[-] tippy.all.min.js
[edit]
[-] calendly.min.js
[edit]
[-] jquery.jplayer.min.js
[edit]
[-] jquery.newsTicker.min.js
[edit]
[-] darkmode.min.js
[edit]
[-] goodshare.min.js
[edit]
[-] SplitText.min.js
[edit]
[-] jquery.newsTicker.js
[edit]
[-] jquery.flatWeatherPlugin.min.js
[edit]
[-] rvslider.min.js
[edit]
[-] gmap.min.js
[edit]
[-] jquery.jclock.min.js
[edit]
[-] chart.js
[edit]
[-] jquery.mousewheel.js
[edit]
[-] vanilla-tilt.js
[edit]
[-] search.min.js
[edit]
[-] jquery.justifiedGallery.min.js
[edit]
[-] pageable.min.js
[edit]
[-] particles.js
[edit]
[-] jquery.imagezoom.min.js
[edit]
[-] jquery.mousewheel.min.js
[edit]
[-] gmap.js
[edit]
[-] news-ticker.min.js
[edit]
[-] datatables.uikit.min.js
[edit]
[-] tippy.all.js
[edit]
[-] gsap.js
[edit]
[-] table-of-content.min.js
[edit]
[-] gsap.min.js
[edit]
[-] metisMenu.min.js
[edit]
[-] wavify.min.js
[edit]
[-] jquery.progressScroll.min.js
[edit]
[-] morphext.min.js
[edit]
[-] darkmode.js
[edit]
[-] gridtab.min.js
[edit]
[-] morphext.js
[edit]
[-] image-compare-viewer.js
[edit]
[-] parallax.min.js
[edit]
[-] search.js
[edit]
[-] sidetabs.min.js
[edit]
[-] recliner.js
[edit]
[-] countUp.js
[edit]
[-] clipboard.js
[edit]
[-] jquery-asPieProgress.min.js
[edit]
[-] wavify.js
[edit]
[-] recliner.min.js
[edit]
[-] jquery.jclock.js
[edit]
[-] pageable.js
[edit]
[-] jquery.tagcanvas.js
[edit]
[-] gridtab.js
[edit]
[-] jquery-qrcode.js
[edit]
[-] countUp.min.js
[edit]
[-] awesomeCloud.js
[edit]
[-] jquery-asPieProgress.js
[edit]
[-] lottie.min.js
[edit]
[-] moment-timezone-with-data.min.js
[edit]
[-] jquery.justifiedGallery.js
[edit]
[-] datatables.js
[edit]
[-] rvslider.js
[edit]
[-] jquery.flatWeatherPlugin.js
[edit]
[-] moment.min.js
[edit]
[-] jquery.honeycombs.min.js
[edit]
[-] table-of-content.js
[edit]
[-] goodshare.js
[edit]
[-] leaflet.js
[edit]
[-] cookieconsent.min.js
[edit]
[-] moment-timezone-with-data.js
[edit]
[-] jQuery.circleMenu.js
[edit]
[-] leaflet.min.js
[edit]
[-] vanilla-tilt.min.js
[edit]
[-] floating-video.min.js
[edit]
[-] typed.js
[edit]
[-] popper.min.js
[edit]
[-] spritespin.js
[edit]
[-] jquery.progressHorizontal.js
[edit]
[-] floating-video.js
[edit]
[-] jquery.mThumbnailScroller.js
[edit]
[-] moment.js
[edit]
[-] spritespin.min.js
[edit]
[-] tilt.jquery.min.js
[edit]
[-] jquery-qrcode.min.js
[edit]
[-] cookieconsent.js
[edit]