Static HTML/CSS/JS portfolio for the design studio 2RE03: locally vendored Bootstrap 5.3.3, self-hosted Inter + Space Grotesk fonts, six pages, Collins-style scroll-snap carousels, a case-studies index with 10 detail pages, and a Web3Forms contact form.
68 lines
1.9 KiB
JavaScript
68 lines
1.9 KiB
JavaScript
/* ==========================================================================
|
|
2RE03 case studies index
|
|
Cursor-following preview image for the typographic case-study list.
|
|
Progressive enhancement: without JS (or on touch/small screens) each row
|
|
shows its own inline thumbnail instead.
|
|
========================================================================== */
|
|
(function () {
|
|
"use strict";
|
|
|
|
var preview = document.querySelector("[data-case-preview]");
|
|
var rows = document.querySelectorAll("[data-case-image]");
|
|
|
|
if (!preview || !rows.length) {
|
|
return;
|
|
}
|
|
|
|
// Only run the floating preview for hover-capable, fine-pointer devices.
|
|
if (!window.matchMedia("(hover: hover) and (pointer: fine)").matches) {
|
|
return;
|
|
}
|
|
|
|
var frame = null;
|
|
var pointerX = 0;
|
|
var pointerY = 0;
|
|
|
|
function place() {
|
|
frame = null;
|
|
preview.style.left = pointerX + "px";
|
|
preview.style.top = pointerY + "px";
|
|
}
|
|
|
|
function onMove(event) {
|
|
pointerX = event.clientX;
|
|
pointerY = event.clientY;
|
|
if (!frame) {
|
|
frame = window.requestAnimationFrame(place);
|
|
}
|
|
}
|
|
|
|
function show(source) {
|
|
if (source) {
|
|
preview.src = source;
|
|
}
|
|
preview.classList.add("is-visible");
|
|
}
|
|
|
|
function hide() {
|
|
preview.classList.remove("is-visible");
|
|
}
|
|
|
|
Array.prototype.forEach.call(rows, function (row) {
|
|
var source = row.getAttribute("data-case-image");
|
|
|
|
row.addEventListener("mouseenter", function () { show(source); });
|
|
row.addEventListener("mousemove", onMove);
|
|
row.addEventListener("mouseleave", hide);
|
|
|
|
// Keyboard users get the preview pinned to the row.
|
|
row.addEventListener("focus", function () {
|
|
var box = row.getBoundingClientRect();
|
|
pointerX = box.left + box.width / 2;
|
|
pointerY = box.top + box.height / 2;
|
|
place();
|
|
show(source);
|
|
});
|
|
row.addEventListener("blur", hide);
|
|
});
|
|
})();
|