update to kirby 4.8
This commit is contained in:
commit
7d7df341d1
636 changed files with 139949 additions and 0 deletions
363
assets/js/script.js
Normal file
363
assets/js/script.js
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
document.addEventListener("DOMContentLoaded", () => {
|
||||
// init
|
||||
const introduction = document.querySelector("#introduction");
|
||||
if (introduction) playIntroduction();
|
||||
|
||||
initNav();
|
||||
initNotes();
|
||||
styleCallouts();
|
||||
linkLayersScrolls();
|
||||
|
||||
let currentUrl = location.href;
|
||||
|
||||
window.onpopstate = function () {
|
||||
let target = null;
|
||||
const currentLayerId = document.querySelector(".current").id;
|
||||
|
||||
if (currentLayerId === "first-level") {
|
||||
window.location.href = window.location.href;
|
||||
} else if (currentLayerId === "second-level") {
|
||||
history.pushState(null, document.title, currentUrl);
|
||||
target = document.querySelector("#first-level .layer-btn");
|
||||
const event = {
|
||||
preventDefault: () => {},
|
||||
stopPropagation: () => {},
|
||||
target: target,
|
||||
};
|
||||
go(event);
|
||||
} else if (currentLayerId === "third-level") {
|
||||
history.pushState(null, document.title, currentUrl);
|
||||
target = document.querySelector("#second-level .layer-btn");
|
||||
const event = {
|
||||
preventDefault: () => {},
|
||||
stopPropagation: () => {},
|
||||
target: target,
|
||||
};
|
||||
go(event);
|
||||
}
|
||||
};
|
||||
|
||||
const collapsableSectionBtns = document.querySelectorAll(
|
||||
".collapsable__button"
|
||||
);
|
||||
collapsableSectionBtns.forEach((btn) => {
|
||||
btn.addEventListener("click", () => {
|
||||
const section = btn.parentNode;
|
||||
section.classList.toggle("open");
|
||||
});
|
||||
});
|
||||
|
||||
animateCursor();
|
||||
|
||||
// functions
|
||||
let ticking = false;
|
||||
|
||||
function linkLayersScrolls() {
|
||||
const thirdLayer = document.querySelector("#third-level");
|
||||
let secondLayer = document.querySelector("#second-level");
|
||||
thirdLayer.addEventListener("scroll", () => {
|
||||
if (!ticking) {
|
||||
window.requestAnimationFrame(() => {
|
||||
scrollLayer(secondLayer, thirdLayer.scrollTop);
|
||||
ticking = false;
|
||||
});
|
||||
ticking = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function scrollLayer(secondLayer, scrollTop) {
|
||||
if (window.innerWidth > 650) return;
|
||||
const parallaxFactor = 0.5;
|
||||
if (secondLayer.scrollTop <= 40) {
|
||||
let newScrollTop = scrollTop * parallaxFactor;
|
||||
newScrollTop = newScrollTop > 40 ? 40 : newScrollTop;
|
||||
secondLayer.scrollTop = newScrollTop;
|
||||
}
|
||||
}
|
||||
|
||||
function playIntroduction() {
|
||||
const parts = introduction.querySelectorAll("span");
|
||||
const step = 800;
|
||||
parts.forEach((part, index) => {
|
||||
setTimeout(() => {
|
||||
part.classList.remove("hide");
|
||||
}, step + step * index);
|
||||
});
|
||||
setTimeout(() => {
|
||||
introduction.classList.add("hide");
|
||||
}, parts.length + 5 * step);
|
||||
}
|
||||
|
||||
function formatSize(size) {
|
||||
if (size < 1_000) {
|
||||
return {
|
||||
size: size,
|
||||
unit: " o",
|
||||
};
|
||||
} else if (size < 1_000_000) {
|
||||
return {
|
||||
size: size / 1_000,
|
||||
unit: " Ko",
|
||||
};
|
||||
} else if (size < 1_000_000_000) {
|
||||
return {
|
||||
size: size / 1_000_000,
|
||||
unit: " Mo",
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
size: size / 1_000_000_000,
|
||||
unit: " Go",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function initNotes() {
|
||||
const notes = document.querySelectorAll(".note");
|
||||
notes.forEach((note) => {
|
||||
note.addEventListener("click", () => {
|
||||
note.classList.toggle("open");
|
||||
note.querySelector(".details").classList.toggle("hide");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function animateCursor() {
|
||||
const cursor = document.getElementById("cursor");
|
||||
|
||||
let animationFrameId;
|
||||
|
||||
document.addEventListener("mousemove", (e) => {
|
||||
if (window.innerWidth < 640) return;
|
||||
const hoveredLayer = e.target.closest(".layer");
|
||||
if (hoveredLayer.id === "first-level") {
|
||||
cursor.classList.add("light");
|
||||
} else if (!e.target.closest(".collapsable__button")) {
|
||||
cursor.classList.remove("light");
|
||||
}
|
||||
isCursorVisible = true;
|
||||
cursor.style.display = "flex";
|
||||
document.body.style.cursor = "none";
|
||||
|
||||
const x = e.clientX - 16;
|
||||
const y = e.clientY - 16 + window.scrollY;
|
||||
|
||||
cancelAnimationFrame(animationFrameId);
|
||||
|
||||
animationFrameId = requestAnimationFrame(() => {
|
||||
cursor.style.left = x + "px";
|
||||
cursor.style.top = y + "px";
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function initNav() {
|
||||
listenLinks();
|
||||
showTargetPageSize();
|
||||
listenCollapsableSections();
|
||||
}
|
||||
|
||||
function listenLinks() {
|
||||
const internalLinks = document.querySelectorAll("a.internal-link");
|
||||
internalLinks.forEach((btn) => {
|
||||
btn.addEventListener("click", go);
|
||||
});
|
||||
|
||||
const imageLinks = document.querySelectorAll("figure a");
|
||||
|
||||
imageLinks.forEach((link) => {
|
||||
const cursorText = document.querySelector("#cursor #text");
|
||||
link.addEventListener("mouseenter", () => {
|
||||
const href = new URL(link.href);
|
||||
cursorText.style.display = "flex";
|
||||
cursorText.textContent = "ouvrir " + href.host;
|
||||
});
|
||||
link.addEventListener("mouseleave", () => {
|
||||
cursorText.style.display = "";
|
||||
cursorText.textContent = "";
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function removeListeners() {
|
||||
const internalLinks = document.querySelectorAll("a.internal-link");
|
||||
internalLinks.forEach((btn) => {
|
||||
btn.removeEventListener("click", go);
|
||||
});
|
||||
}
|
||||
|
||||
function removeTargetPageListeners() {
|
||||
const internalLinks = document.querySelectorAll("a.internal-link");
|
||||
internalLinks.forEach((link) => {
|
||||
link.removeEventListener("mouseenter", handleMouseEnter);
|
||||
link.removeEventListener("mouseleave", handleMouseLeave);
|
||||
});
|
||||
}
|
||||
|
||||
function handleMouseEnter() {
|
||||
const cursorText = document.querySelector("#cursor #text");
|
||||
if (this.href === window.location.href) return;
|
||||
cursorText.style.display = "flex";
|
||||
cursorText.textContent = this.dataset.size;
|
||||
}
|
||||
|
||||
function handleMouseLeave() {
|
||||
const cursorText = document.querySelector("#cursor #text");
|
||||
cursorText.style.display = "";
|
||||
cursorText.textContent = "";
|
||||
}
|
||||
|
||||
function toggleVisibility(element, condition) {
|
||||
element.classList.remove("unvisible", condition);
|
||||
}
|
||||
|
||||
function moveBackward(wrapper, page) {
|
||||
page.content
|
||||
.querySelector(".current .layer-btn")
|
||||
.classList.remove("unvisible");
|
||||
|
||||
wrapper.innerHTML = page.content.innerHTML;
|
||||
wrapper.classList.add("current");
|
||||
|
||||
setTimeout(() => {
|
||||
wrapper.querySelector(".current .layer-btn").classList.add("unvisible");
|
||||
}, 50);
|
||||
}
|
||||
|
||||
function moveForward(originWrapper, page) {
|
||||
const isThirdLevel = originWrapper.id === "third-level";
|
||||
const targetWrapper = isThirdLevel
|
||||
? document.querySelector("#second-level")
|
||||
: originWrapper.nextElementSibling;
|
||||
|
||||
originWrapper.classList.remove("current");
|
||||
targetWrapper.classList.add("current");
|
||||
|
||||
const emptys = page.content.querySelectorAll(".empty");
|
||||
const current = document.querySelector(".current");
|
||||
|
||||
if (current.id === "second-level" && emptys.length === 3) {
|
||||
const firstEmpty = page.content.querySelector(".empty");
|
||||
firstEmpty.parentNode.removeChild(firstEmpty);
|
||||
}
|
||||
|
||||
targetWrapper.innerHTML = page.content.innerHTML;
|
||||
targetWrapper.classList.remove("out-screen");
|
||||
}
|
||||
|
||||
function go(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
const btn = event.target.closest("a");
|
||||
const wrapper = btn.closest(".layer");
|
||||
const targetUrl = btn.href;
|
||||
|
||||
if (targetUrl === window.location.href) return;
|
||||
|
||||
removeListeners();
|
||||
removeTargetPageListeners();
|
||||
|
||||
fetch(targetUrl)
|
||||
.then((res) => res.text())
|
||||
.then((htmlString) => {
|
||||
const page = getPage(htmlString);
|
||||
history.pushState(null, page.title, targetUrl);
|
||||
|
||||
let timer = 0;
|
||||
|
||||
const currentLevel = document.querySelector(".current");
|
||||
if (currentLevel.scrollTop > 0) {
|
||||
document.querySelector(".current").scrollTo({
|
||||
top: 0,
|
||||
behavior: "smooth",
|
||||
});
|
||||
timer = 500;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
if (wrapper.classList.contains("current")) {
|
||||
moveForward(wrapper, page);
|
||||
} else {
|
||||
moveBackward(wrapper, page);
|
||||
}
|
||||
|
||||
document.querySelector("title").textContent = `${page.title}`;
|
||||
|
||||
document.querySelectorAll(`.current ~ .layer`).forEach((layer) => {
|
||||
layer.classList.add("out-screen");
|
||||
});
|
||||
|
||||
const layerBtnsToShow = document.querySelectorAll(
|
||||
".layer-btn:not(.current .layer-btn)"
|
||||
);
|
||||
|
||||
layerBtnsToShow.forEach((layerBtn) => {
|
||||
toggleVisibility(layerBtn, window.innerWidth < 640);
|
||||
});
|
||||
|
||||
listenLinks();
|
||||
showTargetPageSize();
|
||||
styleCallouts();
|
||||
initNotes();
|
||||
linkLayersScrolls();
|
||||
currentUrl = window.location.href;
|
||||
}, timer);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Fetch Error:", err);
|
||||
});
|
||||
}
|
||||
|
||||
function showTargetPageSize() {
|
||||
const internalLinks = document.querySelectorAll("a.internal-link");
|
||||
internalLinks.forEach((link) => {
|
||||
link.addEventListener("mouseenter", handleMouseEnter);
|
||||
link.addEventListener("mouseleave", handleMouseLeave);
|
||||
});
|
||||
}
|
||||
|
||||
function listenCollapsableSections() {
|
||||
const collapsableSections = document.querySelectorAll(
|
||||
".collapsable__button"
|
||||
);
|
||||
|
||||
const cursorText = document.querySelector("#cursor #text");
|
||||
collapsableSections.forEach((section) => {
|
||||
section.addEventListener("mouseenter", () => {
|
||||
cursorText.style.display = "flex";
|
||||
cursorText.textContent = "ouvrir/fermer";
|
||||
});
|
||||
section.addEventListener("mouseleave", () => {
|
||||
cursorText.style.display = "";
|
||||
cursorText.textContent = "";
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function getPage(htmlString) {
|
||||
const parser = new DOMParser();
|
||||
const fullPage = parser.parseFromString(htmlString, "text/html");
|
||||
const title = fullPage.querySelector("title").textContent;
|
||||
const content = fullPage.querySelector(".layer.current");
|
||||
|
||||
return {
|
||||
title: title,
|
||||
content: content,
|
||||
};
|
||||
}
|
||||
|
||||
function getUrlLastPart(url) {
|
||||
const parts = url.split("/");
|
||||
const lastPart = parts[parts.length - 1];
|
||||
return lastPart;
|
||||
}
|
||||
|
||||
function styleCallouts() {
|
||||
const callouts = document.querySelectorAll(".callout");
|
||||
callouts.forEach((callout) => {
|
||||
if (!callout.closest("p")) return;
|
||||
callout.closest("p").classList.add("callout");
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue