~scrumplex/website

1adfd55b0263931265551b30dca14f46bfc2fa35 — Sefa Eyeoglu 2 months ago 5f45b7c
refactor: hacky way to implement a better data-scroll
2 files changed, 39 insertions(+), 9 deletions(-)

M src/js/application.js
M src/scss/_base.scss
M src/js/application.js => src/js/application.js +31 -8
@@ 28,13 28,11 @@ window.addEventListener("beforeunload", () => {
});

document.querySelectorAll("*[data-scroll]").forEach((elem) => {
    elem.addEventListener("mousedown", applyScroll);

    elem.addEventListener("click", (e) => {
        e.preventDefault();
        const targetSelector = elem.getAttribute("data-scroll");
        let offset = window.pageYOffset + document.querySelector(targetSelector).getBoundingClientRect().top;

        const targetElem = document.querySelector(targetSelector);
        const offset = applyScroll(targetElem);
        window.scrollTo({top: offset, behavior: "smooth"});
    });
});


@@ 52,24 50,43 @@ function applyScrollConditionally() {
        applyScroll();
}

function applyScroll() {
function applyScroll(scrollTarget = null) {
    // Black magic ahead!
    // We sometimes need this method to show all sheets and then scroll to one of them.
    // To achieve this we need to have a way to get the target position (like pixels) of
    // the sheet we want to scroll to (in this case it's scrollTarget).
    // As the bounding box always includes current transforms (so our translateY in the
    // fade-in animation) we need to somehow get the boundingBox while our sheet is not
    // being transformed. A hacky way to do this is to modify the behavior of .sheet[hidden]
    // depending on the state of this method. In this case we are adding .scrolled to body
    // which will cause all hidden sheets to instead be transparent.
    // Additionally we will stop any animations that would be playing then.
    // Now the element should be at it's target position so we just grab the position before
    // un-hiding the elements and voila!
    // One caveat: if the content changes after this method returned, the scroll might be a
    // bit offset.

    let offset = getElementScrollOffset(scrollTarget);
    if (document.body.classList.contains("scrolled"))
        return false;
        return offset;

    const hiddenElems = document.querySelectorAll(".sheet[hidden]"),
        posMain = mainElem.getBoundingClientRect().top + window.pageYOffset; // offset to top rel. to document
        posMain = getElementScrollOffset(mainElem); // offset to top rel. to document

    document.getElementById("wrapper").style.paddingTop = `${posMain}px`;
    document.body.classList.add("scrolled");

    mainElem.classList.add("sheet-splashed");
    mainElem.classList.remove("sheet-splash");
    if (scrollTarget)  // recalculate, as it probably changed because of body.scrolled
        offset = getElementScrollOffset(scrollTarget);

    hiddenElems.forEach((elem) => {
        elem.removeAttribute("hidden");
    });

    window.removeEventListener("scroll", applyScrollConditionally);
    return true;
    return offset;
}

function startSpinningChars(fps = 4) {


@@ 88,6 105,12 @@ function startSpinningChars(fps = 4) {
    spinnerElement.removeAttribute("hidden");
}

function getElementScrollOffset(elem) {
    if (elem)
        return window.pageYOffset + elem.getBoundingClientRect().top;
    return -1;
}

ready().then(() => {
    startSpinningChars();
});

M src/scss/_base.scss => src/scss/_base.scss +8 -1
@@ 64,6 64,13 @@ body {
    }
}

// Why is this you ask? Well look into application.js#applyScroll
.scrolled .sheet[hidden] {
    display: block;
    opacity: 0;
    animation: none;
}

#particles-js {
    position: absolute;
    width: 100%;


@@ 80,4 87,4 @@ body {
    height: 20%;
    width: 100%;
    background: linear-gradient(to bottom, transparentize($colorBrand, 1.0) 0%, $colorBrand 100%);
}
\ No newline at end of file
}