You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Three.js中3D房间对象循环位置切换:Button +2功能实现需求

实现Button +2的2房间间隔切换功能

核心思路

原Button +1通过将数组最后一个元素移到开头,让每个房间对应的位置索引前进1,实现1个房间间隔的切换。要实现2个房间间隔的切换,只需要将数组最后两个元素移到数组开头即可,这样每个房间对应的位置索引会前进2,对应到预设的positions数组中,就实现了2间隔的位置切换。

修改后的完整代码

import React, { Suspense, useEffect, useMemo, useState } from "react";
import { Canvas } from "@react-three/fiber";
import { ContactShadows, OrbitControls } from "@react-three/drei";
import "./PartOne.css";
import { RoomOne } from "../assets/Room1";
import { Room2 } from "../assets/Room2";
import { Room3 } from "../assets/Room3";
import { Room4 } from "../assets/Room4";
import { Room5 } from "../assets/Room5";
import { Room6 } from "../assets/Room6";
import { Room7 } from "../assets/Room7";
import { Room8 } from "../assets/Room8";

const PartOne = () => {
  const [rooms, setRooms] = useState([
    RoomOne,
    Room2,
    Room3,
    Room4,
    Room5,
    Room6,
    Room7,
    Room8
  ]);
  const positions = useMemo(() => [
    [0.0, 0.0, 0.0],
    [-3.6, -2.7, 0.0],
    [-0.0, -2.7, 3.6],
    [-7.2, -5.4, 0.0],
    [-3.6, -5.4, 3.6],
    [-0.0, -5.4, 7.2],
    [-7.2, -8.1, 3.6],
    [-3.6, -8.11, 7.2]
  ], []);

  useEffect(() => {
    console.log("rooms state:", rooms);
  }, [rooms]);

  return (
    <div className="wrapper">
      <button
        onClick={() => {
          let arr = [...rooms];
          arr.unshift(arr.pop());
          setRooms(arr);
        }}
      >
        Button +1
      </button>

      <button
        onClick={() => {
          let arr = [...rooms];
          // 截取最后2个元素放到数组开头
          const newRooms = [...arr.slice(-2), ...arr.slice(0, -2)];
          setRooms(newRooms);
        }}
      >
        Button +2
      </button>

      <Canvas shadows camera={{ fov: 70, position: [0, 0, 30] }}>
        <Suspense fallback={null}>
          <ambientLight intensity={0.3} />
          <directionalLight
            castShadow
            receiveShadow
            intensity={2}
            position={[80, 80, 80]}
            shadow-normalBias={0.1}
            shadow-camera-left={-12}
            shadow-camera-right={12}
            shadow-camera-top={12}
            shadow-camera-bottom={-12}
            shadow-camera-near={0.5}
            shadow-camera-far={200}
          />
          {rooms.map((room, roomIndex) =>
            room({ position: positions[roomIndex] })
          )}
          <ContactShadows />
        </Suspense>
        <OrbitControls enablePan={true} enableZoom={true} enableRotate={true} />
      </Canvas>
    </div>
  );
};

export default PartOne;

关键修改点说明

  1. Button +2的点击逻辑:
    使用数组slice方法,arr.slice(-2)获取最后2个元素,arr.slice(0, -2)获取前面所有元素,拼接后得到新数组,一次完成2间隔的切换逻辑,比两次执行unshift(pop())更高效清晰。
  2. 补全useMemo依赖数组:
    原代码useMemo未传依赖数组,会导致每次渲染都重建positions数组,补全空数组后,positions仅在组件初始化时创建一次,优化性能。

内容的提问来源于stack exchange,提问作者Sayedul Karim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 09:05:41