Files
partition-jlg-theme/resources/scripts/app.js
T

516 lines
19 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import domReady from '@roots/sage/client/dom-ready';
/**
* Application entrypoint
*/
domReady(async () => {
// pour régler tous les pb au refresh quand la page est déjà scrollée
window.scrollTo(0, 0);
// CLEANER LE TABLEAU
let minHeadTh = document.querySelector("#main table thead tr th:first-of-type");
minHeadTh.style.width = `${100 / 8}%`;
let otherHeadThs = document.querySelectorAll("#main table thead tr th:not(:first-of-type)");
for (let otherHeadTh of otherHeadThs) {
otherHeadTh.style.width = `${100 / 8 * 1.75}%`;
}
let minTableTds = document.querySelectorAll("#main table tbody tr td:first-of-type");
for (let minTableTd of minTableTds) {
if (minTableTd.parentNode.childElementCount != 1) {
minTableTd.style.width = `${100 / 8}%`;
}
}
let otherTableTds = document.querySelectorAll("#main table tbody tr td:not(:first-of-type)");
for (let otherTableTd of otherTableTds) {
otherTableTd.style.width = `${100 / 8 * 1.75}%`;
}
// HEADER AU SCROLL
let tableHead = document.querySelector("thead tr");
let tHeadHeight = tableHead.offsetHeight;
tableHead.style.maxHeight = `${tHeadHeight}px`;
let headerHeight = document.querySelector("header").offsetHeight;
window.onscroll = () => {
tableHead.style.minHeight = `${headerHeight + 72}px`;
let scroll = window.scrollY;
let headerNewHeight = tHeadHeight - scroll;
if (headerNewHeight > 72) {
tableHead.style.height = `${headerHeight + headerNewHeight}px`;
} else {
tableHead.style.height = tableHead.style.minHeight;
}
}
// italiques -> A FAIRE SUR LE CSV AVANT D'IMPORTER CA RALENTIT DE OUF LE CHARGEMENT
/* let tbody = document.querySelector('body main table tbody');
let tbodyContent = tbody.innerHTML;
let asteriskCounter = 0;
for (let i = 0; i < tbodyContent.length; i++) {
if (tbodyContent[i] == "*") {
if (asteriskCounter % 2 == 0) {
tbodyContent = tbodyContent.substring(0, i) + '<span class="font-caslon italic">' + tbodyContent.substring(i + 1);
} else {
tbodyContent = tbodyContent.substring(0, i) + '</span>' + tbodyContent.substring(i + 1);
}
asteriskCounter++;
}
}
tbody.innerHTML = tbodyContent;
*/
// titres de parties dans le tableau
let mainpartTitless = document.querySelectorAll('.isMainPart');
for (let mainpartTitles of mainpartTitless) {
if (mainpartTitles.nextElementSibling.classList.contains('isSubPart')) {
mainpartTitles.firstElementChild.firstElementChild.style.height = "1.5rem";
mainpartTitles.firstElementChild.style.marginBottom = "-0.25rem";
mainpartTitles.style.borderBottom = "0";
mainpartTitles.style.paddingBottom = "0";
mainpartTitles.nextElementSibling.style.paddingTop = "0";
}
}
// couleurs titres
let colors = [
{'red' : 'cf0118'},
{'blue1': '0101c4'},
{'blue2': '01049e'},
{'blue3': '010678'},
{'blue4': '010952'},
{'blue5': '00113c'},
{'yellow1': 'ade719'},
{'yellow2': '8cc700'},
{'yellow3': '74af00'},
{'yellow4': '5c9900'},
{'yellow5': '377600'},
{'pink1': 'cf0118'},
{'pink2': 'a10418'}
];
let titles = document.querySelectorAll('.isMainPart, .isSubPart');
let partTitles = [];
for (let title of titles) {
if (!title.nextElementSibling.classList.contains('isSubPart')) {
partTitles.push(title);
}
}
for (let i = 0; i < partTitles.length; i++) {
if (partTitles[i].previousElementSibling?.classList.contains('isMainPart')) {
partTitles[i].previousElementSibling.firstElementChild.firstElementChild.style.backgroundColor = "#" + Object.values(colors[i])[0];
}
partTitles[i].firstElementChild.firstElementChild.style.backgroundColor = "#" + Object.values(colors[i])[0];
}
// set parts rectangles
function convertToSeconds(timeStr) {
let [hourStr, minStr] = timeStr.split('h');
if (!minStr) {
minStr = hourStr;
hourStr = '0';
}
minStr = minStr.replace('', ':');
minStr = minStr.replace("'", ':');
const [min, sec] = minStr.split(':');
return parseInt(hourStr) * 3600 + parseInt(min) * 60 + parseInt(sec);
}
let partTimesNodes = document.querySelectorAll('body #app main tbody tr:not(.isContentPart) + tr:not(.isSubPart) td:first-of-type');
let partTimes = Array.from(partTimesNodes);
for (let i = 0; i < partTimes.length; i++) {
partTimes[i] = convertToSeconds(partTimes[i].innerText);
}
let lastTime = document.querySelectorAll('body #app main tbody tr:last-of-type td:first-of-type');
partTimes.push(convertToSeconds(lastTime[0].innerText));
let partDurations = [];
for (let i = 0; i < partTimes.length - 1; i++) {
partDurations.push(partTimes[i + 1] - partTimes[i]);
}
let totalTime = convertToSeconds(lastTime[0].innerText);
let tlContainer, tlContainerHeight, bodyHeight;
let partBlockHeights = [];
let activePartIndex = 0;
function getAllHeights() {
partBlockHeights = [];
tlContainer = document.querySelector('#timeline_container');
let header = document.querySelector('header'), footer = document.querySelector('footer');
tlContainer.style.height = `calc(100vh - ${header.offsetHeight}px - ${footer.offsetHeight}px - 60px)`;
tlContainer.style.top = `${document.querySelector('header').offsetHeight + 30}px`;
tlContainerHeight = tlContainer.offsetHeight;
bodyHeight = document.querySelector('body').offsetHeight;
for (let partDuration of partDurations) {
partBlockHeights.push(partDuration / totalTime * tlContainerHeight);
}
}
getAllHeights();
function drawFriseRects() {
for (let i = 0; i < partBlockHeights.length; i++) {
let partDiv = document.createElement('div');
partDiv.style.width = "22px";
partDiv.style.height = partBlockHeights[i] + "px";
partDiv.style.backgroundColor = "#" + Object.values(colors[i])[0];
partDiv.style.borderBottom = "solid 1px #010d19";
partDiv.style.borderTop = "solid 1px #010d19";
partDiv.style.transition = "width 0.3s ease-out";
partDiv.style.cursor = "pointer";
tlContainer.prepend(partDiv);
tlContainer.children[0].addEventListener("mouseenter", function() {
let el = tlContainer.children[tlContainer.children.length - 1 - i];
if (Array.from(el.parentNode.children).length - Array.from(el.parentNode.children).indexOf(el) - 1 != activePartIndex) {
el.style.width = "32px";
toggleTitleHover(i, 'show');
}
});
tlContainer.children[0].addEventListener("mouseleave", function() {
let el = tlContainer.children[tlContainer.children.length - 1 - i];
if (Array.from(el.parentNode.children).length - Array.from(el.parentNode.children).indexOf(el) - 1 != activePartIndex) {
el.style.width = "22px";
}
toggleTitleHover(i, 'hide');
});
tlContainer.children[0].addEventListener("click", function() {
titresFrise[i].el.scrollIntoView({ behavior: 'smooth', block: 'center' });
});
}
}
drawFriseRects();
window.addEventListener('resize', () => {
while(tlContainer.lastChild) {
tlContainer.removeChild(tlContainer.lastChild);
}
getAllHeights();
drawFriseRects();
});
// titres parties frise
let titreFriseEl = document.createElement('div');
let elements = Array.from(document.querySelectorAll('.isMainPart, .isSubPart'));
let mainWithoutSubAfter = [];
let mainWithSubAfter = [];
let subWithoutMainBefore = [];
let lastMain = null;
for (let i = 0; i < elements.length; i++) {
let current = elements[i];
let next = elements[i + 1];
if (current.classList.contains('isMainPart')) {
lastMain = current;
if (next && next.classList.contains('isSubPart')) {
mainWithSubAfter.push({ index: i, main: current.innerText, sub: next.innerText, el: elements[i] });
} else {
mainWithoutSubAfter.push({ index: i, main: current.innerText, sub: "", el: elements[i] });
}
}
if (current.classList.contains('isSubPart')) {
let prevMain = lastMain && lastMain.classList.contains('isMainPart') ? lastMain.innerText : "";
subWithoutMainBefore.push({ index: i, main: prevMain, sub: current.innerText, el: elements[i] });
}
}
let titresFrise = [...mainWithoutSubAfter, ...mainWithSubAfter, ...subWithoutMainBefore];
titresFrise.sort((a, b) => a.index - b.index);
for (let i = titresFrise.length - 1; i > 0; i--) {
let current = titresFrise[i];
let next = titresFrise[i - 1];
if (current.main === next.main && current.sub === next.sub) {
titresFrise.splice(i, 1);
}
}
titreFriseEl.setAttribute('id', 'titres_frise');
titreFriseEl.innerHTML = `
<p class="uppercase">${getCurrentTime(titresFrise[0].el)}</p>
<p>${titresFrise[0].main}</p>
<p class="font-authentic-60">${titresFrise[0].sub}</p>
`;
titreFriseEl.style.fontSize = '0.9em';
titreFriseEl.style.zIndex = '0';
titreFriseEl.style.position = 'fixed';
titreFriseEl.style.left = '60px';
titreFriseEl.style.width = '10vw';
titreFriseEl.style.lineHeight = '1.2';
titreFriseEl.style.marginTop = '-8px';
titreFriseEl.style.top = `${document.querySelector('#timeline_container').getBoundingClientRect().top}px`;
let main = document.querySelector('#main');
main.prepend(titreFriseEl);
// création et togle des titres au survol des div de la timeline
function drawFixedTitles() {
let tlContainer = document.querySelector('#timeline_container');
let fixedTitlesContainer = document.createElement('div');
fixedTitlesContainer.setAttribute('id', 'fixedTitlesContainer');
main.prepend(fixedTitlesContainer);
for (let index = 0; index < titresFrise.length; index++) {
let titreFixedEl = document.createElement('div');
titreFixedEl.style.position = 'fixed';
titreFixedEl.style.zIndex = 1;
titreFixedEl.style.display = 'none';
titreFixedEl.style.opacity = '0';
titreFixedEl.style.transition = 'opacity 0.3s ease-out';
titreFixedEl.style.width = '10vw';
titreFixedEl.style.top = `${tlContainer.children[index].getBoundingClientRect().top - 8}px`;
titreFixedEl.style.left = '60px';
titreFixedEl.style.fontSize = '0.9em';
titreFixedEl.style.lineHeight = '1.2';
let titreFixedElContent = document.createElement('p');
titreFixedElContent.innerHTML = `
<p>${titresFrise[titresFrise.length - index - 1].main}</p>
<p class="font-authentic-60">${titresFrise[titresFrise.length - index - 1].sub}</p>
`;
titreFixedElContent.style.backgroundColor = '#010d19';
titreFixedEl.append(titreFixedElContent);
let topGradient = document.createElement('div');
topGradient.style.height = '10px';
topGradient.style.width = '100%';
topGradient.style.background = 'linear-gradient(to bottom, transparent, #010d19)';
titreFixedEl.prepend(topGradient);
let bottomGradient = document.createElement('div');
bottomGradient.style.height = '10px';
bottomGradient.style.width = '100%';
bottomGradient.style.background = 'linear-gradient(to top, transparent, #010d19)';
titreFixedEl.append(bottomGradient);
fixedTitlesContainer.prepend(titreFixedEl);
}
}
drawFixedTitles();
function toggleTitleHover(elIndex, state) {
let fixedTitlesContainer = document.querySelector('#fixedTitlesContainer');
let el = fixedTitlesContainer.children[elIndex];
if (state === 'show') {
el.style.display = 'block';
setTimeout(() => {
el.style.opacity = '1';
}, 1);
} else if (state === 'hide') {
el.style.opacity = '0';
setTimeout(() => {
el.style.display = 'none';
}, 300);
}
}
// make the cursor move on scroll
let cursor = document.querySelector('#cursor');
cursor.style.top = `${document.querySelector('#timeline_container').getBoundingClientRect().top}px`;
cursor.style.cursor = 'grab';
let titres = document.querySelector('#titres_frise');
titres.style.cursor = 'grab';
let partRects = document.querySelectorAll('#timeline_container div');
partRects = Array.from(partRects);
partRects = partRects.reverse();
partRects[0].style.width = '32px';
let grabbing = false;
document.addEventListener("scroll", (event) => {
if (!grabbing) {
displayCurrentPartTitle(getCurrentPartFromScroll());
moveCursorFromScroll(getCurrentPartFromScroll());
}
});
function makeElementDraggable(element, relatedEl) {
let offsetY;
element.addEventListener('mousedown', (e) => {
e.preventDefault();
grabbing = true;
offsetY = e.clientY - +element.style.top.slice(0, -2);
element.style.cursor = 'grabbing';
});
document.addEventListener('mousemove', (e) => {
if (grabbing) {
if (e.clientY < tlContainerHeight + tlContainer.offsetTop && e.clientY > tlContainer.offsetTop) {
const y = e.clientY - offsetY;
element.style.top = `${y}px`;
relatedEl.style.top = `${y}px`;
if (!isNaN(y)) displayCurrentPartTitle(getCurrentPartFromCursor(y));
} else if (e.clientY <= tlContainer.offsetTop) {
element.style.top = `${tlContainer.offsetTop}px`;
relatedEl.style.top = `${tlContainer.offsetTop}px`;
} else if (e.clientY >= tlContainerHeight + tlContainer.offsetTop) {
element.style.top = `${tlContainerHeight + tlContainer.offsetTop}px`;
relatedEl.style.top = `${tlContainerHeight + tlContainer.offsetTop}px`;
}
}
});
document.addEventListener('mouseup', () => {
grabbing = false;
element.style.cursor = 'grab';
});
}
makeElementDraggable(cursor, titres);
makeElementDraggable(titres, cursor);
/* let cursorPrevTranslateAmount = +cursor.style.transform.slice(0, -3).slice(11);
// make the cursor draggable
let prevMousePos = 0;
cursor.addEventListener("mousedown", (event) => {
if (!grabbing) {
event.preventDefault();
grabbing = true;
prevMousePos = event.clientY;
}
});
window.addEventListener("mousemove", (event) => {
if (grabbing) {
event.preventDefault();
let newPos = cursorPrevTranslateAmount + (event.clientY - prevMousePos);
if (event.clientY < tlContainerHeight + tlContainer.offsetTop && event.clientY > tlContainer.offsetTop) {
cursor.style.transform = `translateY(${newPos}px)`;
window.scrollBy(0, (event.clientY - prevMousePos) * (bodyHeight / tlContainerHeight));
cursorPrevTranslateAmount = +cursor.style.transform.slice(0, -3).slice(11);
} else if (event.clientY <= tlContainer.offsetTop) {
cursor.style.transform = "translateY(0px)";
window.scroll(0, 0);
cursorPrevTranslateAmount = 0;
} else if (event.clientY >= tlContainerHeight + tlContainer.offsetTop) {
cursor.style.transform = `translateY(${tlContainerHeight}px)`;
window.scroll(0, bodyHeight);
cursorPrevTranslateAmount = +cursor.style.transform.slice(0, -3).slice(11);
}
prevMousePos = event.clientY;
}
});
window.addEventListener("mouseup", (event) => {
if (grabbing) {
grabbing = false;
}
});
*/
// get heights of parts dans le tableau et dans la timeline
function getSteps() {
let tlElSteps = [];
for (let i = 0; i < partRects.length; i++) {
tlElSteps.push(partRects[i].offsetTop);
}
let titles = document.querySelectorAll('.isMainPart, .isSubPart');
let scrollSteps = [];
for (let title of titles) {
let nextLine = title.nextElementSibling;
if (!nextLine?.classList.contains('isSubPart')) {
scrollSteps.push(title.offsetTop);
}
}
return({
'tlElSteps':tlElSteps,
'scrollSteps':scrollSteps
});
}
function moveCursorFromScroll(currentPartIndex) {
let currentScroll = window.scrollY;
let cursorTopValue = 0;
let tlPartHeight, tlPartBottom;
for (let j = 0; j < partRects.length; j++) {
tlPartHeight = partRects[j].getBoundingClientRect().height
tlPartBottom = partRects[j].getBoundingClientRect().top - tlContainer.getBoundingClientRect().top;
cursorTopValue = tlPartBottom;
// get the amount of the current scrollpart scrolled
if (j === currentPartIndex) break;
}
let currentScrollPartBottom = getSteps().scrollSteps[currentPartIndex - 1] ? getSteps().scrollSteps[currentPartIndex - 1] : 0;
let currentScrollPartHeight;
if (getSteps().scrollSteps[currentPartIndex + 1]) {
currentScrollPartHeight = getSteps().scrollSteps[currentPartIndex + 1] - currentScrollPartBottom;
} else {
currentScrollPartHeight = document.querySelector('body').scrollHeight - currentScrollPartBottom;
}
let currentScrollSincePartBottom = currentScroll - currentScrollPartBottom;
let scrollPartProportion = currentScrollSincePartBottom / currentScrollPartHeight;
cursorTopValue = cursorTopValue + tlPartHeight * (tlPartHeight / tlPartHeight * (scrollPartProportion - 0.3));
if (cursorTopValue > 0) {
cursor.style.transform = `translateY(${cursorTopValue}px)`;
titres.style.transform = `translateY(${cursorTopValue}px)`;
} else {
cursor.style.transform = `translateY(0px)`;
titres.style.transform = `translateY(0px)`;
}
}
let prevPartIndex = 0;
function displayCurrentPartTitle(currentPartIndex) {
titres.firstElementChild.innerText = getCurrentTime(titresFrise[currentPartIndex]?.el);
let mainEl = titres.children[1];
let subEl = titres.lastElementChild;
if (mainEl.innerText != titresFrise[currentPartIndex]?.main || subEl.innerText != titresFrise[currentPartIndex]?.sub) {
mainEl.innerText = titresFrise[currentPartIndex]?.main;
subEl.innerText = titresFrise[currentPartIndex]?.sub;
partRects[prevPartIndex].style.width = '22px';
partRects[currentPartIndex].style.width = '32px';
}
activePartIndex = currentPartIndex;
prevPartIndex = currentPartIndex;
}
function getCurrentPartFromScroll() {
let currentScroll = window.scrollY;
for (let i = 0; i < getSteps().scrollSteps.length; i++) {
if (
(currentScroll + window.innerHeight / 2 >= getSteps().scrollSteps[i]
&& currentScroll + window.innerHeight / 2 <= getSteps().scrollSteps[i + 1]) ||
(currentScroll + window.innerHeight / 2 >= getSteps().scrollSteps[i]
&& i === getSteps().scrollSteps.length - 1)
) {
return(i);
}
}
}
function getCurrentPartFromCursor(cursorTop) {
for (let i = 0; i < getSteps().tlElSteps.length; i++) {
if (cursorTop - tlContainer.offsetTop >= getSteps().tlElSteps[i] && cursorTop - tlContainer.offsetTop < getSteps().tlElSteps[i + 1]) {
return(i);
} else if (cursorTop - tlContainer.offsetTop > getSteps().tlElSteps[getSteps().tlElSteps.length - 1]) {
return(getSteps().tlElSteps.length - 1);
}
}
}
function getCurrentTime(titleEl) {
let nextRow = titleEl?.nextElementSibling;
while(nextRow) {
if (nextRow.offsetTop > window.scrollY &&
nextRow.classList.contains('isContentPart')) {
return(nextRow.firstElementChild.innerText);
}
nextRow = nextRow.nextElementSibling;
}
}
});
/**
* @see {@link https://webpack.js.org/api/hot-module-replacement/}
*/
if (import.meta.webpackHot) import.meta.webpackHot.accept(console.error);