vlw.se/assets/js/pages/index.js
Victor Westerlund 140132fa72
feat: release 1.0.0 (#1)
* wip: 2024-02-13T12:59:17+0100 (1707825557)

* wip: 2024-02-21T03:16:48+0100 (1708481808)

* wip: 2024-02-21T20:50:20+0100 (1708545020)

* wip: 2024-02-21T20:50:20+0100 (1708545020)

* wip: 2024-03-01T13:17:58+0100 (1709295478)

* wip: 2024-03-06T12:06:58+0100 (1709723218)

* wip: 2024-03-07T15:07:57+0100 (1709820477)

* wip: 2024-03-09T01:36:44+0100 (1709944604)

* wip: 2024-03-14T23:24:12+0100 (1710455052)

* wip: 2024-03-28T18:27:40+0100 (1711646860)

* wip: 2024-03-28T18:27:40+0100 (1711646860)

* feat: create README

* wip: 2024-04-01T12:21:45+0200 (1711966905)
2024-04-01 10:22:25 +00:00

120 lines
No EOL
4.1 KiB
JavaScript
Executable file

const EMAIL_CPY_ANIM_DUR_MSECONDS = 1000;
// Run email copied splash animation
const emailCopiedAnimation = () => {
const CONFETTI_COUNT = 40;
const CONFETTI_SCALE_PIXELS = 300;
const randomIntFromInterval = (min, max) => {
return Math.floor(Math.random() * (max - min + 1) + min)
}
// Create new splash element
const splashElement = document.createElement("splash");
splashElement.innerText = "copied!";
// Set inline display to none to hide this element on pages where the splash element has no override styles defined.
splashElement.style.display = "none";
// Array of box-shadow strings as "confetti"
const confetti = [];
// Generate random confetti
for (let i = 0; i < CONFETTI_COUNT; i++) {
// Random confetti position
const x = randomIntFromInterval(CONFETTI_SCALE_PIXELS * -1, CONFETTI_SCALE_PIXELS);
const y = randomIntFromInterval(CONFETTI_SCALE_PIXELS * -1, CONFETTI_SCALE_PIXELS);
// Random confetti RGB color
const rgb = [
randomIntFromInterval(0, 255),
randomIntFromInterval(0, 255),
randomIntFromInterval(0, 255)
];
// Interpolate random values and append to outer confetti array
confetti.push(`${x}px ${y}px 0 rgb(${rgb.join(",")})`);
}
// Set CSS variable on splash element that in turn will be used by pseudo-element
splashElement.style.setProperty("--confetti", confetti.join(","));
// Start animation by appending the created element to the document body
document.body.appendChild(splashElement);
// Run hide animation
setTimeout(() => {
splashElement.classList.add("hide");
// Selfdestruct element when hide animation finishes
setTimeout(() => splashElement.remove(), 400);
}, EMAIL_CPY_ANIM_DUR_MSECONDS + 100);
}
new vv.Interactions("index", {
// Copy email address to clipboard
copyEmail: async () => {
try {
await navigator.clipboard.writeText("victor@vlw.se");
// Run "email copied" animation!
emailCopiedAnimation();
// NOTE: I don't know, spamming the button is kinda fun
// Prevent interactions with the copy email elements while the animation is running
/*[...document.querySelectorAll("[vv-call='copyEmail']")].forEach(element => {
//element.classList.add("lock");
setTimeout(() => element.classList.remove("lock"), EMAIL_CPY_ANIM_DUR_MSECONDS);
});*/
} catch (error) {
console.error(error.message);
}
},
// Open the fullscreen menu
openMenu: () => document.querySelector("menu").classList.add("active"),
// Close the fullscreen menu
closeMenu: () => document.querySelector("menu").classList.remove("active")
});
// Change site accent color on hover of menu items
if (window.matchMedia("(hover: hover)")) {
// Update root CSS variables
const updateColor = (rgb = null, hue = 0) => {
if (!rgb) {
document.documentElement.style.removeProperty("--hue-accent");
document.documentElement.style.removeProperty("--primer-color-accent");
document.documentElement.style.removeProperty("--color-accent");
return;
}
document.documentElement.style.setProperty("--hue-accent", `${hue}deg`);
document.documentElement.style.setProperty("--primer-color-accent", `${rgb}`);
// Compiled color variable must to be updated to receive the new RGB values
document.documentElement.style.setProperty("--color-accent", "rgb(var(--primer-color-accent)");
};
[...document.querySelectorAll("menu li")].forEach(element => {
// Change site accent color to RGB and HUE rotation defined in element dataset
element.addEventListener("mouseenter", (event) => updateColor(event.target.dataset.rgb, event.target.dataset.hue));
// Reset initial accent color and hues
element.addEventListener("mouseleave", () => updateColor());
});
// Reset color on navigation
document.querySelector(vv._env.MAIN).addEventListener(vv.Navigation.events.LOADED, () => updateColor(), { once: true });
}
// Open search box from mobile fullscreen menu
{
// Open search dialog when searchbox is clicked
document.querySelector("menu searchbox").addEventListener("click", () => {
// Search box dialog element
document.querySelector("dialog.search").showModal();
// Close fullscreen menu
document.querySelector("menu").classList.remove("active");
});
}