提问人:Hristo hristov 提问时间:11/11/2023 更新时间:11/11/2023 访问量:6
React Fiber 和 Drei clickHandler 运行两次 (Next.js)
React Fiber and Drei clickHandler runs two times (Next.js)
问:
在我开始之前,我想指出我正在研究Nextjs。我目前有一个体验组件,我一直在其中摆弄和测试不同的想法。我传递了一系列潜在的博客,并尝试动态生成它们。当我将 onClick 事件处理程序添加到博客时,问题就来了。当我单击 Blog 组件时,它确实运行了处理程序,但它运行了两次。处理程序所做的只是通过轻微旋转将组件移动到一个方向。我目前有主要的Page.js和两个组件,这就是一切。我确实有一些 glb 文件和模型,但它们与问题无关。
页面.js
"use client"
import { Experience } from '@/Components/Experience/Experience'
import { Backdrop, OrbitControls, PerspectiveCamera, ScrollControls, useHelper, } from '@react-three/drei';
import { Canvas } from '@react-three/fiber';
import { useEffect, useRef } from 'react';
import * as THREE from "three";
export default function Home() {
const items = [1, 2, 3, 4, 5, 6, 7, 8];
return (
<section id="base">
<Canvas shadows >
<ScrollControls
pages={items ? items.length * 0.36 : 0}
horizontal
damping={1}
>
{items ?
<Experience blogs={items} />
:
null}
</ScrollControls>
</Canvas>
</section>
)
}
经验:
"use client";
import {
OrbitControls,
ScrollControls,
useTexture,
Decal,
useHelper,
PerspectiveCamera,
Backdrop,
useScroll,
Scroll,
} from "@react-three/drei";
import { Blog } from "../Blog/Blog";
import { useFrame, useLoader, useThree } from "@react-three/fiber";
import { TextureLoader } from "three";
import { useLayoutEffect, useRef, useState } from "react";
import { PointLightHelper } from "three";
import { useEffect } from "react";
import gsap from "gsap";
import * as THREE from "three";
import { Page } from "../Page/Page";
const Light = () => {
const ref = useRef();
useHelper(ref, PointLightHelper, 1);
return (
<rectAreaLight
width={20}
height={20}
ref={ref}
position={[-5, 10, 20]}
intensity={0.7}
rotation={[0, 0, 0]}
/>
);
};
export const Experience = ({ blogs }) => {
const [map] = useLoader(TextureLoader, ["/react.jpg"]);
const [moveIndex, setMoveIndex] = useState(0);
const cameraRef = useRef();
const scroll = useScroll();
const tl = useRef();
const axesRef = useRef();
const blogsRef = blogs.map((blog) => useRef(null));
const chosenhandler = (index) => {
console.log(blogsRef[index].current);
if (blogsRef[index].current.name == "active") {
blogsRef[index].current.name = "";
gsap.to(
blogsRef[index].current.position,
{
duration: 2,
z: blogsRef[index].current.position.z + 1,
ease: "power4.out",
},
0
);
gsap.to(
blogsRef[index].current.rotation,
{
duration: 2,
_y: blogsRef[index].current.position._y - 0.3,
ease: "power4.out",
},
0
);
} else {
blogsRef[index].current.name = "active";
gsap.to(
blogsRef[index].current.position,
{
duration: 2,
z: blogsRef[index].current.position.z - 1,
ease: "power4.out",
},
0
);
gsap.to(
blogsRef[index].current.rotation,
{
duration: 2,
_y: blogsRef[index].current.position._y + 0.3,
ease: "power4.out",
},
0
);
}
};
const blogGeneration = blogs.map((blog, index) => {
const distance = 7 * index;
const positioning = distance + index;
console.log("blog" + index);
return (
<Blog
scroll={scroll}
position={[positioning, 3, -0.2 * index + 1]}
rotation={[0, -1.5, 0]}
key={"blog" + index}
innerRef={blogsRef[index]}
onClick={(e) => chosenhandler(index)}
/>
);
});
return (
<>
<axesHelper ref={axesRef} />
<ambientLight intensity={0.5} />
<Light />
<PerspectiveCamera
ref={cameraRef}
makeDefault={true}
position={[0.1, 7.2, 8]}
fov={70}
rotation={[0, 0.3, 0]}
/>
<Backdrop
scale={[400, 120, 10]}
rotation={[0, 0.1, 0]}
position={[10, 0, -20]}
floor={10} // Stretches the floor segment, 0.25 by default
segments={20} // Mesh-resolution, 20 by default
>
<meshStandardMaterial color="#fff" />
</Backdrop>
<Scroll>{blogGeneration}</Scroll>
</>
);
};
博客:
/*
Auto-generated by: https://github.com/pmndrs/gltfjsx
Command: npx [email protected] models/project-prep.glb
*/
import React, { useEffect, useRef, useState } from "react";
import { Decal, Float, useGLTF, useHelper, useScroll } from "@react-three/drei";
import { useFrame, useLoader } from "@react-three/fiber";
import { DoubleSide, PointLightHelper, TextureLoader } from "three";
import gsap from "gsap";
import * as THREE from "three";
export function Blog(props) {
const [map] = useLoader(TextureLoader, ["/react.jpg"]);
const { nodes, materials } = useGLTF("models/Blog.glb");
const data = useScroll();
const Light = () => {
const ref = useRef();
return (
<rectAreaLight
width={5}
height={5}
ref={ref}
position={[3, 4.2, 0]}
intensity={3}
rotation={[0, 1.3, 0]}
/>
);
};
const [hovered, setHovered] = useState(false);
useEffect(() => {
document.body.style.cursor = hovered ? "pointer" : "auto";
}, [hovered]);
return (
<group
{...props}
dispose={null}
ref={props.innerRef}
onPointerOver={() => setHovered(true)}
onPointerOut={() => setHovered(false)}
>
<Float
speed={5}
rotationIntensity={0.1}
floatIntensity={0.2}
floatingRange={[0.1, 1]}
>
{hovered ? <Light /> : null}
<mesh
geometry={nodes.Cube.geometry}
material={materials.Material}
position={[0, 4.2, 0]}
scale={[0.25, 2.5, 3]}
>
<Decal
position={[1.15, 0, 0.1]}
rotation={[0, 1, 0]}
scale={[1.6, 1.87, 1.6]}
>
<meshStandardMaterial
side={DoubleSide}
map={map}
polygonOffset
polygonOffsetFactor={-1}
/>
</Decal>
</mesh>
</Float>
</group>
);
}
useGLTF.preload("models/blog.glb");
我尝试关闭严格模式,但它并没有做太多事情。我玩了很多,但没有成功。我尝试改变我的方法,但这是不可能的。
答: 暂无答案
评论