结合使用 useContext 钩子和 three.js (react-three-fiber) 组件,主题颜色不会 load/update 正确
Theme colors won't load/update correctly using useContext hook in combination with three.js (react-three-fiber) component
有人能告诉我为什么 标签中的所有组件在更改主题时都会适应,但 three.js 组件( 和 )却不会t?
Box.jsx:
import { useFrame, useThree } from "@react-three/fiber";
import React, { useContext, useEffect } from "react";
import { useRef } from "react";
import { angleToRadians } from "../../../utils/angle";
import * as THREE from "three";
import { themes, ThemeContext } from "../../../utils/Theme";
export default function Box(){
const orbitControlsRef = useRef(null);
useFrame((state) => {
if (orbitControlsRef.current) {
const { x, y } = state.mouse;
orbitControlsRef.current.setAzimuthalAngle(-x * angleToRadians(45));
orbitControlsRef.current.setPolarAngle((y+ 1.5) * angleToRadians(90 - 30));
orbitControlsRef.current.update();
}
})
const q = window.innerWidth;
const canvas = document.querySelector('.canvas');
var deviceAngle = 0;
if(window.matchMedia("(pointer: coarse)").matches) {
canvas.setAttribute('style', 'pointer-events: none;');
deviceAngle = 50;
}
else{
deviceAngle = 160;
}
const theme = useContext(ThemeContext);
return (
<>
<PerspectiveCamera makeDefault position={[0, 0, 7]} fov={90} />
<OrbitControls ref={orbitControlsRef} minPolarAngle={angleToRadians(20)} maxPolarAngle={angleToRadians(deviceAngle)} enableDamping enabled={false}/>
{/* <OrbitControls /> */}
<mesh position={[0,0,0]} rotation={[0,0,0]}>
<torusBufferGeometry attach={'geometry'} args={[5,2,70,100]} />
<MeshDistortMaterial
wireframeLinecap wireframeLinejoin
attach="material"
wireframe
speed={0.4}
distort={0.46}
color={theme.pLight}/>
</mesh>
<fog attach="fog" color={theme.secondary} near={5} far={7.5} position={[0,0,0]}/>
<mesh position={[0,0,0]}>
<pointLight color={theme.cta} intensity={0.3} position={[0,0,1]} />
<ambientLight color={theme.secondary} intensity={0.5} />
</mesh>
</>
)
}
`
App.jsx:
在这里,我导入了一个包含主题的主题对象,并将 ThemeContext 设置为当前主题。这发生在标有 -+- 的注释行。
import Box from "./components/three/box/Box";
import { Html, useProgress} from "@react-three/drei"
import { Canvas } from "@react-three/fiber"
import Cursor from "./components/cursor/Cursor";
import Welcome from "./components/welcome/Welcome";
import Socials from "./components/socials/Socials";
import Scroll from "./components/scroll_indicator/Scroll";
import About from "./components/about/About";
import { OrbitControls } from "@react-three/drei";
import {
EffectComposer,
Bloom,
Glitch,
Scanline
} from "@react-three/postprocessing";
import { BlendFunction, Resizer, KernelSize, GlitchMode } from 'postprocessing'
import Section from "./components/ux/section/Section";
import { Suspense, createContext, useContext } from "react";
import BottomBar from "./components/ux/bottom_bar/BottomBar";
import ProgressBar from "./components/ux/progress_bar/ProgressBar";
import Skills from "./components/skills/Skills";
import Projects from "./components/projects/Projects";
import Logo from "./components/ux/logo/Logo";
import ModeSwitch from "./components/ux/light_dark_mode/ModeSwitch";
import {themes, ThemeContext} from './utils/Theme'
import { useEffect } from "react";
function Loader() {
const { progress } = useProgress()
return <Html center>{progress} % loaded</Html>
}
export default function App() {
const theme = useContext(ThemeContext);
/* -------------------+-------------- */
var currentTheme= themes.light;
document.body.style.backgroundColor = currentTheme.primary;
document.body.style.color = currentTheme.text;
return (
<ThemeContext.Provider value={currentTheme}>
{/* <Logo/> */}
<ModeSwitch/>
<BottomBar/>
<Scroll/>
<Welcome/>
<Socials/>
<Canvas className="canvas"
>
<Suspense fallback={<Loader/>}>
<EffectComposer multisampling={0} disableNormalPass={true} >
</EffectComposer>
<Box />
<OrbitControls enabled={false}/>
</Suspense>
</Canvas>
<Section content={<About/>} id={'about'}/>
<Section content={<Skills/>}/>
<Section content={<Projects/>} id={'projects'}/>
</ThemeContext.Provider>
);
}
好的,我已经找到答案了!上下文提供者不能将值传递到元素中。我也在 canvas 标签内重新声明了 ,它起作用了!
有人能告诉我为什么
Box.jsx:
import { useFrame, useThree } from "@react-three/fiber";
import React, { useContext, useEffect } from "react";
import { useRef } from "react";
import { angleToRadians } from "../../../utils/angle";
import * as THREE from "three";
import { themes, ThemeContext } from "../../../utils/Theme";
export default function Box(){
const orbitControlsRef = useRef(null);
useFrame((state) => {
if (orbitControlsRef.current) {
const { x, y } = state.mouse;
orbitControlsRef.current.setAzimuthalAngle(-x * angleToRadians(45));
orbitControlsRef.current.setPolarAngle((y+ 1.5) * angleToRadians(90 - 30));
orbitControlsRef.current.update();
}
})
const q = window.innerWidth;
const canvas = document.querySelector('.canvas');
var deviceAngle = 0;
if(window.matchMedia("(pointer: coarse)").matches) {
canvas.setAttribute('style', 'pointer-events: none;');
deviceAngle = 50;
}
else{
deviceAngle = 160;
}
const theme = useContext(ThemeContext);
return (
<>
<PerspectiveCamera makeDefault position={[0, 0, 7]} fov={90} />
<OrbitControls ref={orbitControlsRef} minPolarAngle={angleToRadians(20)} maxPolarAngle={angleToRadians(deviceAngle)} enableDamping enabled={false}/>
{/* <OrbitControls /> */}
<mesh position={[0,0,0]} rotation={[0,0,0]}>
<torusBufferGeometry attach={'geometry'} args={[5,2,70,100]} />
<MeshDistortMaterial
wireframeLinecap wireframeLinejoin
attach="material"
wireframe
speed={0.4}
distort={0.46}
color={theme.pLight}/>
</mesh>
<fog attach="fog" color={theme.secondary} near={5} far={7.5} position={[0,0,0]}/>
<mesh position={[0,0,0]}>
<pointLight color={theme.cta} intensity={0.3} position={[0,0,1]} />
<ambientLight color={theme.secondary} intensity={0.5} />
</mesh>
</>
)
}
`
App.jsx:
在这里,我导入了一个包含主题的主题对象,并将 ThemeContext 设置为当前主题。这发生在标有 -+- 的注释行。
import Box from "./components/three/box/Box";
import { Html, useProgress} from "@react-three/drei"
import { Canvas } from "@react-three/fiber"
import Cursor from "./components/cursor/Cursor";
import Welcome from "./components/welcome/Welcome";
import Socials from "./components/socials/Socials";
import Scroll from "./components/scroll_indicator/Scroll";
import About from "./components/about/About";
import { OrbitControls } from "@react-three/drei";
import {
EffectComposer,
Bloom,
Glitch,
Scanline
} from "@react-three/postprocessing";
import { BlendFunction, Resizer, KernelSize, GlitchMode } from 'postprocessing'
import Section from "./components/ux/section/Section";
import { Suspense, createContext, useContext } from "react";
import BottomBar from "./components/ux/bottom_bar/BottomBar";
import ProgressBar from "./components/ux/progress_bar/ProgressBar";
import Skills from "./components/skills/Skills";
import Projects from "./components/projects/Projects";
import Logo from "./components/ux/logo/Logo";
import ModeSwitch from "./components/ux/light_dark_mode/ModeSwitch";
import {themes, ThemeContext} from './utils/Theme'
import { useEffect } from "react";
function Loader() {
const { progress } = useProgress()
return <Html center>{progress} % loaded</Html>
}
export default function App() {
const theme = useContext(ThemeContext);
/* -------------------+-------------- */
var currentTheme= themes.light;
document.body.style.backgroundColor = currentTheme.primary;
document.body.style.color = currentTheme.text;
return (
<ThemeContext.Provider value={currentTheme}>
{/* <Logo/> */}
<ModeSwitch/>
<BottomBar/>
<Scroll/>
<Welcome/>
<Socials/>
<Canvas className="canvas"
>
<Suspense fallback={<Loader/>}>
<EffectComposer multisampling={0} disableNormalPass={true} >
</EffectComposer>
<Box />
<OrbitControls enabled={false}/>
</Suspense>
</Canvas>
<Section content={<About/>} id={'about'}/>
<Section content={<Skills/>}/>
<Section content={<Projects/>} id={'projects'}/>
</ThemeContext.Provider>
);
}
好的,我已经找到答案了!上下文提供者不能将值传递到元素中。我也在 canvas 标签内重新声明了