Przeglądaj źródła

taff sur le grab du curseur de la tl

Valentin 1 rok temu
rodzic
commit
7fe64ecbf2
1 zmienionych plików z 203 dodań i 136 usunięć
  1. 203 136
      resources/scripts/app.js

+ 203 - 136
resources/scripts/app.js

@@ -43,7 +43,7 @@ domReady(async () => {
     }
   }
   // italiques -> A FAIRE SUR LE CSV AVANT D'IMPORTER CA RALENTIT DE OUF LE CHARGEMENT
-/*         let tbody = document.querySelector('body main table tbody');
+  /*       let tbody = document.querySelector('body main table tbody');
   let tbodyContent = tbody.innerHTML;
   let asteriskCounter = 0;
   for (let i = 0; i < tbodyContent.length; i++) {
@@ -128,17 +128,18 @@ domReady(async () => {
   }
   let totalTime = convertToSeconds(lastTime[0].innerText);
 
-  let tlContainer, tlContainerHeight;
-  var bodyHeight = document.querySelector('body').offsetHeight;
+  let tlContainer, tlContainerHeight, bodyHeight;
   let partBlockHeights = [];
   let activePartIndex = 0;
-
+  
   function getAllHeights() {
     partBlockHeights = [];
     tlContainer = document.querySelector('#timeline_container');
-    tlContainer.style.height = `calc(100vh - ${document.querySelector('header').offsetHeight}px - ${document.querySelector('footer').offsetHeight}px - 60px)`;
+    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);
     }
@@ -178,7 +179,6 @@ domReady(async () => {
   drawFriseRects();
 
   window.addEventListener('resize', () => {
-    bodyHeight = document.querySelector('body').offsetHeight;
     while(tlContainer.lastChild) {
       tlContainer.removeChild(tlContainer.lastChild);
     }
@@ -230,92 +230,29 @@ domReady(async () => {
   }
 
   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.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.top = `${document.querySelector('#timeline_container').getBoundingClientRect().top - 8}px`;
+  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);
 
-  // make the cursor move on scroll
-  let cursor = document.querySelector('#cursor');
-  let isCursorGrabbed = false;
-  cursor.style.top = `${document.querySelector('#timeline_container').getBoundingClientRect().top}px`;
-  let cursorPrevTranslateAmount = +cursor.style.transform.slice(0, -3).slice(11);
-  document.addEventListener("scroll", (event) => {
-    if (!isCursorGrabbed) {
-      scrollMovement();
-    }
-  });
-  // make the cursor draggable
-  let prevMousePos = 0;
-  cursor.addEventListener("mousedown", (event) => {
-    if (!isCursorGrabbed) {
-      event.preventDefault();
-      isCursorGrabbed = true;
-      prevMousePos = event.clientY;
-    }
-  });
-  window.addEventListener("mousemove", (event) => {
-    if (isCursorGrabbed) {
-      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 (isCursorGrabbed) {
-      isCursorGrabbed = false;
-    }
-  });
-
-  function getSteps() {
-    let partRects = document.querySelectorAll('#timeline_container div');
-    let tlElSteps = [];
-    let total = 0;
-    for (let i = 0; i < partRects.length; i++) {
-      total = total + partRects[i].clientHeight;
-      if (i === 0) total = total - partRects[0].clientHeight;
-      tlElSteps.push(total);
-    }
-    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
-    });
-  }
-
+  // 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);
-    let index = 0;
-    for (let titreFrise of titresFrise) {
+    for (let index = 0; index < titresFrise.length; index++) {
       let titreFixedEl = document.createElement('div');
       titreFixedEl.style.position = 'fixed';
       titreFixedEl.style.zIndex = 1;
@@ -328,7 +265,10 @@ domReady(async () => {
       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.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');
@@ -342,7 +282,6 @@ domReady(async () => {
       bottomGradient.style.background = 'linear-gradient(to top, transparent, #010d19)';
       titreFixedEl.append(bottomGradient);
       fixedTitlesContainer.prepend(titreFixedEl);
-      index++;
     }
   }
   drawFixedTitles();
@@ -363,75 +302,203 @@ domReady(async () => {
     }
   }
 
-  function cursorMovement() {
-  }
-  
+  // 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');
-  let prevPartIndex = 0;
+  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);
+
+
 
-  function scrollMovement() {
+
+
+
+/*   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));
     
-    for (let i = 0; i < getSteps().scrollSteps.length; i++) {
-      if ((currentScroll >= getSteps().scrollSteps[i] && currentScroll <= getSteps().scrollSteps[i + 1]) ||
-          (currentScroll >= getSteps().scrollSteps[i] && i === getSteps().scrollSteps.length - 1)) {
-        // titres et temps
-        titres.firstElementChild.innerText = getCurrentTime(titresFrise[i].el);
-        let mainEl = titres.children[1];
-        let subEl = titres.lastElementChild;
-        if (mainEl.innerText != titresFrise[i].main || subEl.innerText != titresFrise[i].sub) {
-          mainEl.innerText = titresFrise[i].main;
-          subEl.innerText = titresFrise[i].sub;
-          partRects[prevPartIndex].style.width = '22px';
-          partRects[i].style.width = '32px';
-        }
-        activePartIndex = i;
-        prevPartIndex = i;
-        
-        // curseur
-        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 === i) break;
-        }
+    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 currentScrollPartBottom = getSteps().scrollSteps[i - 1] ? getSteps().scrollSteps[i - 1] : 0;
-        let currentScrollPartHeight;
-        if (getSteps().scrollSteps[i + 1]) {
-          currentScrollPartHeight = getSteps().scrollSteps[i + 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)`;
-        }
-        
-        break;
+  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;
+    let nextRow = titleEl?.nextElementSibling;
     while(nextRow) {
       if (nextRow.offsetTop > window.scrollY &&
           nextRow.classList.contains('isContentPart')) {