Can someone help me with this code. It actually pisses me off...
I want the dropdown that opens to collapse to a button when I click anywhere on the screen except for "sphere". I don't want it to work when the dropdown is already in button form. It's kinda like when u have multiple windows on screen and clicking on one closes the other [unless it's pinned].
MY BIGGEST PROBLEM: I can't disable clicks for either state, so help... I can explain more in the comments..
CODE
// → split text into spans
const h1 = document.querySelector("[data-splittext]");
if (h1) {
const letters = [...h1.textContent.trim()];
h1.innerHTML = letters
.map((char, i) => \<span style="--i:${i / (letters.length + 1)};">${char}</span>`)`
.join("");
}
// → slideVars setup
import { slideVars } from "https://esm.sh/@codepen/slidevars";
slideVars.init({
"--radius": { type: "slider", min: 1, max: 80, default: 25, unit: "vmin" },
"--spinDuration": { type: "slider", min: 1, max: 100, default: 25, unit: "s" },
"--speedYMod": { type: "slider", min: -10, max: 10, default: -3, unit: "" },
"--speedXMod": { type: "slider", min: -10, max: 10, default: 1, unit: "" },
"--speedZMod": { type: "slider", min: -10, max: 10, default: 0, unit: "" },
"--perspective": { type: "slider", min: 100, max: 2000, default: 1000, unit: "px" },
"--blur": { type: "slider", min: 0, max: 100, default: 8, unit: "px" },
"--c-black": { type: "color", default: "#202116" },
"--c-white": { type: "color", default: "#fff" }
});
// → panel refs
const clickTarget = document.querySelector("dialog");
const settingsPanel =
document.querySelector("slide-vars") ||
document.querySelector(".slidevars-container") ||
document.querySelector("slidevars-panel");
// → panel toggle / positioning
document.addEventListener("click", (event) => {
if (!settingsPanel) return;
if (settingsPanel.contains(event.target)) return;
if (!clickTarget || !clickTarget.contains(event.target)) return;
event.stopPropagation();
event.preventDefault();
const isHidden = settingsPanel.style.display === "none";
const isActive = settingsPanel.classList.contains("is-active");
if (isHidden) {
settingsPanel.style.setProperty("top", \${event.clientY}px`, "important");`
settingsPanel.style.setProperty("left", \${event.clientX}px`, "important");`
settingsPanel.style.display = "block";
settingsPanel.classList.add("is-active");
return;
}
if (isActive) {
destructPanel();
return;
}
settingsPanel.style.setProperty("top", \${event.clientY}px`, "important");`
settingsPanel.style.setProperty("left", \${event.clientX}px`, "important");`
settingsPanel.style.setProperty("right", "unset", "important");
settingsPanel.style.setProperty("bottom", "unset", "important");
settingsPanel.classList.add("is-active");
});
// → dragging
let isDragging = false;
let didDrag = false;
let startX, startY, initialLeft, initialTop;
if (settingsPanel) {
settingsPanel.addEventListener("mousedown", (e) => {
if (["INPUT", "SELECT", "BUTTON"].includes(e.target.tagName)) return;
isDragging = true;
didDrag = false;
startX = e.clientX;
startY = e.clientY;
const rect = settingsPanel.getBoundingClientRect();
initialLeft = rect.left;
initialTop = rect.top;
settingsPanel.style.cursor = "grabbing";
e.preventDefault();
});
window.addEventListener("mousemove", (e) => {
if (!isDragging) return;
didDrag = true;
const dx = e.clientX - startX;
const dy = e.clientY - startY;
settingsPanel.style.setProperty("left", \${initialLeft + dx}px`, "important");`
settingsPanel.style.setProperty("top", \${initialTop + dy}px`, "important");`
});
window.addEventListener("mouseup", () => {
if (!isDragging) return;
isDragging = false;
settingsPanel.style.cursor = "grab";
if (didDrag) {
const root = settingsPanel.shadowRoot;
const toggleBtn = root?.querySelector(".toggle-button");
toggleBtn?.click();
}
didDrag = false;
});
settingsPanel.addEventListener("dblclick", (e) => {
if (didDrag) return;
e.stopPropagation();
destructPanel();
});
}
// → collapse animation
function destructPanel() {
if (!settingsPanel) return;
settingsPanel.classList.remove("is-active");
settingsPanel.classList.remove("slidevars-unfold");
settingsPanel.classList.add("slidevars-fold");
setTimeout(() => {
settingsPanel.style.display = "none";
settingsPanel.classList.remove("slidevars-fold");
}, 350);
}
// → customize toggle button
customElements.whenDefined("slide-vars").then(() => {
const el = document.querySelector("slide-vars");
if (!el) return;
const root = el.shadowRoot;
if (!root) return;
const btn = root.querySelector(".toggle-button");
if (!btn) return;
btn.style.background = "#a83030";
btn.style.borderRadius = "50%";
btn.style.setProperty("mask", "none", "important");
btn.style.setProperty("-webkit-mask", "none", "important");
const oldLogo = btn.querySelector("slidevars-logo");
oldLogo?.remove();
const fontLink = document.createElement("link");
fontLink.rel = "stylesheet";
fontLink.href = "https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined";
root.appendChild(fontLink);
const icon = document.createElement("span");
icon.textContent = "sync";
icon.style.fontFamily = "Material Symbols Outlined";
icon.style.fontSize = "28px";
icon.style.fontVariationSettings = "'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 36'";
icon.style.setProperty("color", "#06c943", "important");
icon.style.position = "absolute";
icon.style.left = "50%";
icon.style.top = "50%";
icon.style.transform = "translate(-50%, -50%)";
icon.style.pointerEvents = "none";
btn.appendChild(icon);
});