如何根据背景颜色动态改变文字颜色

问题描述 投票:0回答:1

我正在开发一个左侧有滚动间谍导航栏的登陆页面。我希望滚动间谍的背景和文本颜色根据背景颜色动态变化。

例如,如果该部分具有深色背景,我希望滚动间谍具有浅色背景(反之亦然)。我被困在如何检测部分的背景颜色并相应地调整滚动间谍的颜色。

这是我在滚动间谍及其文本中真正想要的行为,我也制作了导航及其功能,但我需要的只是更改颜色,例如,在浅色背景上,滚动间谍导航应该是黑色的,在浅色背景上,它应该是黑暗的:

这里是参考网站: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;

reactjs scroll colors
1个回答
0
投票

在你的滚动间谍“混合混合差异”的容器上使用这个顺风类,它会自动反转颜色

© www.soinside.com 2019 - 2024. All rights reserved.