maju.www
clone your own copy | download snapshot

Snapshots | iceberg

Inside this repository

script.js
application/javascript

Download raw (7.0 KB)

// Code for syncing the scroll //
const mainElement = document.querySelector(".main");
const sideBar = document.querySelector(".aside-scroll");

let scrollRatio = sideBar.scrollHeight / mainElement.scrollHeight;

mainElement.addEventListener("scroll", () => {
  if (mainElement.getAttribute("data-view") !== "grid") {
    sideBar.scrollTop = mainElement.scrollTop * scrollRatio;
  }
});

//Recalculate the scroll ratio everytime the window is resized.
window.addEventListener("resize", () => {
  scrollRatio = sideBar.scrollHeight / mainElement.scrollHeight;
});

const projects = document.querySelectorAll(".project");

const frLangButton = document.getElementById("language-fr");
const nlLangButton = document.getElementById("language-nl");
const enLangButton = document.getElementById("language-en");

let currentScrollPos;

// Intersection observer to update the url depending on which project is visible
const options = {
  // Only call the callback function when at least 50% of the element is in the viewport
  threshold: 0.8,
  // Use the document as the root element for intersection calculations
  root: mainElement,
};

const observer = new IntersectionObserver((entries, _observer) => {
  entries.forEach((entry) => {
    // Check if the element has entered the viewport
    if (entry.isIntersecting) {
      if (mainElement.getAttribute("data-view") !== "grid") {
        history.pushState(null, null, `#${entry.target.id}`)
        frLangButton.href = `fr/#${entry.target.id}`;
        nlLangButton.href = `nl/#${entry.target.id}`;
        enLangButton.href = `en/#${entry.target.id}`;

        currentScrollPos = entry.target

        const strokeSize = window.getComputedStyle(document.documentElement).getPropertyValue('--stroke-size')[0];

        if (entry.target.previousElementSibling) {
          entry.target.dataset.previousProject = entry.target.previousElementSibling.offsetTop - Number(strokeSize);
        }
        if (entry.target.nextElementSibling) {
          entry.target.dataset.nextProject = entry.target.nextElementSibling.offsetTop - Number(strokeSize);
        }
      }
    }
  });
}, options);

projects.forEach((project) => {
  observer.observe(project);
});

const colors = [
  "--red",
  "--yellow",
  "--pink",
  "--green",
  "--orange",
  "--purple",
  "--sand",
  "--brown",
  "--blue",
  "--darkergrey",
  "--labelgrey",
];

// Code for syncing the checkboxes and displaying the right projects //

function toggleCheckboxes(e) {
  closeAbout();
  const checkboxId = e.target.id;
  const isChecked = e.target.checked;

  if (checkboxId === "all") {
    toggleAll(isChecked);
  } else if (document.querySelector("#all").checked) {
    toggleAll(false);
    e.target.checked = true;
  }

  if (
    document.querySelectorAll('input[type="checkbox"]:checked').length === 5 // If all checkboxes are checked, also check the all checkbox
  ) {
    toggleAll(true);
  }
  if (
    document.querySelectorAll('input[type="checkbox"]:checked').length === 0
  ) {
    choice = Math.ceil(Math.random() * colors.length);
    document.body.style.backgroundColor = `var(${colors[choice]})`;
  } else {
    document.body.style.backgroundColor = "black";
  }
  displayProjects();
}

function toggleAll(checkedValue) {
  document
    .querySelectorAll('input[type="checkbox"]')
    .forEach((checkbox) => (checkbox.checked = checkedValue));
}

function displayProjects() {
  const checkedValues = [
    ...document.querySelectorAll('input[type="checkbox"]:checked'),
  ].map((checkbox) => checkbox.value);
  const selectedYear = document.querySelector("#years").value;
  const selectedYears =
    selectedYear === "All"
      ? [...document.querySelectorAll(".project")].map(
        (project) => project.dataset.projectYear
      )
      : [selectedYear];

  document.querySelectorAll("[data-project-type]").forEach((project) => {
    if (
      checkedValues.includes(project.dataset.projectType) &&
      selectedYears.includes(project.dataset.projectYear)
    ) {
      project.dataset.projectVisibility = "true";
    } else {
      project.dataset.projectVisibility = "false";
    }
  });
}

function filterYears() {
  if (mainElement.dataset.view !== "grid") {
    toggleMainView();
  }
  displayProjects();
}

function closeAllInfo() {
  const projects = document.querySelectorAll(".project");
  projects.forEach((project) => {
    project.dataset.infoVisibility = false;
  });
}

function toggleMainView() {
  mainElement.dataset.view === "list" ? setGridView() : setListView();
}
function setListView() {
  mainElement.dataset.view = "list";
  document.querySelector("#list-view").classList.add("active");
  document.querySelector("#grid-view").classList.remove("active");
  closeAllInfo();
}

function setGridView() {
  mainElement.dataset.view = "grid";
  document.querySelector("#grid-view").classList.add("active");
  document.querySelector("#list-view").classList.remove("active");
  closeAllInfo();
}

function toggleInfoVisibility(e) {
  const parentElement = e.target.closest(".project");
  const visibility = parentElement.getAttribute("data-info-visibility");

  const mainView = mainElement.getAttribute("data-view");
  if (mainView === "grid") {
    setListView();
    const parentId = parentElement.id;
    window.location.hash = parentId;
    return;
  }

  parentElement.setAttribute(
    "data-info-visibility",
    visibility === "false" ? "true" : "false"
  );
}
function displayAbout() {
  const aboutElement = document.querySelector("#about");
  aboutElement.dataset.visibility === "hidden" ? openAbout() : closeAbout();
}
function openAbout() {
  const aboutElement = document.querySelector("#about");
  const aboutButton = document.querySelector("#about-button");
  aboutElement.dataset.visibility = "visible";
  aboutButton.dataset.visibility = "visible";
}
function closeAbout() {
  const aboutElement = document.querySelector("#about");
  const aboutButton = document.querySelector("#about-button");
  aboutElement.dataset.visibility = "hidden";
  aboutButton.dataset.visibility = "hidden";
}

function toggleNavVisibility(element) {
  const navMenu = element.target.closest(".nav-menu");
  if (navMenu) {
    const visibility = navMenu.dataset.visibility;

    if (visibility === "hidden" || visibility === "default") {
      navMenu.dataset.visibility = "visible";
    } else if (visibility === "visible") {
      navMenu.dataset.visibility = "hidden";
    }
  }
}
document
  .querySelector(".nav-hamburger-button")
  .addEventListener("click", (element) => {
    toggleNavVisibility(element);
  });

// For keyboard scrolling
window.onload = () => {
  document.body.onkeydown = (event) => {
    switch (event.key) {
      case " ":
      case "PageDown":
      case "ArrowDown": {
        event.preventDefault()
        mainElement.scrollTo({
          top: currentScrollPos.dataset.nextProject,
          behavior: "smooth",
        });
        break;
      }
      case "PageUp":
      case "ArrowUp": {
        event.preventDefault()
        mainElement.scrollTo({
          top: currentScrollPos.dataset.previousProject,
          behavior: "smooth",
        });
        break;
      }
    }
  };
};