120 lines
4.1 KiB
JavaScript
120 lines
4.1 KiB
JavaScript
/* Progress line, reveals, diagram draw, space backdrop. No dependencies. */
|
|
(function () {
|
|
var root = document.documentElement;
|
|
root.classList.add("anims");
|
|
var reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
var canObserve = "IntersectionObserver" in window;
|
|
|
|
function reveal(target, threshold) {
|
|
var nodes = [].slice.call(
|
|
typeof target == "string" ? document.querySelectorAll(target) : target
|
|
);
|
|
if (!canObserve || reduce) {
|
|
nodes.forEach(function (n) { n.classList.add("is-in"); });
|
|
return;
|
|
}
|
|
var io = new IntersectionObserver(function (entries) {
|
|
entries.forEach(function (entry) {
|
|
if (!entry.isIntersecting) return;
|
|
entry.target.classList.add("is-in");
|
|
io.unobserve(entry.target);
|
|
});
|
|
}, { threshold: threshold, rootMargin: "0px 0px -6% 0px" });
|
|
nodes.forEach(function (n) { io.observe(n); });
|
|
}
|
|
|
|
var bar = document.querySelector(".progress");
|
|
var waiting = false;
|
|
var groups = document.querySelectorAll(
|
|
".tiles, .chips, .ladder, .courses, .cert-gallery, .work-list, .timeline, .contact-rows"
|
|
);
|
|
|
|
function paint() {
|
|
waiting = false;
|
|
if (!bar) return;
|
|
var max = document.documentElement.scrollHeight - window.innerHeight;
|
|
var p = max > 0 ? window.scrollY / max : 0;
|
|
bar.style.transform = "scaleX(" + Math.min(1, Math.max(0, p)) + ")";
|
|
}
|
|
|
|
function queue() {
|
|
if (waiting) return;
|
|
waiting = true;
|
|
window.requestAnimationFrame(paint);
|
|
}
|
|
|
|
function makeSpace() {
|
|
var space = document.createElement("div");
|
|
space.className = "space";
|
|
space.setAttribute("aria-hidden", "true");
|
|
var small = window.innerWidth < 700;
|
|
var tints = ["#ffffff", "#ffffff", "#cfe0ff", "#bcd0ff", "#ffe6c8", "#a8f0d2"];
|
|
|
|
function rnd(a, b) { return a + Math.random() * (b - a); }
|
|
|
|
function layer(count, cls) {
|
|
var box = document.createElement("div");
|
|
box.className = "space__layer " + cls;
|
|
for (var i = 0; i < count; i++) {
|
|
var s = document.createElement("div");
|
|
var r = Math.random();
|
|
var size = r < 0.7 ? rnd(1, 1.6) : r < 0.94 ? rnd(1.8, 2.4) : rnd(2.8, 3.6);
|
|
var big = r >= 0.94;
|
|
s.className = "space__star";
|
|
s.style.left = rnd(0, 100).toFixed(2) + "%";
|
|
s.style.top = rnd(0, 100).toFixed(2) + "%";
|
|
s.style.width = size.toFixed(1) + "px";
|
|
s.style.height = size.toFixed(1) + "px";
|
|
s.style.setProperty("--c", tints[(Math.random() * tints.length) | 0]);
|
|
s.style.setProperty("--o", (big ? rnd(0.8, 1) : rnd(0.4, 0.85)).toFixed(2));
|
|
s.style.setProperty("--g", (size * (big ? 3 : 1.5)).toFixed(1) + "px");
|
|
s.style.setProperty("--t", rnd(3, 8).toFixed(1) + "s");
|
|
s.style.setProperty("--d", (-rnd(0, 8)).toFixed(1) + "s");
|
|
box.appendChild(s);
|
|
}
|
|
space.appendChild(box);
|
|
}
|
|
|
|
layer(small ? 50 : 90, "space__layer--far");
|
|
layer(small ? 22 : 40, "space__layer--near");
|
|
|
|
if (!reduce) {
|
|
var aim = function (m) {
|
|
m.style.left = rnd(35, 105).toFixed(1) + "%";
|
|
m.style.top = rnd(-8, 45).toFixed(1) + "%";
|
|
};
|
|
for (var k = 0; k < (small ? 2 : 3); k++) {
|
|
var m = document.createElement("div");
|
|
m.className = "space__meteor";
|
|
m.style.setProperty("--t", rnd(9, 17).toFixed(1) + "s");
|
|
m.style.setProperty("--d", rnd(1, 9).toFixed(1) + "s");
|
|
m.style.setProperty("--a", rnd(138, 152).toFixed(0) + "deg");
|
|
aim(m);
|
|
m.addEventListener("animationiteration", function (e) { aim(e.target); });
|
|
space.appendChild(m);
|
|
}
|
|
}
|
|
|
|
document.body.appendChild(space);
|
|
}
|
|
|
|
try {
|
|
[].forEach.call(groups, function (group) {
|
|
[].forEach.call(group.children, function (item, i) {
|
|
item.style.setProperty("--i", Math.min(i, 6));
|
|
});
|
|
});
|
|
reveal(".reveal", 0.08);
|
|
reveal(".diagram", 0.22);
|
|
reveal(groups, 0.12);
|
|
if (bar && !reduce) {
|
|
window.addEventListener("scroll", queue, { passive: true });
|
|
window.addEventListener("resize", queue, { passive: true });
|
|
paint();
|
|
}
|
|
makeSpace();
|
|
} catch (err) {
|
|
root.classList.remove("anims");
|
|
}
|
|
})();
|