diff --git a/functions.php b/functions.php index 6bf49c9..a32b330 100644 --- a/functions.php +++ b/functions.php @@ -331,6 +331,12 @@ collect(['setup', 'filters']) add_action('admin_enqueue_scripts', 'log_posts_with_user_revisions'); + function custom_logout_redirect() { + wp_redirect( home_url() ); + exit(); + } + add_action('wp_logout','custom_logout_redirect'); + // function supprimer_tous_les_articles() { // $args = array( diff --git a/resources/scripts/app.js b/resources/scripts/app.js index bf38292..d329a64 100644 --- a/resources/scripts/app.js +++ b/resources/scripts/app.js @@ -17,6 +17,11 @@ domReady(async () => { window.addEventListener('resize', function() { setTimeout(function() { window.scrollTo(0, 0); + let editButtons = document.querySelectorAll(".edit-button"); + for (let editButton of editButtons) { + let editContainer = editButton.parentElement; + editContainer.style.height = `${editContainer.previousElementSibling.offsetHeight}px`; + } }, 0); }); diff --git a/resources/scripts/front/timeline.js b/resources/scripts/front/timeline.js index 202e4a9..e12ac74 100644 --- a/resources/scripts/front/timeline.js +++ b/resources/scripts/front/timeline.js @@ -1,18 +1,42 @@ function customTimeline() { - // 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"; + let colors, titles, partTitles; + let partDurations = []; + let totalTime; + let tlContainer, tlContainerHeight; + let partBlockHeights = []; + let activePartIndex = 0; + let steps = { + tlElSteps: [], + scrollSteps: [] + } + let previousScroll; + let grabbing = false; + let titresFrise; + let cursor = document.querySelector('#cursor'); + let titresCursor; + let partRects; + let isScrollingFromGrab = false; + let prevPartIndex = 0; + let lastCallTimestamp = 0; + let timestampDebounce = 200; + + // titres de parties dans le tableau + function setPartTitlesInPartition() { + let mainpartTitles = document.querySelectorAll('.isMainPart'); + for (let mainpartTitle of mainpartTitles) { + if (mainpartTitle.nextElementSibling.classList.contains('isSubPart')) { + mainpartTitle.firstElementChild.firstElementChild.style.height = "1.5rem"; + mainpartTitle.firstElementChild.style.marginBottom = "-0.25rem"; + mainpartTitle.style.borderBottom = "0"; + mainpartTitle.style.paddingBottom = "0"; + mainpartTitle.nextElementSibling.style.paddingTop = "0"; } } - - // couleurs titres - let colors = [ + } + + // couleurs titres + function setPartsColors() { + colors = [ {'red' : 'cf0118'}, {'blue1': '0101c4'}, {'blue2': '01049e'}, @@ -27,8 +51,8 @@ function customTimeline() { {'pink1': 'cf0118'}, {'pink2': 'a10418'} ]; - let titles = document.querySelectorAll('.isMainPart, .isSubPart'); - let partTitles = []; + titles = document.querySelectorAll('.isMainPart, .isSubPart'); + partTitles = []; for (let title of titles) { if (!title.nextElementSibling.classList.contains('isSubPart')) { partTitles.push(title); @@ -40,21 +64,23 @@ function customTimeline() { } 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); - } - + } + + // 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); + } + + function getPartsTimes() { 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++) { @@ -62,98 +88,73 @@ function customTimeline() { } 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; - 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; - for (let partDuration of partDurations) { - partBlockHeights.push(partDuration / totalTime * tlContainerHeight); - } + totalTime = convertToSeconds(lastTime[0].innerText); + } + + function getAllHeights() { + partBlockHeights = []; + tlContainer = document.querySelector('#timeline_container'); + let header = document.querySelector('header'); + let footer = document.querySelector('footer'); + tlContainer.style.height = `calc(100vh - ${header.offsetHeight}px - ${footer.offsetHeight}px - 60px)`; + tlContainer.style.top = `${header.offsetHeight + 30}px`; + tlContainerHeight = tlContainer.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() { - isScrollingFromGrab = false; - titresFrise[i].el.scrollIntoView({ behavior: 'smooth', block: 'center' }); - }); - } + } + + function drawFriseRects() { + for (let i = 0; i < partBlockHeights.length; i++) { + let partDiv = document.createElement('div'); + partDiv.classList.add('tlRectPart'); + partDiv.style.height = partBlockHeights[i] + "px"; + partDiv.style.backgroundColor = "#" + Object.values(colors[i])[0]; + 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() { + isScrollingFromGrab = false; + titresFrise[i].el.scrollIntoView({ behavior: 'smooth', block: 'center' }); + }); } - drawFriseRects(); - - window.addEventListener('resize', () => { - while(tlContainer.lastChild) { - tlContainer.removeChild(tlContainer.lastChild); - } - getAllHeights(); - drawFriseRects(); - setPartRects(); - }); - - // detect if is scrolling - - let previousScroll; - - function isWindowScrolling() { - let currentScroll = window.scrollY; - if (currentScroll !== previousScroll) { - previousScroll = currentScroll; - return true; - } else { - return false; - } + } + + // detect if is scrolling + function isWindowScrolling() { + let currentScroll = window.scrollY; + if (currentScroll !== previousScroll) { + previousScroll = currentScroll; + return true; + } else { + return false; } - - // titres parties frise - let titreFriseEl = document.createElement('div'); - - let elements = Array.from(document.querySelectorAll('.isMainPart, .isSubPart')); + } + // titres parties frise + function displayTimelineTitles() { let mainWithoutSubAfter = []; let mainWithSubAfter = []; let subWithoutMainBefore = []; - + + let elements = Array.from(document.querySelectorAll('.isMainPart, .isSubPart')); let lastMain = null; - - let grabbing = false; - + for (let i = 0; i < elements.length; i++) { let current = elements[i]; let next = elements[i + 1]; @@ -173,7 +174,7 @@ function customTimeline() { } } - let titresFrise = [...mainWithoutSubAfter, ...mainWithSubAfter, ...subWithoutMainBefore]; + titresFrise = [...mainWithoutSubAfter, ...mainWithSubAfter, ...subWithoutMainBefore]; titresFrise.sort((a, b) => a.index - b.index); @@ -185,6 +186,9 @@ function customTimeline() { titresFrise.splice(i, 1); } } + + + let titreFriseEl = document.createElement('div'); titreFriseEl.setAttribute('id', 'titres_frise'); titreFriseEl.innerHTML = ` @@ -192,346 +196,331 @@ function customTimeline() {

