// source : https://stackoverflow.com/questions/68732160/make-a-div-bigger-and-wider-while-scrolling function getSize(curbID, yValue) { var offset = 2 / 5; // difference between each curve var stableLen = 0.1; var mainFunc = (-Math.abs(yValue - curbID * offset) + 1 + stableLen) / 2 + Math.abs((-Math.abs(yValue - curbID * offset) + 1 + stableLen) / 2); /* basically do that : /\ _____/ \______ */ var secoFunc = (-Math.abs(yValue - curbID * offset) + stableLen) / 2 + Math.abs((-Math.abs(yValue - curbID * offset) + stableLen) / 2); /* basically do that : ______/\______ so the difference do __ ______/ \______ */ return mainFunc - secoFunc; } function setupPage() { var elements = document.getElementsByClassName("container"); for (var i = 0; i < elements.length; i++) { elements[i].id = "card" + i; } } function changeWidth() { // Variables var speedFactor = 1 / 10; var nb_div = document.getElementsByClassName("container").length; var offset = 3.5 / speedFactor; // this is the number of false data-points added at the end. it doesn't work well when modifying speed_factor // Elements var timeLineElm = document.getElementById("timeline"); var startTimeElm = document.getElementById("startTime"); var spacer1 = document.getElementById("spacer1"); var projetPerso = document.getElementById("projetPerso"); // Positions var startTimeBoxSize = startTimeElm.getBoundingClientRect(); var ymin = startTimeBoxSize.top + window.scrollY; var ymax = document.getElementById("card".concat(nb_div - 1)).getBoundingClientRect().bottom + window.scrollY; // get each maximum card size var cardSizes = []; // fill the cardSizes array with original height of each card function calculateCardSizes() { timeLineElm.style.height = "".concat(0.8 * window.screen.height, "px"); console.log("taille de la fenetre: " + window.screen.height); console.log("taille de la barre" + timeLineElm.style.height); cardSizes = []; for (var i = 0; i < nb_div; i++) { var cardElem = document.getElementById("card" + i); cardElem.style.transform = 'scale(1)'; cardElem.style.display = ""; cardElem.style.height = ""; var cardSize = cardElem.getBoundingClientRect().bottom - cardElem.getBoundingClientRect().top; cardSizes.push(cardSize); } } calculateCardSizes(); function scaleAllCards(scrollVal) { console.log(timeLineElm.style.height); var shownCardsSizes = []; for (var i = 0; i < nb_div; i++) { var s = getSize(i, scrollVal * speedFactor); if (s > 0.01) shownCardsSizes.push([cardSizes[i], s]); } var c = timeLineElm.style.height.replace("px", ""); // @ts-ignore var scaleOffset = (c - shownCardsSizes.reduce(function (x, y) { return x + y[0] * y[1]; }, 0)) / shownCardsSizes.map(function (x) { return x[0]; }).reduce(function (x, y) { return x + y; }); //x = c - sum(ai*si)/sum(ai) for (var i = 0; i < nb_div; i++) { var cardElem = document.getElementById("card" + i); var s = getSize(i, scrollVal * speedFactor); cardElem.style.display = s < 0.01 ? "none" : ""; cardElem.style.transform = "scale(".concat(s, ")"); cardElem.style.transform = "scale(".concat(s, ")"); cardElem.style.height = "".concat(cardSizes[i] * (s + Math.max(scaleOffset, 0)), "px"); if (window.matchMedia("(max-width: 1000px)").matches) cardElem.style.left = "".concat(15 * (2 - s), "px"); // 15px + the size missing to the circle } } scaleAllCards((timeLineElm.getBoundingClientRect().y - ymin) / (ymax - ymin) * nb_div); // action to take whenever we go above the timeline or under function all() { startTimeElm.style.position = "relative"; timeLineElm.style.position = "relative"; startTimeElm.style.top = ""; timeLineElm.style.top = ""; projetPerso.style.top = ""; projetPerso.style.position = "relative"; } // action to take whenever we go above the timeline function backToTop() { spacer1.style.height = "0px"; if (window.matchMedia("(max-width: 1000px)").matches) timeLineElm.style.left = "23px"; // TODO this 23 shouldn't be hardcoded } // action to take whenever we go under the timeline function under() { if (spacer1.style.height.replace("px", "") < "100") { spacer1.style.height = -spacer1.getBoundingClientRect().bottom + "px"; } } // main function, called each time we scroll function changeWidthParam() { var scrollVal = (window.scrollY - ymin) / (ymax - ymin) * nb_div; if (window.scrollY > ymin && scrollVal < nb_div + offset) { if (timeLineElm.style.position !== "fixed") { // apply once startTimeElm.style.position = "fixed"; startTimeElm.style.right = "0%"; startTimeElm.style.left = "0%"; startTimeElm.style.top = 0 + "px"; timeLineElm.style.position = "fixed"; timeLineElm.style.left = "0%"; if (window.matchMedia("(max-width: 1000px)").matches) { timeLineElm.style.left = "31px"; console.log("Mobile Version"); } timeLineElm.style.top = startTimeElm.getBoundingClientRect().bottom + 20 + "px"; projetPerso.style.position = "fixed"; projetPerso.style.top = timeLineElm.getBoundingClientRect().bottom + 'px'; projetPerso.style.right = "0%"; projetPerso.style.left = "0%"; } scaleAllCards(scrollVal); } else { all(); if (scrollVal < 2) { backToTop(); } else { under(); } } } function updateSize() { calculateCardSizes(); changeWidthParam(); } return { "main": changeWidthParam, "updateSize": updateSize }; } window.addEventListener("load", function () { setupPage(); var f = changeWidth(); window.addEventListener('scroll', function () { requestAnimationFrame(f.main); }, false); addEventListener("resize", function (event) { return f.updateSize(); }); }); // source: https://stackoverflow.com/a/26837814 window.onbeforeunload = function () { window.scrollTo(0, 0); };