I'm a beginner at Three Js.
In the code when I click Button 1 you can see the object moves/changes its positions after 1 room. Now I want to do this, Whenever I click Button 2 they should change position after 2 rooms.
This is my code: https://codesandbox.io/s/2ndddddd-7ydbr2
Here's the file:
import React, { Suspense, useEffect, useMemo, useRef, useState } from "react";
import { Canvas } from "@react-three/fiber";
import { ContactShadows, OrbitControls, useGLTF } 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());
console.log("arr::", arr);
setRooms(arr);
}}
>
Button 1
</button>
<button
onClick={() => {
let arr = [...rooms];
arr.unshift(arr.pop());
console.log("arr::", arr);
setRooms(arr);
}}
>
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}
/>
{console.log("rooms render", rooms)}
{rooms.map((room, roomIndex) =>
room({ position: positions[roomIndex] })
)}
<ContactShadows />
</Suspense>
<OrbitControls enablePan={true} enableZoom={true} enableRotate={true} />
</Canvas>
</div>
);
};
export default PartOne;
CodePudding user response:
basically you want to rotate your array based on the number of times to rotate.
so you can use a function like this
const rotate = function (arr, numberOfShifts) {
let tmp = 0;
const leng = arr.length;
numberOfShifts = numberOfShifts % leng;
for (let i = 0; i < numberOfShifts; i ) {
tmp = arr.pop();
arr.unshift(tmp);
}
return arr;
};
const arr = [1,2,3,4,5]
console.log(rotate(arr, 1))
console.log(rotate(arr, 2))
In your code instead of this arr.unshift(arr.pop());
call this function rotate(arr, 1)
for button 1
and rotate(arr, 2)
for button 2
updated your code:
import React, { Suspense, useEffect, useMemo, useRef, useState } from "react";
import { Canvas } from "@react-three/fiber";
import { ContactShadows, OrbitControls, useGLTF } 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]);
const rotate = function (arr, numberOfShifts) {
let tmp = 0;
const leng = arr.length;
numberOfShifts = numberOfShifts % leng;
for (let i = 0; i < numberOfShifts; i ) {
tmp = arr.pop();
arr.unshift(tmp);
}
return arr;
};
return (
<div className="wrapper">
<button
onClick={() => {
let arr = [...rooms];
rotate(arr,1)
console.log("arr::", arr);
setRooms(arr);
}}
>
Button 1
</button>
<button
onClick={() => {
let arr = [...rooms];
rotate(arr,2)
console.log("arr::", arr);
setRooms(arr);
}}
>
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}
/>
{console.log("rooms render", rooms)}
{rooms.map((room, roomIndex) =>
room({ position: positions[roomIndex] })
)}
<ContactShadows />
</Suspense>
<OrbitControls enablePan={true} enableZoom={true} enableRotate={true} />
</Canvas>
</div>
);
};
export default PartOne;