${titresFrise[0].main}

${titresFrise[0].sub}

`; - titreFriseEl.style.fontSize = '0.9em'; - titreFriseEl.style.backgroundColor = 'rgba(1, 13, 25, 0.6)'; - titreFriseEl.style.zIndex = '20'; - 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 = ` -

${titresFrise[titresFrise.length - index - 1].main}

-

${titresFrise[titresFrise.length - index - 1].sub}

- `; - 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); - } + + titresCursor = document.querySelector('#titres_frise'); + + setTimeout(() => { + titreFriseEl.firstElementChild.innerText = getCurrentTime(titresFrise[0].el); + }, 10); + + } + + // 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.classList.add('tlFixedTitle'); + titreFixedEl.style.top = `${tlContainer.children[index].getBoundingClientRect().top - 8}px`; + let titreFixedElContent = document.createElement('p'); + titreFixedElContent.innerHTML = ` +

${titresFrise[titresFrise.length - index - 1].main}

+

${titresFrise[titresFrise.length - index - 1].sub}

+ `; + titreFixedEl.append(titreFixedElContent); + 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); - } + } + + 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); } - - - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - // ICI IL Y A LE GRAB DU CURSEUR DE LA TL - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - // make the cursor move on scroll - let cursor = document.querySelector('#cursor'); + } + + // make the cursor move on scroll + function setupCursor() { 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; - function setPartRects() { - partRects = document.querySelectorAll('#timeline_container div'); - partRects = Array.from(partRects); - partRects = partRects.reverse(); - partRects[0].style.width = '32px'; - } - setPartRects(); - document.addEventListener("scroll", () => { - if (!grabbing) { - displayCurrentPartTitle(getCurrentPartFromScroll()); - if (document.documentElement.scrollTop === 0) { - let firstTimeText = document.querySelector('tbody tr:nth-of-type(2) td:first-of-type'); - titres.firstElementChild.innerText = firstTimeText.innerText; - } else if (document.documentElement.scrollTop + window.innerHeight >= document.body.scrollHeight) { - let lastTimeText = document.querySelector('tbody tr:last-of-type td:first-of-type'); - titres.firstElementChild.innerText = lastTimeText.innerText; - } - moveCursorFromScroll(getCurrentPartFromScroll()); + titresCursor.style.cursor = 'grab'; + } + + function setPartRects() { + partRects = document.querySelectorAll('#timeline_container div'); + partRects = Array.from(partRects); + partRects = partRects.reverse(); + partRects[0].style.width = '32px'; + } + + document.addEventListener("scroll", () => { + if (!grabbing) { + displayCurrentPartTitle(getCurrentPartFromScroll()); + if (document.documentElement.scrollTop === 0) { + let firstTimeText = document.querySelector('tbody tr:nth-of-type(2) td:first-of-type'); + titresCursor.firstElementChild.innerText = firstTimeText.innerText; + } else if (document.documentElement.scrollTop + window.innerHeight >= document.body.scrollHeight) { + let lastTimeText = document.querySelector('tbody tr:last-of-type td:first-of-type'); + titresCursor.firstElementChild.innerText = lastTimeText.innerText; } + moveCursorFromScroll(getCurrentPartFromScroll()); + } + }); + + function makeElementDraggable(element, relatedEl) { + let offsetY; + + element.addEventListener('mousedown', (e) => { + let elTransformY = element.style.transform ? +element.style.transform.split('(')[1].split('p')[0] : 0; + e.preventDefault(); + grabbing = true; + offsetY = e.clientY - elTransformY; + element.style.cursor = 'grabbing'; }); - function makeElementDraggable(element, relatedEl) { - let offsetY; - - element.addEventListener('mousedown', (e) => { - let elTransformY; - if (!element.style.transform) { - elTransformY = 0; - } else { - elTransformY = +element.style.transform.split('(')[1].split('p')[0]; - } - e.preventDefault(); - grabbing = true; - offsetY = e.clientY - elTransformY; - 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.transform = `translateY(${y}px)`; - relatedEl.style.transform = `translateY(${y}px)`; - if (!isNaN(y)) displayCurrentPartTitle(getCurrentPartFromCursor(y)); - } else if (e.clientY < tlContainer.offsetTop + 10) { - element.style.transform = `translateY(0px)`; - relatedEl.style.transform = `translateY(0px)`; + document.addEventListener('mousemove', (e) => { + if (grabbing) { + const y = e.clientY - offsetY; + if (e.clientY < tlContainerHeight + tlContainer.offsetTop && e.clientY > tlContainer.offsetTop && y > 0) { + element.style.transform = `translateY(${y}px)`; + relatedEl.style.transform = `translateY(${y}px)`; + if (!isNaN(y)) displayCurrentPartTitle(getCurrentPartFromCursor(y)); + } else if (e.clientY < tlContainer.offsetTop || y <= 0) { + element.style.transform = `translateY(0px)`; + relatedEl.style.transform = `translateY(0px)`; + setTimeout(() => { let firstTimeText = document.querySelector('tbody tr:nth-of-type(2) td:first-of-type'); - titres.firstElementChild.innerText = firstTimeText.innerText; - } else if (e.clientY >= tlContainerHeight + tlContainer.offsetTop) { - element.style.transform = `translateY(${tlContainerHeight}px)`; - relatedEl.style.transform = `translateY(${tlContainerHeight}px)`; - let lastTimeText = document.querySelector('tbody tr:last-of-type td:first-of-type'); - titres.firstElementChild.innerText = lastTimeText.innerText; - } - } - }); - - document.addEventListener('mouseup', () => { - if (grabbing) scrollOnGrab(element); - element.style.cursor = 'grab'; - grabbing = false; - }); - } - - makeElementDraggable(cursor, titres); - makeElementDraggable(titres, cursor); - - // 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); + titresCursor.firstElementChild.innerText = firstTimeText.innerText; + }, 100); + } else if (e.clientY >= tlContainerHeight + tlContainer.offsetTop) { + element.style.transform = `translateY(${tlContainerHeight}px)`; + relatedEl.style.transform = `translateY(${tlContainerHeight}px)`; + let lastTimeText = document.querySelector('tbody tr:last-of-type td:first-of-type'); + titresCursor.firstElementChild.innerText = lastTimeText.innerText; } } - return({ - 'tlElSteps':tlElSteps, - 'scrollSteps':scrollSteps - }); - } - - - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - // ICI IL Y A LE SCROLL DU GRAB - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - let isScrollingFromGrab = false; - - function scrollOnGrab(el) { - let scrollValue = - ((getSteps().scrollSteps[getCursorPositionInTimelinePart(el).stepAfterMouseUp] - getSteps().scrollSteps[getCursorPositionInTimelinePart(el).stepAfterMouseUp - 1]) * getCursorPositionInTimelinePart(el).proportionInPart) - + getSteps().scrollSteps[getCursorPositionInTimelinePart(el).stepAfterMouseUp]; - isScrollingFromGrab = true; - window.scrollTo({ top: scrollValue, behavior: 'smooth' }); - setTimeout(() => { - isScrollingFromGrab = false; - }, 2000); - } - - function getCursorPositionInTimelinePart(el) { - let elTransformY; - if (!el.style.transform) { - elTransformY = 0; - } else { - elTransformY = +el.style.transform.split('(')[1].split('p')[0]; - } - - let tlPartHeight, tlPartBottom, tlPartTop, proportionInPart, stepAfterMouseUp; - for (let j = 0; j < partRects.length; j++) { - if (j === getCurrentPartFromCursor(elTransformY)) { - tlPartHeight = partRects[j].getBoundingClientRect().height; - tlPartBottom = partRects[j].getBoundingClientRect().top - tlContainer.getBoundingClientRect().top; - tlPartTop = tlPartBottom - tlPartHeight; - proportionInPart = ((tlPartHeight - (elTransformY - tlPartTop)) / tlPartHeight) * -1; - if (proportionInPart > 0 && proportionInPart < 1) { - stepAfterMouseUp = j; - return {stepAfterMouseUp, proportionInPart}; - } else { - stepAfterMouseUp = j; - proportionInPart = 0; - return {stepAfterMouseUp, proportionInPart}; - } - } - } - } - - - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - // ICI IL Y A LE RAPPORT SCROLL / TIMELINE - // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - function moveCursorFromScroll(currentPartIndex) { - if (!isScrollingFromGrab) { - 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; + }); + + document.addEventListener('mouseup', (e) => { + if (grabbing) { + scrollOnGrab(element); + let elTransformY = element.style.transform ? +element.style.transform.split('(')[1].split('p')[0] : 0; + offsetY = e.clientY - elTransformY; + const y = e.clientY - offsetY; + if (e.clientY < tlContainer.offsetTop || y <= 0) { + window.scrollTo(0, 0); } 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)`; + setTimeout(() => { + titresCursor.firstElementChild.innerText = getCurrentTime(titresFrise[getCurrentPartFromCursor(y)]?.el); + }, 1000); } } + element.style.cursor = 'grab'; + grabbing = false; + }); + } + + // get heights of parts dans le tableau et dans la timeline + function getSteps() { + steps.tlElSteps = []; + steps.scrollSteps = []; + for (let i = 0; i < partRects.length; i++) { + // steps.tlElSteps.push(partRects[i].offsetTop); + steps.tlElSteps.push(partRects[i].getBoundingClientRect().top); } - - let prevPartIndex = 0; - let lastCallTimestamp = 0; - - function displayCurrentPartTitle(currentPartIndex) { - if (isNaN(currentPartIndex)) currentPartIndex = 0; - const currentTime = performance.now(); - if (currentTime - lastCallTimestamp >= 400) { - lastCallTimestamp = currentTime; - titres.firstElementChild.innerText = getCurrentTime(titresFrise[currentPartIndex]?.el); // ICI POUR METTRE LE TEMPS BIEN - setTimeout(() => { - if (isWindowScrolling()) { - setTimeout(() => { - titres.firstElementChild.innerText = getCurrentTime(titresFrise[currentPartIndex]?.el); - }, 400); - } - }, 200); + let titles = document.querySelectorAll('.isMainPart, .isSubPart'); + for (let title of titles) { + let nextLine = title.nextElementSibling; + if (!nextLine?.classList.contains('isSubPart')) { + // steps.scrollSteps.push(title.offsetTop); + steps.scrollSteps.push(title.offsetTop); } - 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() { + } + + function scrollOnGrab(el) { + let scrollValue; + if (getCursorPositionInTimelinePart(el).stepAfterMouseUp === steps.scrollSteps.length - 1) { + scrollValue = + ((document.documentElement.scrollHeight - steps.scrollSteps[getCursorPositionInTimelinePart(el).stepAfterMouseUp]) * getCursorPositionInTimelinePart(el).proportionInPart) + + steps.scrollSteps[getCursorPositionInTimelinePart(el).stepAfterMouseUp]; + } else { + scrollValue = + ((steps.scrollSteps[getCursorPositionInTimelinePart(el).stepAfterMouseUp + 1] - steps.scrollSteps[getCursorPositionInTimelinePart(el).stepAfterMouseUp]) * getCursorPositionInTimelinePart(el).proportionInPart) + + steps.scrollSteps[getCursorPositionInTimelinePart(el).stepAfterMouseUp]; + } + isScrollingFromGrab = true; + window.scrollTo({ top: scrollValue, behavior: 'smooth' }); + setTimeout(() => { + isScrollingFromGrab = false; + }, 1000); + } + + function getCursorPositionInTimelinePart(el) { + let elTransformY; + if (!el.style.transform) { + elTransformY = 0; + } else { + elTransformY = +el.style.transform.split('(')[1].split('p')[0]; + } + + let tlPartHeight, tlPartBottom, tlPartTop, proportionInPart, stepAfterMouseUp; + tlPartHeight = partRects[getCurrentPartFromCursor(elTransformY) || 0].getBoundingClientRect().height; + tlPartBottom = partRects[getCurrentPartFromCursor(elTransformY) || 0].getBoundingClientRect().bottom - tlContainer.getBoundingClientRect().top; + tlPartTop = steps.tlElSteps[getCurrentPartFromCursor(elTransformY) || 0] - steps.tlElSteps[0]; + proportionInPart = 1 - ((tlPartHeight - (elTransformY - tlPartTop)) / tlPartHeight); + + if (proportionInPart > 0 && proportionInPart < 1) { + stepAfterMouseUp = getCurrentPartFromCursor(elTransformY); + return {stepAfterMouseUp, proportionInPart}; + } else { + stepAfterMouseUp = getCurrentPartFromCursor(elTransformY); + proportionInPart = 0; + return {stepAfterMouseUp, proportionInPart}; + } + } + + function moveCursorFromScroll(currentPartIndex) { + if (!isScrollingFromGrab) { 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(cursorTransformY) { - for (let i = 0; i < getSteps().tlElSteps.length; i++) { - if (cursorTransformY >= getSteps().tlElSteps[i] && cursorTransformY < getSteps().tlElSteps[i + 1]) { - return(i); - } else if (cursorTransformY > getSteps().tlElSteps[getSteps().tlElSteps.length - 1]) { - return(getSteps().tlElSteps.length - 1); - } - } - } - - /////////////////////////////////////// - // ICI LE GETCURRENTTIME !!!!!!!!!!!!!! - /////////////////////////////////////// - - function getCurrentTime(titleEl) { - let nextRow = titleEl?.nextElementSibling; - if (!grabbing) { - while(nextRow) { - if (nextRow.offsetTop - window.innerHeight / 4 > window.scrollY && - nextRow.classList.contains('isContentPart')) { - return(nextRow.firstElementChild.innerText); - } - nextRow = nextRow.nextElementSibling; - } + let tlPartHeight = parseInt(partRects[currentPartIndex].style.height); + let cursorTopValue = partRects[currentPartIndex].getBoundingClientRect().top - parseInt(tlContainer.style.top); + + let currentScrollPartTop = steps.scrollSteps[currentPartIndex] || 0; + let currentScrollPartHeight; + if (steps.scrollSteps[currentPartIndex + 1]) { + currentScrollPartHeight = steps.scrollSteps[currentPartIndex + 1] - currentScrollPartTop; } else { - let cursor = document.querySelector('#cursor'); - let allRowsUnder = []; - nextRow = nextRow.nextElementSibling.nextElementSibling; - while(nextRow) { - if (nextRow.classList.contains('isMainPart') || nextRow.classList.contains('isSubPart')) { - break; - } - allRowsUnder.push(nextRow); - nextRow = nextRow.nextElementSibling; - } - let currentRowIndex = Math.floor(allRowsUnder.length * getCursorPositionInTimelinePart(cursor).proportionInPart); - if (currentRowIndex - 20 >= 0) { - return allRowsUnder[currentRowIndex - 20].firstElementChild.innerText; - } else { - return allRowsUnder[0].firstElementChild.innerText; - } + currentScrollPartHeight = document.querySelector('body').scrollHeight - currentScrollPartTop; + } + + let currentScrollSincePartBottom = currentScroll - currentScrollPartTop; + let scrollPartProportion = currentScrollSincePartBottom / currentScrollPartHeight; + + cursorTopValue = cursorTopValue + tlPartHeight * scrollPartProportion; + + if (cursorTopValue > 0) { + cursor.style.transform = `translateY(${cursorTopValue}px)`; + titresCursor.style.transform = `translateY(${cursorTopValue}px)`; + } else { + cursor.style.transform = `translateY(0px)`; + titresCursor.style.transform = `translateY(0px)`; } } + } + + function displayCurrentPartTitle(currentPartIndex) { + if (isNaN(currentPartIndex)) currentPartIndex = 0; + const currentTime = performance.now(); + if (currentTime - lastCallTimestamp >= timestampDebounce) { + lastCallTimestamp = currentTime; + if (titresCursor) titresCursor.firstElementChild.innerText = getCurrentTime(titresFrise[currentPartIndex]?.el); // ICI POUR METTRE LE TEMPS BIEN + } + let mainEl = titresCursor.children[1]; + let subEl = titresCursor.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 < steps.scrollSteps.length; i++) { + if ( + (currentScroll + window.innerHeight / 2 >= steps.scrollSteps[i] + && currentScroll + window.innerHeight / 2 <= steps.scrollSteps[i + 1]) || + (currentScroll + window.innerHeight / 2 >= steps.scrollSteps[i] + && i === steps.scrollSteps.length - 1) + ) { + return(i); + } + } + } + + function getCurrentPartFromCursor(cursorTransformY) { + for (let i = 0; i < steps.tlElSteps.length; i++) { + if (cursorTransformY >= steps.tlElSteps[i] - steps.tlElSteps[0] && cursorTransformY < steps.tlElSteps[i + 1] - steps.tlElSteps[0]) { + return(i); + } else if (cursorTransformY > steps.tlElSteps[steps.tlElSteps.length - 1] - steps.tlElSteps[0]) { + return(steps.tlElSteps.length - 1); + } + } + } + + function getCurrentTime(titleEl) { + let nextRow = titleEl?.nextElementSibling; + let allRowsUnder = []; + if (!grabbing) { + while(nextRow) { + if (nextRow.offsetTop - window.innerHeight / 4 > window.scrollY && + nextRow.classList.contains('isContentPart')) { + return nextRow.firstElementChild.innerText; + } + allRowsUnder.push(nextRow.firstElementChild.innerText); + nextRow = nextRow.nextElementSibling; + } + return allRowsUnder[allRowsUnder.length-1]; + } else { + let cursor = document.querySelector('#cursor'); + if (nextRow.classList.contains('isSubPart')) nextRow = nextRow.nextElementSibling.nextElementSibling; + while(nextRow) { + if (nextRow.classList.contains('isMainPart') || nextRow.classList.contains('isSubPart')) { + break; + } + allRowsUnder.push(nextRow.firstElementChild.innerText); + nextRow = nextRow.nextElementSibling; + } + let currentRowIndex = Math.floor(allRowsUnder.length * getCursorPositionInTimelinePart(cursor).proportionInPart); + return allRowsUnder[currentRowIndex]; + } + } + + + setPartTitlesInPartition(); + setPartsColors(); + getPartsTimes(); + + setTimeout(() => { + getAllHeights(); + drawFriseRects(); + displayTimelineTitles(); + setupCursor(); + drawFixedTitles(); + setPartRects(); + makeElementDraggable(cursor, titresCursor); + makeElementDraggable(titresCursor, cursor); + getSteps(); + }, 100); + + + + let resizeTimeout; + + window.addEventListener('resize', () => { + tlContainer.innerHTML = ''; + document.querySelector("#titres_frise")?.remove(); + clearTimeout(resizeTimeout); + resizeTimeout = setTimeout(() => { + getAllHeights(); + drawFriseRects(); + displayTimelineTitles(); + setupCursor(); + setPartRects(); + makeElementDraggable(titresCursor, cursor); + getSteps(); + }, 100); + }); + } export { customTimeline }; \ No newline at end of file diff --git a/resources/styles/app.css b/resources/styles/app.css index 3d3801f..a847b0a 100644 --- a/resources/styles/app.css +++ b/resources/styles/app.css @@ -62,6 +62,41 @@ z-index: 10; } + .tlRectPart { + width: 22px; + border-bottom: solid 1px #010d19; + border-top: solid 1px #010d19; + transition: width 0.3s ease-out; + cursor: pointer; + } + + .tlFixedTitle { + position: fixed; + z-index: 1; + display: none; + opacity: 0; + transition: opacity 0.3s ease-out; + width: 10vw; + left: 60px; + font-size: 0.9em; + line-height: 1.2; + } + + .tlFixedTitle p { + background-color: #010d19; + } + + #titres_frise { + font-size: 0.9em; + background-color: rgba(1, 13, 25, 0.6); + z-index: 20; + position: fixed; + left: 60px; + width: 10vw; + line-height: 1.2; + margin-top: -8px; + } + .isContentPart td:last-of-type { position: absolute; width: auto !important; @@ -238,5 +273,10 @@ .edit-button { transform: translateX(70px); } + + thead::after { + left: auto; + right: 0 !important; + } } } \ No newline at end of file diff --git a/resources/views/sections/header.blade.php b/resources/views/sections/header.blade.php index 16565fc..54be125 100644 --- a/resources/views/sections/header.blade.php +++ b/resources/views/sections/header.blade.php @@ -25,7 +25,7 @@ Partition
- Le Livre d'Image
+ Le Livre d'image
de Jean-Luc Godard