我正在开发一个左侧有滚动间谍导航栏的登陆页面。我希望滚动间谍的背景和文本颜色根据背景颜色动态变化。
例如,如果该部分具有深色背景,我希望滚动间谍具有浅色背景(反之亦然)。我被困在如何检测部分的背景颜色并相应地调整滚动间谍的颜色。
这是我在滚动间谍及其文本中真正想要的行为,我也制作了导航及其功能,但我需要的只是更改颜色,例如,在浅色背景上,滚动间谍导航应该是黑色的,在浅色背景上,它应该是黑暗的:
这里是参考网站:MG Motor Europe:
这是我目前拥有的代码:
"use client";
import { useEffect, useState } from "react";
const sections = [
{ id: "MG HS", name: "MG HS" },
{ id: "MG Info", name: "MG HS" },
{ id: "safety", name: "Safety" },
{ id: "car-performance", name: "Car Performance" },
{ id: "plugin-hybrid", name: "Plugin Hybrid" },
{ id: "mg-pilot", name: "MG Pilot" },
{ id: "car-design", name: "Car Design" },
{ id: "comfort", name: "Comfort" },
{ id: "car-technology", name: "Car Technology" },
{ id: "mg-view", name: "MG View" },
];
const ScrollSpy = () => {
const [activeSection, setActiveSection] = useState<string>("");
const [hoveredSection, setHoveredSection] = useState<string>("");
const [showScrollSpy, setShowScrollSpy] = useState<boolean>(false);
useEffect(() => {
const handleScroll = () => {
const scrollPosition = window.scrollY + 60;
const sectionElements = document.querySelectorAll("div[id]");
let currentSectionId = "";
let anySectionVisible = false;
sectionElements.forEach((element) => {
const section = element as HTMLElement;
const sectionTop = section.getBoundingClientRect().top + window.scrollY;
const sectionBottom = sectionTop + section.offsetHeight;
if (scrollPosition >= sectionTop && scrollPosition < sectionBottom) {
currentSectionId = section.getAttribute("id") || "";
anySectionVisible = true;
}
});
if (!hoveredSection) {
setActiveSection(currentSectionId);
}
setShowScrollSpy(anySectionVisible);
};
window.addEventListener("scroll", handleScroll);
handleScroll();
return () => window.removeEventListener("scroll", handleScroll);
}, [hoveredSection]);
return (
<div
className={`hidden md:flex md:fixed md:top-[160px] md:left-[74px] md:h-full md:flex-col md:items-center md:space-y-2 md:p-2 md:z-50 md:transition-opacity md:duration-300 ${
showScrollSpy ? "md:opacity-100" : "md:opacity-0"
}`}
>
<div className="relative flex flex-col items-center space-y-2">
{sections.map((section) => (
<div
key={section.id}
className="relative flex items-center space-x-2"
onMouseEnter={() => {
setHoveredSection(section.id);
if (activeSection !== section.id) {
setActiveSection("");
}
}}
onMouseLeave={() => {
if (activeSection === "") {
setActiveSection((prev) => (prev === section.id ? "" : prev));
}
setHoveredSection("");
}}
>
<a
href={`#${section.id}`}
className={`block h-8 transition-all duration-300 ${
hoveredSection === section.id || activeSection === section.id
? "bg-[#181818] w-[4px]"
: "bg-[#181818] w-[2px] opacity-[70%]"
}`}
></a>
{(hoveredSection === section.id ||
activeSection === section.id) && (
<div
className={`absolute left-6 w-[60px] text-[10px] font-light text-[#181818] transition-opacity duration-300 ${
hoveredSection === section.id || activeSection === section.id
? "opacity-100"
: "opacity-0"
}`}
>
{section.name}
</div>
)}
</div>
))}
</div>
</div>
);
};
export default ScrollSpy;
我尝试根据部分 ID 更改颜色,但这不是正确的解决方案
我也向chatgpt寻求解决方案,它告诉我有关背景亮度的信息,但我无法管理它:
这是chatgpt的解决方案:
"use client";
import { useEffect, useState } from "react";
const sections = [
{ id: "MG HS", name: "MG HS" },
{ id: "MG Info", name: "MG Info" },
{ id: "safety", name: "Safety" },
{ id: "car-performance", name: "Car Performance" },
{ id: "plugin-hybrid", name: "Plugin Hybrid" },
{ id: "mg-pilot", name: "MG Pilot" },
{ id: "car-design", name: "Car Design" },
{ id: "comfort", name: "Comfort" },
{ id: "car-technology", name: "Car Technology" },
{ id: "mg-view", name: "MG View" },
];
const ScrollSpy = () => {
const [activeSection, setActiveSection] = useState<string>("");
const [hoveredSection, setHoveredSection] = useState<string>("");
const [showScrollSpy, setShowScrollSpy] = useState<boolean>(false);
const [scrollSpyColor, setScrollSpyColor] = useState<string>("light");
const getLuminance = (color: string) => {
// Convert rgba/hex to RGB
let rgb = color;
if (color.startsWith("rgba")) {
rgb = color.replace(/rgba?\(|\s+|\)/g, "").split(",").slice(0, 3).join(",");
} else if (color.startsWith("rgb")) {
rgb = color.replace(/rgb\(|\s+|\)/g, "");
} else if (color.startsWith("#")) {
let hex = color.slice(1);
if (hex.length === 3) hex = hex.split("").map(h => h + h).join("");
rgb = [0, 2, 4].map(i => parseInt(hex.slice(i, i + 2), 16)).join(",");
}
const [r, g, b] = rgb.split(",").map(Number).map(value => value / 255);
const luminance = 0.2126 * (r ** 2.2) + 0.7152 * (g ** 2.2) + 0.0722 * (b ** 2.2);
return luminance;
};
useEffect(() => {
const handleScroll = () => {
const scrollPosition = window.scrollY + 60;
const sectionElements = document.querySelectorAll("div[id]");
let currentSectionId = "";
let anySectionVisible = false;
sectionElements.forEach((element) => {
const section = element as HTMLElement;
const sectionTop = section.getBoundingClientRect().top + window.scrollY;
const sectionBottom = sectionTop + section.offsetHeight;
if (scrollPosition >= sectionTop && scrollPosition < sectionBottom) {
currentSectionId = section.getAttribute("id") || "";
anySectionVisible = true;
// Get the computed background color of the current section
const sectionBgColor = window.getComputedStyle(section).backgroundColor;
// Determine the luminance of the background color
const luminance = getLuminance(sectionBgColor);
// Set ScrollSpy color based on luminance
setScrollSpyColor(luminance > 0.5 ? "dark" : "light");
}
});
if (!hoveredSection) {
setActiveSection(currentSectionId);
}
setShowScrollSpy(anySectionVisible);
};
window.addEventListener("scroll", handleScroll);
handleScroll();
return () => window.removeEventListener("scroll", handleScroll);
}, [hoveredSection]);
return (
<div
className={`hidden md:flex md:fixed md:top-[160px] md:left-[74px] md:h-full md:flex-col md:items-center md:space-y-2 md:z-50 md:transition-opacity md:duration-300 ${
showScrollSpy ? "md:opacity-100" : "md:opacity-0"
}`}
>
<div className="relative flex flex-col items-center space-y-2">
{sections.map((section) => (
<div
key={section.id}
className="relative flex items-center space-x-2"
onMouseEnter={() => {
setHoveredSection(section.id);
if (activeSection !== section.id) {
setActiveSection("");
}
}}
onMouseLeave={() => {
if (activeSection === "") {
setActiveSection((prev) => (prev === section.id ? "" : prev));
}
setHoveredSection("");
}}
>
<a
href={`#${section.id}`}
className={`block h-8 transition-all duration-300 ${
hoveredSection === section.id || activeSection === section.id
? scrollSpyColor === "dark"
? "bg-black w-[4px]" // Dark bar on light backgrounds
: "bg-white w-[4px]" // Light bar on dark backgrounds
: scrollSpyColor === "dark"
? "bg-black w-[2px] opacity-[70%]" // Dark bar default on light
: "bg-white w-[2px] opacity-[70%]" // Light bar default on dark
}`}
></a>
{(hoveredSection === section.id || activeSection === section.id) && (
<div
className={`absolute left-6 w-[60px] text-[10px] font-light transition-opacity duration-300 ${
hoveredSection === section.id || activeSection === section.id
? "opacity-100"
: "opacity-0"
}`}
style={{
color: scrollSpyColor === "dark" ? "#000000" : "#ffffff", // Dark text on light, light text on dark
}}
>
{section.name}
</div>
)}
</div>
))}
</div>
</div>
);
};
export default ScrollSpy;
在你的滚动间谍“混合混合差异”的容器上使用这个顺风类,它会自动反转颜色